summaryrefslogtreecommitdiff
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2013-04-21 15:54:15 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2013-04-21 15:54:15 (UTC)
commit1906ddfb5d3887edeedaf8e07d14ad89abbd214d (patch) (unidiff)
tree37df37cfcd6df9931ce92e53ef8d686adc9caa09
parent0608e045f6aa471916829468f48082ea07a453f4 (diff)
downloadclipperz-1906ddfb5d3887edeedaf8e07d14ad89abbd214d.zip
clipperz-1906ddfb5d3887edeedaf8e07d14ad89abbd214d.tar.gz
clipperz-1906ddfb5d3887edeedaf8e07d14ad89abbd214d.tar.bz2
Aborted attempt to factor out the Crypto library on its own module
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/AES.js864
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/Base.js1847
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/BigInt.js1755
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/BigInt_scoped.js1644
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/ByteArray.js1496
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Curve.js545
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/FiniteField.js521
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Point.js62
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Value.js381
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/ECC/StandardCurves.js234
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/PRNG.js850
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/RSA.js146
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/SHA.js296
-rw-r--r--frontend/gamma/js/ClipperzCryptoLibrary/SRP.js326
14 files changed, 0 insertions, 10967 deletions
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/AES.js b/frontend/gamma/js/ClipperzCryptoLibrary/AES.js
deleted file mode 100644
index cbbbb13..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/AES.js
+++ b/dev/null
@@ -1,864 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.AES depends on Clipperz.ByteArray!";
26}
27
28 //Dependency commented to avoid a circular reference
29//try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) {
30 //throw "Clipperz.Crypto.AES depends on Clipperz.Crypto.PRNG!";
31//}
32
33if (typeof(Clipperz.Crypto.AES) == 'undefined') { Clipperz.Crypto.AES = {}; }
34
35//#############################################################################
36
37Clipperz.Crypto.AES.DeferredExecutionContext = function(args) {
38 args = args || {};
39
40 this._key = args.key;
41 this._message = args.message;
42 this._result = args.message.clone();
43 this._nonce = args.nonce;
44 this._messageLength = this._message.length();
45
46 this._messageArray = this._message.arrayValues();
47 this._resultArray = this._result.arrayValues();
48 this._nonceArray = this._nonce.arrayValues();
49
50 this._executionStep = 0;
51
52 // this._elaborationChunkSize = 1024; // 4096; // 16384; //4096;
53 this._elaborationChunks = 10;
54 this._pauseTime = 0.02; // 0.02 //0.2;
55
56 return this;
57}
58
59Clipperz.Crypto.AES.DeferredExecutionContext.prototype = MochiKit.Base.update(null, {
60
61 'key': function() {
62 return this._key;
63 },
64
65 'message': function() {
66 return this._message;
67 },
68
69 'messageLength': function() {
70 return this._messageLength;
71 },
72
73 'result': function() {
74 return new Clipperz.ByteArray(this.resultArray());
75 },
76
77 'nonce': function() {
78 return this._nonce;
79 },
80
81 'messageArray': function() {
82 return this._messageArray;
83 },
84
85 'resultArray': function() {
86 return this._resultArray;
87 },
88
89 'nonceArray': function() {
90 return this._nonceArray;
91 },
92
93 'elaborationChunkSize': function() {
94 // return Clipperz.Crypto.AES.DeferredExecution.chunkSize;
95 // return this._elaborationChunkSize;
96 return (this._elaborationChunks * 1024);
97 },
98
99 'executionStep': function() {
100 return this._executionStep;
101 },
102
103 'setExecutionStep': function(aValue) {
104 this._executionStep = aValue;
105 },
106
107 'tuneExecutionParameters': function (anElapsedTime) {
108//var originalChunks = this._elaborationChunks;
109 if (anElapsedTime > 0) {
110 this._elaborationChunks = Math.round(this._elaborationChunks * ((anElapsedTime + 1000)/(anElapsedTime * 2)));
111 }
112//Clipperz.log("tuneExecutionParameters - elapsedTime: " + anElapsedTime + /*originalChunks,*/ " chunks # " + this._elaborationChunks + " [" + this._executionStep + " / " + this._messageLength + "]");
113 },
114
115 'pause': function(aValue) {
116 // return MochiKit.Async.wait(Clipperz.Crypto.AES.DeferredExecution.pauseTime, aValue);
117 return MochiKit.Async.wait(this._pauseTime, aValue);
118 },
119
120 'isDone': function () {
121//console.log("isDone", this.executionStep(), this.messageLength());
122 return (this._executionStep >= this._messageLength);
123 },
124
125 //-----------------------------------------------------------------------------
126 __syntaxFix__: "syntax fix"
127
128});
129
130//#############################################################################
131
132Clipperz.Crypto.AES.Key = function(args) {
133 args = args || {};
134
135 this._key = args.key;
136 this._keySize = args.keySize || this.key().length();
137
138 if (this.keySize() == 128/8) {
139 this._b = 176;
140 this._numberOfRounds = 10;
141 } else if (this.keySize() == 256/8) {
142 this._b = 240;
143 this._numberOfRounds = 14;
144 } else {
145 MochiKit.Logging.logError("AES unsupported key size: " + (this.keySize() * 8) + " bits");
146 throw Clipperz.Crypto.AES.exception.UnsupportedKeySize;
147 }
148
149 this._stretchedKey = null;
150
151 return this;
152}
153
154Clipperz.Crypto.AES.Key.prototype = MochiKit.Base.update(null, {
155
156 'asString': function() {
157 return "Clipperz.Crypto.AES.Key (" + this.key().toHexString() + ")";
158 },
159
160 //-----------------------------------------------------------------------------
161
162 'key': function() {
163 return this._key;
164 },
165
166 'keySize': function() {
167 return this._keySize;
168 },
169
170 'b': function() {
171 return this._b;
172 },
173
174 'numberOfRounds': function() {
175 return this._numberOfRounds;
176 },
177 //=========================================================================
178
179 'keyScheduleCore': function(aWord, aRoundConstantsIndex) {
180 varresult;
181 var sbox;
182
183 sbox = Clipperz.Crypto.AES.sbox();
184
185 result = [sbox[aWord[1]] ^ Clipperz.Crypto.AES.roundConstants()[aRoundConstantsIndex],
186 sbox[aWord[2]],
187 sbox[aWord[3]],
188 sbox[aWord[0]]];
189
190 return result;
191 },
192
193 //-----------------------------------------------------------------------------
194
195 'xorWithPreviousStretchValues': function(aKey, aWord, aPreviousWordIndex) {
196 varresult;
197 var i,c;
198
199 result = [];
200 c = 4;
201 for (i=0; i<c; i++) {
202 result[i] = aWord[i] ^ aKey.byteAtIndex(aPreviousWordIndex + i);
203 }
204
205 return result;
206 },
207
208 //-----------------------------------------------------------------------------
209
210 'sboxShakeup': function(aWord) {
211 var result;
212 var sbox;
213 var i,c;
214
215 result = [];
216 sbox = Clipperz.Crypto.AES.sbox();
217 c =4;
218 for (i=0; i<c; i++) {
219 result[i] = sbox[aWord[i]];
220 }
221
222 return result;
223 },
224
225 //-----------------------------------------------------------------------------
226
227 'stretchKey': function(aKey) {
228 varcurrentWord;
229 varkeyLength;
230 varpreviousStretchIndex;
231 var i,c;
232
233 keyLength = aKey.length();
234 previousStretchIndex = keyLength - this.keySize();
235
236 currentWord = [aKey.byteAtIndex(keyLength - 4),
237 aKey.byteAtIndex(keyLength - 3),
238 aKey.byteAtIndex(keyLength - 2),
239 aKey.byteAtIndex(keyLength - 1)];
240 currentWord = this.keyScheduleCore(currentWord, keyLength / this.keySize());
241
242 if (this.keySize() == 256/8) {
243 c = 8;
244 } else if (this.keySize() == 128/8){
245 c = 4;
246 }
247
248 for (i=0; i<c; i++) {
249 if (i == 4) {
250 //fifth streatch word
251 currentWord = this.sboxShakeup(currentWord);
252 }
253
254 currentWord = this.xorWithPreviousStretchValues(aKey, currentWord, previousStretchIndex + (i*4));
255 aKey.appendBytes(currentWord);
256 }
257
258 return aKey;
259 },
260
261 //-----------------------------------------------------------------------------
262
263 'stretchedKey': function() {
264 if (this._stretchedKey == null) {
265 var stretchedKey;
266
267 stretchedKey = this.key().clone();
268
269 while (stretchedKey.length() < this.keySize()) {
270 stretchedKey.appendByte(0);
271 }
272
273 while (stretchedKey.length() < this.b()) {
274 stretchedKey = this.stretchKey(stretchedKey);
275 }
276
277 this._stretchedKey = stretchedKey.split(0, this.b());
278 }
279
280 return this._stretchedKey;
281 },
282
283 //=========================================================================
284 __syntaxFix__: "syntax fix"
285});
286
287//#############################################################################
288
289Clipperz.Crypto.AES.State = function(args) {
290 args = args || {};
291
292 this._data = args.block;
293 this._key = args.key;
294
295 return this;
296}
297
298Clipperz.Crypto.AES.State.prototype = MochiKit.Base.update(null, {
299
300 'key': function() {
301 return this._key;
302 },
303
304 //-----------------------------------------------------------------------------
305
306 'data': function() {
307 return this._data;
308 },
309
310 'setData': function(aValue) {
311 this._data = aValue;
312 },
313
314 //=========================================================================
315
316 'addRoundKey': function(aRoundNumber) {
317 //each byte of the state is combined with the round key; each round key is derived from the cipher key using a key schedule.
318 vardata;
319 varstretchedKey;
320 varfirstStretchedKeyIndex;
321 var i,c;
322
323 data = this.data();
324 stretchedKey = this.key().stretchedKey();
325 firstStretchedKeyIndex = aRoundNumber * (128/8);
326 c = 128/8;
327 for (i=0; i<c; i++) {
328 data[i] = data[i] ^ stretchedKey.byteAtIndex(firstStretchedKeyIndex + i);
329 }
330 },
331
332 //-----------------------------------------------------------------------------
333
334 'subBytes': function() {
335 // a non-linear substitution step where each byte is replaced with another according to a lookup table.
336 var i,c;
337 vardata;
338 var sbox;
339
340 data = this.data();
341 sbox = Clipperz.Crypto.AES.sbox();
342
343 c = 16;
344 for (i=0; i<c; i++) {
345 data[i] = sbox[data[i]];
346 }
347 },
348
349 //-----------------------------------------------------------------------------
350
351 'shiftRows': function() {
352 //a transposition step where each row of the state is shifted cyclically a certain number of steps.
353 varnewValue;
354 vardata;
355 varshiftMapping;
356 vari,c;
357
358 newValue = new Array(16);
359 data = this.data();
360 shiftMapping = Clipperz.Crypto.AES.shiftRowMapping();
361 // [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
362 c = 16;
363 for (i=0; i<c; i++) {
364 newValue[i] = data[shiftMapping[i]];
365 }
366 for (i=0; i<c; i++) {
367 data[i] = newValue[i];
368 }
369 },
370
371 //-----------------------------------------------------------------------------
372/*
373 'mixColumnsWithValues': function(someValues) {
374 varresult;
375 vara;
376 var i,c;
377
378 c = 4;
379 result = [];
380 a = [];
381 for (i=0; i<c; i++) {
382 a[i] = [];
383 a[i][1] = someValues[i]
384 if ((a[i][1] & 0x80) == 0x80) {
385 a[i][2] = (a[i][1] << 1) ^ 0x11b;
386 } else {
387 a[i][2] = a[i][1] << 1;
388 }
389
390 a[i][3] = a[i][2] ^ a[i][1];
391 }
392
393 for (i=0; i<c; i++) {
394 varx;
395
396 x = Clipperz.Crypto.AES.mixColumnsMatrix()[i];
397 result[i] = a[0][x[0]] ^ a[1][x[1]] ^ a[2][x[2]] ^ a[3][x[3]];
398 }
399
400 return result;
401 },
402
403 'mixColumns': function() {
404 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
405 var data;
406 var i, c;
407
408 data = this.data();
409 c = 4;
410 for(i=0; i<c; i++) {
411 varblockIndex;
412 var mixedValues;
413
414 blockIndex = i * 4;
415 mixedValues = this.mixColumnsWithValues([data[blockIndex + 0],
416 data[blockIndex + 1],
417 data[blockIndex + 2],
418 data[blockIndex + 3]]);
419 data[blockIndex + 0] = mixedValues[0];
420 data[blockIndex + 1] = mixedValues[1];
421 data[blockIndex + 2] = mixedValues[2];
422 data[blockIndex + 3] = mixedValues[3];
423 }
424 },
425*/
426
427 'mixColumns': function() {
428 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
429 var data;
430 var i, c;
431 var a_1;
432 var a_2;
433
434 a_1 = new Array(4);
435 a_2 = new Array(4);
436
437 data = this.data();
438 c = 4;
439 for(i=0; i<c; i++) {
440 varblockIndex;
441 var ii, cc;
442
443 blockIndex = i * 4;
444
445 cc = 4;
446 for (ii=0; ii<cc; ii++) {
447 var value;
448
449 value = data[blockIndex + ii];
450 a_1[ii] = value;
451 a_2[ii] = (value & 0x80) ? ((value << 1) ^ 0x011b) : (value << 1);
452 }
453
454 data[blockIndex + 0] = a_2[0] ^ a_1[1] ^ a_2[1] ^ a_1[2] ^ a_1[3];
455 data[blockIndex + 1] = a_1[0] ^ a_2[1] ^ a_1[2] ^ a_2[2] ^ a_1[3];
456 data[blockIndex + 2] = a_1[0] ^ a_1[1] ^ a_2[2] ^ a_1[3] ^ a_2[3];
457 data[blockIndex + 3] = a_1[0] ^ a_2[0] ^ a_1[1] ^ a_1[2] ^ a_2[3];
458 }
459 },
460
461 //=========================================================================
462
463 'spinRound': function(aRoundNumber) {
464 this.addRoundKey(aRoundNumber);
465 this.subBytes();
466 this.shiftRows();
467 this.mixColumns();
468 },
469
470 'spinLastRound': function() {
471 this.addRoundKey(this.key().numberOfRounds() - 1);
472 this.subBytes();
473 this.shiftRows();
474 this.addRoundKey(this.key().numberOfRounds());
475 },
476
477 //=========================================================================
478
479 'encrypt': function() {
480 vari,c;
481
482 c = this.key().numberOfRounds() - 1;
483 for (i=0; i<c; i++) {
484 this.spinRound(i);
485 }
486
487 this.spinLastRound();
488 },
489
490 //=========================================================================
491 __syntaxFix__: "syntax fix"
492});
493
494//#############################################################################
495
496Clipperz.Crypto.AES.VERSION = "0.1";
497Clipperz.Crypto.AES.NAME = "Clipperz.Crypto.AES";
498
499MochiKit.Base.update(Clipperz.Crypto.AES, {
500
501 //http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-AES.html
502 //http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
503 //http://en.wikipedia.org/wiki/Rijndael_key_schedule
504 //http://en.wikipedia.org/wiki/Rijndael_S-box
505
506 '__repr__': function () {
507 return "[" + this.NAME + " " + this.VERSION + "]";
508 },
509
510 'toString': function () {
511 return this.__repr__();
512 },
513
514 //=============================================================================
515
516 '_sbox': null,
517 'sbox': function() {
518 if (Clipperz.Crypto.AES._sbox == null) {
519 Clipperz.Crypto.AES._sbox = [
5200x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
5210xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
5220xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
5230x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
5240x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
5250x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
5260xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
5270x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
5280xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
5290x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
5300xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
5310xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
5320xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
5330x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
5340xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
5350x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
536 ];
537 }
538
539 return Clipperz.Crypto.AES._sbox;
540 },
541
542 //-----------------------------------------------------------------------------
543 //
544 // 0 4 8 12 0 4 812
545 // 1 5 9 13 => 5 9 131
546 // 2 6 10 14 10 14 26
547 // 3 7 11 15 15 3 711
548 //
549 '_shiftRowMapping': null,
550 'shiftRowMapping': function() {
551 if (Clipperz.Crypto.AES._shiftRowMapping == null) {
552 Clipperz.Crypto.AES._shiftRowMapping = [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
553 }
554
555 return Clipperz.Crypto.AES._shiftRowMapping;
556 },
557
558 //-----------------------------------------------------------------------------
559
560 '_mixColumnsMatrix': null,
561 'mixColumnsMatrix': function() {
562 if (Clipperz.Crypto.AES._mixColumnsMatrix == null) {
563 Clipperz.Crypto.AES._mixColumnsMatrix = [[2, 3, 1 ,1],
564 [1, 2, 3, 1],
565 [1, 1, 2, 3],
566 [3, 1, 1, 2] ];
567 }
568
569 return Clipperz.Crypto.AES._mixColumnsMatrix;
570 },
571
572 '_roundConstants': null,
573 'roundConstants': function() {
574 if (Clipperz.Crypto.AES._roundConstants == null) {
575 Clipperz.Crypto.AES._roundConstants = [ , 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154];
576 // Clipperz.Crypto.AES._roundConstants = [ , 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a];
577 }
578
579 return Clipperz.Crypto.AES._roundConstants;
580 },
581
582 //=============================================================================
583
584 'incrementNonce': function(aNonce) {
585//Clipperz.Profile.start("Clipperz.Crypto.AES.incrementNonce");
586 var i;
587 var done;
588
589 done = false;
590 i = aNonce.length - 1;
591
592 while ((i>=0) && (done == false)) {
593 var currentByteValue;
594
595 currentByteValue = aNonce[i];
596
597 if (currentByteValue == 0xff) {
598 aNonce[i] = 0;
599 if (i>= 0) {
600 i --;
601 } else {
602 done = true;
603 }
604 } else {
605 aNonce[i] = currentByteValue + 1;
606 done = true;
607 }
608 }
609//Clipperz.Profile.stop("Clipperz.Crypto.AES.incrementNonce");
610 },
611
612 //-----------------------------------------------------------------------------
613
614 'encryptBlock': function(aKey, aBlock) {
615 varresult;
616 varstate;
617
618 state = new Clipperz.Crypto.AES.State({block:aBlock, key:aKey});
619//is(state.data(), 'before');
620 state.encrypt();
621 result = state.data();
622
623 return result;
624 },
625
626 //-----------------------------------------------------------------------------
627
628 'encryptBlocks': function(aKey, aMessage, aNonce) {
629 varresult;
630 var nonce;
631 var self;
632 varmessageIndex;
633 varmessageLength;
634 var blockSize;
635
636 self = Clipperz.Crypto.AES;
637 blockSize = 128/8;
638 messageLength = aMessage.length;
639 nonce = aNonce;
640
641 result = aMessage;
642 messageIndex = 0;
643 while (messageIndex < messageLength) {
644 var encryptedBlock;
645 var i,c;
646
647 self.incrementNonce(nonce);
648 encryptedBlock = self.encryptBlock(aKey, nonce);
649
650 if ((messageLength - messageIndex) > blockSize) {
651 c = blockSize;
652 } else {
653 c = messageLength - messageIndex;
654 }
655
656 for (i=0; i<c; i++) {
657 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
658 }
659
660 messageIndex += blockSize;
661 }
662
663 return result;
664 },
665
666 //-----------------------------------------------------------------------------
667
668 'encrypt': function(aKey, someData, aNonce) {
669 var result;
670 var nonce;
671 varencryptedData;
672 var key;
673
674 key = new Clipperz.Crypto.AES.Key({key:aKey});
675 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
676
677 encryptedData = Clipperz.Crypto.AES.encryptBlocks(key, someData.arrayValues(), nonce.arrayValues());
678
679 result = nonce.appendBytes(encryptedData);
680
681 return result;
682 },
683
684 //-----------------------------------------------------------------------------
685
686 'decrypt': function(aKey, someData) {
687 var result;
688 var nonce;
689 var encryptedData;
690 var decryptedData;
691 vardataIterator;
692 var key;
693
694 key = new Clipperz.Crypto.AES.Key({key:aKey});
695
696 encryptedData = someData.arrayValues();
697 nonce = encryptedData.slice(0, (128/8));
698 encryptedData = encryptedData.slice(128/8);
699 decryptedData = Clipperz.Crypto.AES.encryptBlocks(key, encryptedData, nonce);
700
701 result = new Clipperz.ByteArray(decryptedData);
702
703 return result;
704 },
705
706 //=============================================================================
707
708 'deferredEncryptExecutionChunk': function(anExecutionContext) {
709 varresult;
710 var nonce;
711 var self;
712 varmessageIndex;
713 varmessageLength;
714 var blockSize;
715 var executionLimit;
716 var startTime, endTime;
717
718 self = Clipperz.Crypto.AES;
719 startTime = new Date();
720 blockSize = 128/8;
721 messageLength = anExecutionContext.messageArray().length;
722 nonce = anExecutionContext.nonceArray();
723 result = anExecutionContext.resultArray();
724
725 messageIndex = anExecutionContext.executionStep();
726 executionLimit = messageIndex + anExecutionContext.elaborationChunkSize();
727 executionLimit = Math.min(executionLimit, messageLength);
728
729 while (messageIndex < executionLimit) {
730 var encryptedBlock;
731 var i,c;
732
733 self.incrementNonce(nonce);
734 encryptedBlock = self.encryptBlock(anExecutionContext.key(), nonce);
735
736 if ((executionLimit - messageIndex) > blockSize) {
737 c = blockSize;
738 } else {
739 c = executionLimit - messageIndex;
740 }
741
742 for (i=0; i<c; i++) {
743 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
744 }
745
746 messageIndex += blockSize;
747 }
748 anExecutionContext.setExecutionStep(messageIndex);
749 endTime = new Date();
750 anExecutionContext.tuneExecutionParameters(endTime - startTime);
751
752 return anExecutionContext;
753 },
754
755 //-----------------------------------------------------------------------------
756/*
757 'deferredEncryptBlocks': function(anExecutionContext) {
758 vardeferredResult;
759 varmessageSize;
760 var i,c;
761
762 messageSize = anExecutionContext.messageLength();
763
764 deferredResult = new Clipperz.Async.Deferred("AES.deferredEncryptBloks");
765
766 c = Math.ceil(messageSize / anExecutionContext.elaborationChunkSize());
767 for (i=0; i<c; i++) {
768 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptExecutionChunk);
769 deferredResult.addMethod(anExecutionContext, 'pause');
770 }
771
772 deferredResult.callback(anExecutionContext);
773
774 return deferredResult;
775 },
776*/
777
778 'deferredEncryptBlocks': function(anExecutionContext) {
779 vardeferredResult;
780
781 if (! anExecutionContext.isDone()) {
782 deferredResult = Clipperz.Async.callbacks("Clipperz.Crypto.AES.deferredEncryptBloks", [
783 Clipperz.Crypto.AES.deferredEncryptExecutionChunk,
784 MochiKit.Base.method(anExecutionContext, 'pause'),
785 Clipperz.Crypto.AES.deferredEncryptBlocks
786 ], {trace:false}, anExecutionContext);
787 } else {
788 deferredResult = MochiKit.Async.succeed(anExecutionContext);
789 }
790
791 return deferredResult;
792 },
793
794 //-----------------------------------------------------------------------------
795
796 'deferredEncrypt': function(aKey, someData, aNonce) {
797 var deferredResult;
798 varexecutionContext;
799 var result;
800 var nonce;
801 var key;
802
803 key = new Clipperz.Crypto.AES.Key({key:aKey});
804 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
805
806 executionContext = new Clipperz.Crypto.AES.DeferredExecutionContext({key:key, message:someData, nonce:nonce});
807
808 deferredResult = new Clipperz.Async.Deferred("AES.deferredEncrypt");
809//deferredResult.addCallback(function (aValue) { console.log(">>> deferredEncrypt"); return aValue; });
810 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptBlocks);
811 deferredResult.addCallback(function(anExecutionContext) {
812 var result;
813
814 result = anExecutionContext.nonce().clone();
815 result.appendBytes(anExecutionContext.resultArray());
816
817 return result;
818 });
819//deferredResult.addCallback(function (aValue) { console.log("<<< deferredEncrypt"); return aValue; });
820 deferredResult.callback(executionContext)
821
822 return deferredResult;
823 },
824
825 //-----------------------------------------------------------------------------
826
827 'deferredDecrypt': function(aKey, someData) {
828 var deferredResult
829 var nonce;
830 var message;
831 var key;
832
833 key = new Clipperz.Crypto.AES.Key({key:aKey});
834 nonce = someData.split(0, (128/8));
835 message = someData.split(128/8);
836 executionContext = new Clipperz.Crypto.AES.DeferredExecutionContext({key:key, message:message, nonce:nonce});
837
838 deferredResult = new Clipperz.Async.Deferred("AES.deferredDecrypt");
839//deferredResult.addCallback(function (aValue) { console.log(">>> deferredDecrypt"); return aValue; });
840 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptBlocks);
841 deferredResult.addCallback(function(anExecutionContext) {
842 return anExecutionContext.result();
843 });
844//deferredResult.addCallback(function (aValue) { console.log("<<< deferredDecrypt"); return aValue; });
845 deferredResult.callback(executionContext);
846
847 return deferredResult;
848 },
849
850 //-----------------------------------------------------------------------------
851 __syntaxFix__: "syntax fix"
852
853});
854
855//#############################################################################
856
857//Clipperz.Crypto.AES.DeferredExecution = {
858 // 'chunkSize': 16384, // 4096, // 1024 4096 8192 1638432768;
859 // 'pauseTime': 0.02 //0.2
860//}
861
862Clipperz.Crypto.AES.exception = {
863 'UnsupportedKeySize': new MochiKit.Base.NamedError("Clipperz.Crypto.AES.exception.UnsupportedKeySize")
864};
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/Base.js b/frontend/gamma/js/ClipperzCryptoLibrary/Base.js
deleted file mode 100644
index 9acfc49..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/Base.js
+++ b/dev/null
@@ -1,1847 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24try { if (typeof(Clipperz.Base) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.Base depends on Clipperz.Base!";
26}
27
28if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
29if (typeof(Clipperz.Crypto.Base) == 'undefined') { Clipperz.Crypto.Base = {}; }
30
31Clipperz.Crypto.Base.VERSION = "0.1";
32Clipperz.Crypto.Base.NAME = "Clipperz.Crypto.Base";
33
34//#############################################################################
35 //Downloaded on March 30, 2006 from http://anmar.eu.org/projects/jssha2/files/jssha2-0.3.zip (jsSha2/sha256.js)
36//#############################################################################
37
38/* A JavaScript implementation of the Secure Hash Algorithm, SHA-256
39 * Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/
40 * Distributed under the BSD License
41 * Some bits taken from Paul Johnston's SHA-1 implementation
42 */
43var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
44function safe_add (x, y) {
45 var lsw = (x & 0xFFFF) + (y & 0xFFFF);
46 var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
47 return (msw << 16) | (lsw & 0xFFFF);
48}
49function S (X, n) {return ( X >>> n ) | (X << (32 - n));}
50function R (X, n) {return ( X >>> n );}
51function Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
52function Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
53function Sigma0256(x) {return (S(x, 2) ^ S(x, 13) ^ S(x, 22));}
54function Sigma1256(x) {return (S(x, 6) ^ S(x, 11) ^ S(x, 25));}
55function Gamma0256(x) {return (S(x, 7) ^ S(x, 18) ^ R(x, 3));}
56function Gamma1256(x) {return (S(x, 17) ^ S(x, 19) ^ R(x, 10));}
57function core_sha256 (m, l) {
58 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);
59 var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
60 var W = new Array(64);
61 var a, b, c, d, e, f, g, h, i, j;
62 var T1, T2;
63 /* append padding */
64 m[l >> 5] |= 0x80 << (24 - l % 32);
65 m[((l + 64 >> 9) << 4) + 15] = l;
66 for ( var i = 0; i<m.length; i+=16 ) {
67 a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7];
68 for ( var j = 0; j<64; j++) {
69 if (j < 16) W[j] = m[j + i];
70 else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
71 T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
72 T2 = safe_add(Sigma0256(a), Maj(a, b, c));
73 h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2);
74 }
75 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]);
76 }
77 return HASH;
78}
79function str2binb (str) {
80 var bin = Array();
81 var mask = (1 << chrsz) - 1;
82 for(var i = 0; i < str.length * chrsz; i += chrsz)
83 bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
84 return bin;
85}
86function binb2hex (binarray) {
87 var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
88 var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
89 var str = "";
90 for (var i = 0; i < binarray.length * 4; i++) {
91 str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
92 }
93 return str;
94}
95function hex_sha256(s){return binb2hex(core_sha256(str2binb(s),s.length * chrsz));}
96
97
98
99//#############################################################################
100 //Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (entropy.js)
101//#############################################################################
102
103 // Entropy collection utilities
104
105 /*Start by declaring static storage and initialise
106 the entropy vector from the time we come through
107 here. */
108
109 var entropyData = new Array(); // Collected entropy data
110 var edlen = 0; // Keyboard array data length
111
112 addEntropyTime(); // Start entropy collection with page load time
113 ce(); // Roll milliseconds into initial entropy
114
115 //Add a byte to the entropy vector
116
117 function addEntropyByte(b) {
118 entropyData[edlen++] = b;
119 }
120
121 /*Capture entropy. When the user presses a key or performs
122 various other events for which we can request
123 notification, add the time in 255ths of a second to the
124 entropyData array. The name of the function is short
125 so it doesn't bloat the form object declarations in
126 which it appears in various "onXXX" events. */
127
128 function ce() {
129 addEntropyByte(Math.floor((((new Date).getMilliseconds()) * 255) / 999));
130 }
131
132 //Add a 32 bit quantity to the entropy vector
133
134 function addEntropy32(w) {
135 var i;
136
137 for (i = 0; i < 4; i++) {
138 addEntropyByte(w & 0xFF);
139 w >>= 8;
140 }
141 }
142
143 /*Add the current time and date (milliseconds since the epoch,
144 truncated to 32 bits) to the entropy vector. */
145
146 function addEntropyTime() {
147 addEntropy32((new Date()).getTime());
148 }
149
150 /* Start collection of entropy from mouse movements. The
151 argument specifies the number of entropy items to be
152 obtained from mouse motion, after which mouse motion
153 will be ignored. Note that you can re-enable mouse
154 motion collection at any time if not already underway. */
155
156 var mouseMotionCollect = 0;
157 var oldMoveHandler; // For saving and restoring mouse move handler in IE4
158
159 function mouseMotionEntropy(maxsamp) {
160 if (mouseMotionCollect <= 0) {
161 mouseMotionCollect = maxsamp;
162 if ((document.implementation.hasFeature("Events", "2.0")) &&
163 document.addEventListener) {
164 // Browser supports Document Object Model (DOM) 2 events
165 document.addEventListener("mousemove", mouseMoveEntropy, false);
166 } else {
167 if (document.attachEvent) {
168 // Internet Explorer 5 and above event model
169 document.attachEvent("onmousemove", mouseMoveEntropy);
170 } else {
171 //Internet Explorer 4 event model
172 oldMoveHandler = document.onmousemove;
173 document.onmousemove = mouseMoveEntropy;
174 }
175 }
176//dump("Mouse enable", mouseMotionCollect);
177 }
178 }
179
180 /*Collect entropy from mouse motion events. Note that
181 this is craftily coded to work with either DOM2 or Internet
182 Explorer style events. Note that we don't use every successive
183 mouse movement event. Instead, we XOR the three bytes collected
184 from the mouse and use that to determine how many subsequent
185 mouse movements we ignore before capturing the next one. */
186
187 var mouseEntropyTime = 0; // Delay counter for mouse entropy collection
188
189 function mouseMoveEntropy(e) {
190 if (!e) {
191 e = window.event; // Internet Explorer event model
192 }
193 if (mouseMotionCollect > 0) {
194 if (mouseEntropyTime-- <= 0) {
195 addEntropyByte(e.screenX & 0xFF);
196 addEntropyByte(e.screenY & 0xFF);
197 ce();
198 mouseMotionCollect--;
199 mouseEntropyTime = (entropyData[edlen - 3] ^ entropyData[edlen - 2] ^
200 entropyData[edlen - 1]) % 19;
201//dump("Mouse Move", byteArrayToHex(entropyData.slice(-3)));
202 }
203 if (mouseMotionCollect <= 0) {
204 if (document.removeEventListener) {
205 document.removeEventListener("mousemove", mouseMoveEntropy, false);
206 } else if (document.detachEvent) {
207 document.detachEvent("onmousemove", mouseMoveEntropy);
208 } else {
209 document.onmousemove = oldMoveHandler;
210 }
211//dump("Spung!", 0);
212 }
213 }
214 }
215
216 /*Compute a 32 byte key value from the entropy vector.
217 We compute the value by taking the MD5 sum of the even
218 and odd bytes respectively of the entropy vector, then
219 concatenating the two MD5 sums. */
220
221 function keyFromEntropy() {
222 var i, k = new Array(32);
223
224 if (edlen == 0) {
225 alert("Blooie! Entropy vector void at call to keyFromEntropy.");
226 }
227//dump("Entropy bytes", edlen);
228
229 md5_init();
230 for (i = 0; i < edlen; i += 2) {
231 md5_update(entropyData[i]);
232 }
233 md5_finish();
234 for (i = 0; i < 16; i++) {
235 k[i] = digestBits[i];
236 }
237
238 md5_init();
239 for (i = 1; i < edlen; i += 2) {
240 md5_update(entropyData[i]);
241 }
242 md5_finish();
243 for (i = 0; i < 16; i++) {
244 k[i + 16] = digestBits[i];
245 }
246
247//dump("keyFromEntropy", byteArrayToHex(k));
248 return k;
249 }
250
251//#############################################################################
252 //Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (aesprng.js)
253//#############################################################################
254
255
256 // AES based pseudorandom number generator
257
258 /* Constructor. Called with an array of 32 byte (0-255) values
259 containing the initial seed. */
260
261 function AESprng(seed) {
262 this.key = new Array();
263 this.key = seed;
264 this.itext = hexToByteArray("9F489613248148F9C27945C6AE62EECA3E3367BB14064E4E6DC67A9F28AB3BD1");
265 this.nbytes = 0; // Bytes left in buffer
266
267 this.next = AESprng_next;
268 this.nextbits = AESprng_nextbits;
269 this.nextInt = AESprng_nextInt;
270 this.round = AESprng_round;
271
272 /* Encrypt the initial text with the seed key
273 three times, feeding the output of the encryption
274 back into the key for the next round. */
275
276 bsb = blockSizeInBits;
277 blockSizeInBits = 256;
278 var i, ct;
279 for (i = 0; i < 3; i++) {
280 this.key = rijndaelEncrypt(this.itext, this.key, "ECB");
281 }
282
283 /* Now make between one and four additional
284 key-feedback rounds, with the number determined
285 by bits from the result of the first three
286 rounds. */
287
288 var n = 1 + (this.key[3] & 2) + (this.key[9] & 1);
289 for (i = 0; i < n; i++) {
290 this.key = rijndaelEncrypt(this.itext, this.key, "ECB");
291 }
292 blockSizeInBits = bsb;
293 }
294
295 function AESprng_round() {
296 bsb = blockSizeInBits;
297 blockSizeInBits = 256;
298 this.key = rijndaelEncrypt(this.itext, this.key, "ECB");
299 this.nbytes = 32;
300 blockSizeInBits = bsb;
301 }
302
303 //Return next byte from the generator
304
305 function AESprng_next() {
306 if (this.nbytes <= 0) {
307 this.round();
308 }
309 return(this.key[--this.nbytes]);
310 }
311
312 //Return n bit integer value (up to maximum integer size)
313
314 function AESprng_nextbits(n) {
315 var i, w = 0, nbytes = Math.floor((n + 7) / 8);
316
317 for (i = 0; i < nbytes; i++) {
318 w = (w << 8) | this.next();
319 }
320 return w & ((1 << n) - 1);
321 }
322
323 // Return integer between 0 and n inclusive
324
325 function AESprng_nextInt(n) {
326 var p = 1, nb = 0;
327
328 // Determine smallest p, 2^p > n
329 // nb = log_2 p
330
331 while (n >= p) {
332 p <<= 1;
333 nb++;
334 }
335 p--;
336
337 /* Generate values from 0 through n by first generating
338 values v from 0 to (2^p)-1, then discarding any results v > n.
339 For the rationale behind this (and why taking
340 values mod (n + 1) is biased toward smaller values, see
341 Ferguson and Schneier, "Practical Cryptography",
342 ISBN 0-471-22357-3, section 10.8). */
343
344 while (true) {
345 var v = this.nextbits(nb) & p;
346
347 if (v <= n) {
348 return v;
349 }
350 }
351 }
352
353//#############################################################################
354 //Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (md5.js)
355//#############################################################################
356
357/*
358 * md5.jvs 1.0b 27/06/96
359 *
360 * Javascript implementation of the RSA Data Security, Inc. MD5
361 * Message-Digest Algorithm.
362 *
363 * Copyright (c) 1996 Henri Torgemane. All Rights Reserved.
364 *
365 * Permission to use, copy, modify, and distribute this software
366 * and its documentation for any purposes and without
367 * fee is hereby granted provided that this copyright notice
368 * appears in all copies.
369 *
370 * Of course, this soft is provided "as is" without express or implied
371 * warranty of any kind.
372
373 This version contains some trivial reformatting modifications
374 by John Walker.
375
376 */
377
378function array(n) {
379 for (i = 0; i < n; i++) {
380 this[i] = 0;
381 }
382 this.length = n;
383}
384
385/* Some basic logical functions had to be rewritten because of a bug in
386 * Javascript.. Just try to compute 0xffffffff >> 4 with it..
387 * Of course, these functions are slower than the original would be, but
388 * at least, they work!
389 */
390
391function integer(n) {
392 return n % (0xffffffff + 1);
393}
394
395function shr(a, b) {
396 a = integer(a);
397 b = integer(b);
398 if (a - 0x80000000 >= 0) {
399 a = a % 0x80000000;
400 a >>= b;
401 a += 0x40000000 >> (b - 1);
402 } else {
403 a >>= b;
404 }
405 return a;
406}
407
408function shl1(a) {
409 a = a % 0x80000000;
410 if (a & 0x40000000 == 0x40000000) {
411 a -= 0x40000000;
412 a *= 2;
413 a += 0x80000000;
414 } else {
415 a *= 2;
416 }
417 return a;
418}
419
420function shl(a, b) {
421 a = integer(a);
422 b = integer(b);
423 for (var i = 0; i < b; i++) {
424 a = shl1(a);
425 }
426 return a;
427}
428
429function and(a, b) {
430 a = integer(a);
431 b = integer(b);
432 var t1 = a - 0x80000000;
433 var t2 = b - 0x80000000;
434 if (t1 >= 0) {
435 if (t2 >= 0) {
436 return ((t1 & t2) + 0x80000000);
437 } else {
438 return (t1 & b);
439 }
440 } else {
441 if (t2 >= 0) {
442 return (a & t2);
443 } else {
444 return (a & b);
445 }
446 }
447}
448
449function or(a, b) {
450 a = integer(a);
451 b = integer(b);
452 var t1 = a - 0x80000000;
453 var t2 = b - 0x80000000;
454 if (t1 >= 0) {
455 if (t2 >= 0) {
456 return ((t1 | t2) + 0x80000000);
457 } else {
458 return ((t1 | b) + 0x80000000);
459 }
460 } else {
461 if (t2 >= 0) {
462 return ((a | t2) + 0x80000000);
463 } else {
464 return (a | b);
465 }
466 }
467}
468
469function xor(a, b) {
470 a = integer(a);
471 b = integer(b);
472 var t1 = a - 0x80000000;
473 var t2 = b - 0x80000000;
474 if (t1 >= 0) {
475 if (t2 >= 0) {
476 return (t1 ^ t2);
477 } else {
478 return ((t1 ^ b) + 0x80000000);
479 }
480 } else {
481 if (t2 >= 0) {
482 return ((a ^ t2) + 0x80000000);
483 } else {
484 return (a ^ b);
485 }
486 }
487}
488
489function not(a) {
490 a = integer(a);
491 return 0xffffffff - a;
492}
493
494/* Here begin the real algorithm */
495
496var state = new array(4);
497var count = new array(2);
498 count[0] = 0;
499 count[1] = 0;
500var buffer = new array(64);
501var transformBuffer = new array(16);
502var digestBits = new array(16);
503
504var S11 = 7;
505var S12 = 12;
506var S13 = 17;
507var S14 = 22;
508var S21 = 5;
509var S22 = 9;
510var S23 = 14;
511var S24 = 20;
512var S31 = 4;
513var S32 = 11;
514var S33 = 16;
515var S34 = 23;
516var S41 = 6;
517var S42 = 10;
518var S43 = 15;
519var S44 = 21;
520
521function F(x, y, z) {
522 return or(and(x, y), and(not(x), z));
523}
524
525function G(x, y, z) {
526 return or(and(x, z), and(y, not(z)));
527}
528
529function H(x, y, z) {
530 return xor(xor(x, y), z);
531}
532
533function I(x, y, z) {
534 return xor(y ,or(x , not(z)));
535}
536
537function rotateLeft(a, n) {
538 return or(shl(a, n), (shr(a, (32 - n))));
539}
540
541function FF(a, b, c, d, x, s, ac) {
542 a = a + F(b, c, d) + x + ac;
543 a = rotateLeft(a, s);
544 a = a + b;
545 return a;
546}
547
548function GG(a, b, c, d, x, s, ac) {
549 a = a + G(b, c, d) + x + ac;
550 a = rotateLeft(a, s);
551 a = a + b;
552 return a;
553}
554
555function HH(a, b, c, d, x, s, ac) {
556 a = a + H(b, c, d) + x + ac;
557 a = rotateLeft(a, s);
558 a = a + b;
559 return a;
560}
561
562function II(a, b, c, d, x, s, ac) {
563 a = a + I(b, c, d) + x + ac;
564 a = rotateLeft(a, s);
565 a = a + b;
566 return a;
567}
568
569function transform(buf, offset) {
570 var a = 0, b = 0, c = 0, d = 0;
571 var x = transformBuffer;
572
573 a = state[0];
574 b = state[1];
575 c = state[2];
576 d = state[3];
577
578 for (i = 0; i < 16; i++) {
579 x[i] = and(buf[i * 4 + offset], 0xFF);
580 for (j = 1; j < 4; j++) {
581 x[i] += shl(and(buf[i * 4 + j + offset] ,0xFF), j * 8);
582 }
583 }
584
585 /* Round 1 */
586 a = FF( a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
587 d = FF( d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
588 c = FF( c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
589 b = FF( b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
590 a = FF( a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
591 d = FF( d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
592 c = FF( c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
593 b = FF( b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
594 a = FF( a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
595 d = FF( d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
596 c = FF( c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
597 b = FF( b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
598 a = FF( a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
599 d = FF( d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
600 c = FF( c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
601 b = FF( b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
602
603 /* Round 2 */
604 a = GG( a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
605 d = GG( d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
606 c = GG( c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
607 b = GG( b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
608 a = GG( a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
609 d = GG( d, a, b, c, x[10], S22, 0x2441453); /* 22 */
610 c = GG( c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
611 b = GG( b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
612 a = GG( a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
613 d = GG( d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
614 c = GG( c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
615 b = GG( b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
616 a = GG( a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
617 d = GG( d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
618 c = GG( c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
619 b = GG( b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
620
621 /* Round 3 */
622 a = HH( a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
623 d = HH( d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
624 c = HH( c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
625 b = HH( b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
626 a = HH( a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
627 d = HH( d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
628 c = HH( c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
629 b = HH( b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
630 a = HH( a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
631 d = HH( d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
632 c = HH( c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
633 b = HH( b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
634 a = HH( a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
635 d = HH( d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
636 c = HH( c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
637 b = HH( b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
638
639 /* Round 4 */
640 a = II( a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
641 d = II( d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
642 c = II( c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
643 b = II( b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
644 a = II( a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
645 d = II( d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
646 c = II( c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
647 b = II( b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
648 a = II( a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
649 d = II( d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
650 c = II( c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
651 b = II( b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
652 a = II( a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
653 d = II( d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
654 c = II( c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
655 b = II( b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
656
657 state[0] += a;
658 state[1] += b;
659 state[2] += c;
660 state[3] += d;
661
662}
663
664function md5_init() {
665 count[0] = count[1] = 0;
666 state[0] = 0x67452301;
667 state[1] = 0xefcdab89;
668 state[2] = 0x98badcfe;
669 state[3] = 0x10325476;
670 for (i = 0; i < digestBits.length; i++) {
671 digestBits[i] = 0;
672 }
673}
674
675function md5_update(b) {
676 var index, i;
677
678 index = and(shr(count[0],3) , 0x3F);
679 if (count[0] < 0xFFFFFFFF - 7) {
680 count[0] += 8;
681 } else {
682 count[1]++;
683 count[0] -= 0xFFFFFFFF + 1;
684 count[0] += 8;
685 }
686 buffer[index] = and(b, 0xff);
687 if (index >= 63) {
688 transform(buffer, 0);
689 }
690}
691
692function md5_finish() {
693 var bits = new array(8);
694 var padding;
695 var i = 0, index = 0, padLen = 0;
696
697 for (i = 0; i < 4; i++) {
698 bits[i] = and(shr(count[0], (i * 8)), 0xFF);
699 }
700 for (i = 0; i < 4; i++) {
701 bits[i + 4] = and(shr(count[1], (i * 8)), 0xFF);
702 }
703 index = and(shr(count[0], 3), 0x3F);
704 padLen = (index < 56) ? (56 - index) : (120 - index);
705 padding = new array(64);
706 padding[0] = 0x80;
707 for (i = 0; i < padLen; i++) {
708 md5_update(padding[i]);
709 }
710 for (i = 0; i < 8; i++) {
711 md5_update(bits[i]);
712 }
713
714 for (i = 0; i < 4; i++) {
715 for (j = 0; j < 4; j++) {
716 digestBits[i * 4 + j] = and(shr(state[i], (j * 8)) , 0xFF);
717 }
718 }
719}
720
721/* End of the MD5 algorithm */
722
723//#############################################################################
724 //Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (aes.js)
725//#############################################################################
726
727
728/* rijndael.js Rijndael Reference Implementation
729
730 This is a modified version of the software described below,
731 produced in September 2003 by John Walker for use in the
732 JavsScrypt browser-based encryption package. The principal
733 changes are replacing the original getRandomBytes function with
734 one which calls our pseudorandom generator (which must
735 be instantiated and seeded before the first call on getRandomBytes),
736 and changing keySizeInBits to 256. Some code not required by the
737 JavsScrypt application has been commented out. Please see
738 http://www.fourmilab.ch/javascrypt/ for further information on
739 JavaScrypt.
740
741 The following is the original copyright and application
742 information.
743
744 Copyright (c) 2001 Fritz Schneider
745
746 This software is provided as-is, without express or implied warranty.
747 Permission to use, copy, modify, distribute or sell this software, with or
748 without fee, for any purpose and by any individual or organization, is hereby
749 granted, provided that the above copyright notice and this paragraph appear
750 in all copies. Distribution as a part of an application or binary must
751 include the above copyright notice in the documentation and/or other materials
752 provided with the application or distribution.
753
754 As the above disclaimer notes, you are free to use this code however you
755 want. However, I would request that you send me an email
756 (fritz /at/ cs /dot/ ucsd /dot/ edu) to say hi if you find this code useful
757 or instructional. Seeing that people are using the code acts as
758 encouragement for me to continue development. If you *really* want to thank
759 me you can buy the book I wrote with Thomas Powell, _JavaScript:
760 _The_Complete_Reference_ :)
761
762 This code is an UNOPTIMIZED REFERENCE implementation of Rijndael.
763 If there is sufficient interest I can write an optimized (word-based,
764 table-driven) version, although you might want to consider using a
765 compiled language if speed is critical to your application. As it stands,
766 one run of the monte carlo test (10,000 encryptions) can take up to
767 several minutes, depending upon your processor. You shouldn't expect more
768 than a few kilobytes per second in throughput.
769
770 Also note that there is very little error checking in these functions.
771 Doing proper error checking is always a good idea, but the ideal
772 implementation (using the instanceof operator and exceptions) requires
773 IE5+/NS6+, and I've chosen to implement this code so that it is compatible
774 with IE4/NS4.
775
776 And finally, because JavaScript doesn't have an explicit byte/char data
777 type (although JavaScript 2.0 most likely will), when I refer to "byte"
778 in this code I generally mean "32 bit integer with value in the interval
779 [0,255]" which I treat as a byte.
780
781 See http://www-cse.ucsd.edu/~fritz/rijndael.html for more documentation
782 of the (very simple) API provided by this code.
783
784 Fritz Schneider
785 fritz at cs.ucsd.edu
786
787*/
788
789
790// Rijndael parameters -- Valid values are 128, 192, or 256
791
792var keySizeInBits = 256;
793var blockSizeInBits = 128;
794
795//
796// Note: in the following code the two dimensional arrays are indexed as
797// you would probably expect, as array[row][column]. The state arrays
798// are 2d arrays of the form state[4][Nb].
799
800
801// The number of rounds for the cipher, indexed by [Nk][Nb]
802var roundsArray = [ ,,,,[,,,,10,, 12,, 14],,
803 [,,,,12,, 12,, 14],,
804 [,,,,14,, 14,, 14] ];
805
806// The number of bytes to shift by in shiftRow, indexed by [Nb][row]
807var shiftOffsets = [ ,,,,[,1, 2, 3],,[,1, 2, 3],,[,1, 3, 4] ];
808
809// The round constants used in subkey expansion
810var Rcon = [
8110x01, 0x02, 0x04, 0x08, 0x10, 0x20,
8120x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
8130xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
8140x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
8150xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 ];
816
817// Precomputed lookup table for the SBox
818var SBox = [
819 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171,
820118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164,
821114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113,
822216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226,
823235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214,
824179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
825190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69,
826249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245,
827188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68,
82823, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42,
829144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73,
830 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109,
831141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37,
832 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
833181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225,
834248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
835140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187,
836 22 ];
837
838// Precomputed lookup table for the inverse SBox
839var SBoxInverse = [
840 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215,
841251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222,
842233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66,
843250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73,
844109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92,
845204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21,
846 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247,
847228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2,
848193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220,
849234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173,
850 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29,
851 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75,
852198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168,
853 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81,
854127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160,
855224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
856 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12,
857125 ];
858
859// This method circularly shifts the array left by the number of elements
860// given in its parameter. It returns the resulting array and is used for
861// the ShiftRow step. Note that shift() and push() could be used for a more
862// elegant solution, but they require IE5.5+, so I chose to do it manually.
863
864function cyclicShiftLeft(theArray, positions) {
865 var temp = theArray.slice(0, positions);
866 theArray = theArray.slice(positions).concat(temp);
867 return theArray;
868}
869
870// Cipher parameters ... do not change these
871var Nk = keySizeInBits / 32;
872var Nb = blockSizeInBits / 32;
873var Nr = roundsArray[Nk][Nb];
874
875// Multiplies the element "poly" of GF(2^8) by x. See the Rijndael spec.
876
877function xtime(poly) {
878 poly <<= 1;
879 return ((poly & 0x100) ? (poly ^ 0x11B) : (poly));
880}
881
882// Multiplies the two elements of GF(2^8) together and returns the result.
883// See the Rijndael spec, but should be straightforward: for each power of
884// the indeterminant that has a 1 coefficient in x, add y times that power
885// to the result. x and y should be bytes representing elements of GF(2^8)
886
887function mult_GF256(x, y) {
888 var bit, result = 0;
889
890 for (bit = 1; bit < 256; bit *= 2, y = xtime(y)) {
891 if (x & bit)
892 result ^= y;
893 }
894 return result;
895}
896
897// Performs the substitution step of the cipher. State is the 2d array of
898// state information (see spec) and direction is string indicating whether
899// we are performing the forward substitution ("encrypt") or inverse
900// substitution (anything else)
901
902function byteSub(state, direction) {
903 var S;
904 if (direction == "encrypt") // Point S to the SBox we're using
905 S = SBox;
906 else
907 S = SBoxInverse;
908 for (var i = 0; i < 4; i++) // Substitute for every byte in state
909 for (var j = 0; j < Nb; j++)
910 state[i][j] = S[state[i][j]];
911}
912
913// Performs the row shifting step of the cipher.
914
915function shiftRow(state, direction) {
916 for (var i=1; i<4; i++) // Row 0 never shifts
917 if (direction == "encrypt")
918 state[i] = cyclicShiftLeft(state[i], shiftOffsets[Nb][i]);
919 else
920 state[i] = cyclicShiftLeft(state[i], Nb - shiftOffsets[Nb][i]);
921
922}
923
924// Performs the column mixing step of the cipher. Most of these steps can
925// be combined into table lookups on 32bit values (at least for encryption)
926// to greatly increase the speed.
927
928function mixColumn(state, direction) {
929 var b = []; // Result of matrix multiplications
930 for (var j = 0; j < Nb; j++) { // Go through each column...
931 for (var i = 0; i < 4; i++) { // and for each row in the column...
932 if (direction == "encrypt")
933 b[i] = mult_GF256(state[i][j], 2) ^ // perform mixing
934 mult_GF256(state[(i+1)%4][j], 3) ^
935 state[(i+2)%4][j] ^
936 state[(i+3)%4][j];
937 else
938 b[i] = mult_GF256(state[i][j], 0xE) ^
939 mult_GF256(state[(i+1)%4][j], 0xB) ^
940 mult_GF256(state[(i+2)%4][j], 0xD) ^
941 mult_GF256(state[(i+3)%4][j], 9);
942 }
943 for (var i = 0; i < 4; i++) // Place result back into column
944 state[i][j] = b[i];
945 }
946}
947
948// Adds the current round key to the state information. Straightforward.
949
950function addRoundKey(state, roundKey) {
951 for (var j = 0; j < Nb; j++) { // Step through columns...
952 state[0][j] ^= (roundKey[j] & 0xFF); // and XOR
953 state[1][j] ^= ((roundKey[j]>>8) & 0xFF);
954 state[2][j] ^= ((roundKey[j]>>16) & 0xFF);
955 state[3][j] ^= ((roundKey[j]>>24) & 0xFF);
956 }
957}
958
959// This function creates the expanded key from the input (128/192/256-bit)
960// key. The parameter key is an array of bytes holding the value of the key.
961// The returned value is an array whose elements are the 32-bit words that
962// make up the expanded key.
963
964function keyExpansion(key) {
965 var expandedKey = new Array();
966 var temp;
967
968 // in case the key size or parameters were changed...
969 Nk = keySizeInBits / 32;
970 Nb = blockSizeInBits / 32;
971 Nr = roundsArray[Nk][Nb];
972
973 for (var j=0; j < Nk; j++) // Fill in input key first
974 expandedKey[j] =
975 (key[4*j]) | (key[4*j+1]<<8) | (key[4*j+2]<<16) | (key[4*j+3]<<24);
976
977 // Now walk down the rest of the array filling in expanded key bytes as
978 // per Rijndael's spec
979 for (j = Nk; j < Nb * (Nr + 1); j++) { // For each word of expanded key
980 temp = expandedKey[j - 1];
981 if (j % Nk == 0)
982 temp = ( (SBox[(temp>>8) & 0xFF]) |
983 (SBox[(temp>>16) & 0xFF]<<8) |
984 (SBox[(temp>>24) & 0xFF]<<16) |
985 (SBox[temp & 0xFF]<<24) ) ^ Rcon[Math.floor(j / Nk) - 1];
986 else if (Nk > 6 && j % Nk == 4)
987 temp = (SBox[(temp>>24) & 0xFF]<<24) |
988 (SBox[(temp>>16) & 0xFF]<<16) |
989 (SBox[(temp>>8) & 0xFF]<<8) |
990 (SBox[temp & 0xFF]);
991 expandedKey[j] = expandedKey[j-Nk] ^ temp;
992 }
993 return expandedKey;
994}
995
996// Rijndael's round functions...
997
998function Round(state, roundKey) {
999 byteSub(state, "encrypt");
1000 shiftRow(state, "encrypt");
1001 mixColumn(state, "encrypt");
1002 addRoundKey(state, roundKey);
1003}
1004
1005function InverseRound(state, roundKey) {
1006 addRoundKey(state, roundKey);
1007 mixColumn(state, "decrypt");
1008 shiftRow(state, "decrypt");
1009 byteSub(state, "decrypt");
1010}
1011
1012function FinalRound(state, roundKey) {
1013 byteSub(state, "encrypt");
1014 shiftRow(state, "encrypt");
1015 addRoundKey(state, roundKey);
1016}
1017
1018function InverseFinalRound(state, roundKey){
1019 addRoundKey(state, roundKey);
1020 shiftRow(state, "decrypt");
1021 byteSub(state, "decrypt");
1022}
1023
1024// encrypt is the basic encryption function. It takes parameters
1025// block, an array of bytes representing a plaintext block, and expandedKey,
1026// an array of words representing the expanded key previously returned by
1027// keyExpansion(). The ciphertext block is returned as an array of bytes.
1028
1029function encrypt(block, expandedKey) {
1030 var i;
1031 if (!block || block.length*8 != blockSizeInBits)
1032 return;
1033 if (!expandedKey)
1034 return;
1035
1036 block = packBytes(block);
1037 addRoundKey(block, expandedKey);
1038 for (i=1; i<Nr; i++)
1039 Round(block, expandedKey.slice(Nb*i, Nb*(i+1)));
1040 FinalRound(block, expandedKey.slice(Nb*Nr));
1041 return unpackBytes(block);
1042}
1043
1044// decrypt is the basic decryption function. It takes parameters
1045// block, an array of bytes representing a ciphertext block, and expandedKey,
1046// an array of words representing the expanded key previously returned by
1047// keyExpansion(). The decrypted block is returned as an array of bytes.
1048
1049function decrypt(block, expandedKey) {
1050 var i;
1051 if (!block || block.length*8 != blockSizeInBits)
1052 return;
1053 if (!expandedKey)
1054 return;
1055
1056 block = packBytes(block);
1057 InverseFinalRound(block, expandedKey.slice(Nb*Nr));
1058 for (i = Nr - 1; i>0; i--)
1059 InverseRound(block, expandedKey.slice(Nb*i, Nb*(i+1)));
1060 addRoundKey(block, expandedKey);
1061 return unpackBytes(block);
1062}
1063
1064/* !NEEDED
1065// This method takes a byte array (byteArray) and converts it to a string by
1066// applying String.fromCharCode() to each value and concatenating the result.
1067// The resulting string is returned. Note that this function SKIPS zero bytes
1068// under the assumption that they are padding added in formatPlaintext().
1069// Obviously, do not invoke this method on raw data that can contain zero
1070// bytes. It is really only appropriate for printable ASCII/Latin-1
1071// values. Roll your own function for more robust functionality :)
1072
1073function byteArrayToString(byteArray) {
1074 var result = "";
1075 for(var i=0; i<byteArray.length; i++)
1076 if (byteArray[i] != 0)
1077 result += String.fromCharCode(byteArray[i]);
1078 return result;
1079}
1080*/
1081
1082// This function takes an array of bytes (byteArray) and converts them
1083// to a hexadecimal string. Array element 0 is found at the beginning of
1084// the resulting string, high nibble first. Consecutive elements follow
1085// similarly, for example [16, 255] --> "10ff". The function returns a
1086// string.
1087
1088function byteArrayToHex(byteArray) {
1089 var result = "";
1090 if (!byteArray)
1091 return;
1092 for (var i=0; i<byteArray.length; i++)
1093 result += ((byteArray[i]<16) ? "0" : "") + byteArray[i].toString(16);
1094
1095 return result;
1096}
1097
1098// This function converts a string containing hexadecimal digits to an
1099// array of bytes. The resulting byte array is filled in the order the
1100// values occur in the string, for example "10FF" --> [16, 255]. This
1101// function returns an array.
1102
1103function hexToByteArray(hexString) {
1104 var byteArray = [];
1105 if (hexString.length % 2) // must have even length
1106 return;
1107 if (hexString.indexOf("0x") == 0 || hexString.indexOf("0X") == 0)
1108 hexString = hexString.substring(2);
1109 for (var i = 0; i<hexString.length; i += 2)
1110 byteArray[Math.floor(i/2)] = parseInt(hexString.slice(i, i+2), 16);
1111 return byteArray;
1112}
1113
1114// This function packs an array of bytes into the four row form defined by
1115// Rijndael. It assumes the length of the array of bytes is divisible by
1116// four. Bytes are filled in according to the Rijndael spec (starting with
1117// column 0, row 0 to 3). This function returns a 2d array.
1118
1119function packBytes(octets) {
1120 var state = new Array();
1121 if (!octets || octets.length % 4)
1122 return;
1123
1124 state[0] = new Array(); state[1] = new Array();
1125 state[2] = new Array(); state[3] = new Array();
1126 for (var j=0; j<octets.length; j+= 4) {
1127 state[0][j/4] = octets[j];
1128 state[1][j/4] = octets[j+1];
1129 state[2][j/4] = octets[j+2];
1130 state[3][j/4] = octets[j+3];
1131 }
1132 return state;
1133}
1134
1135// This function unpacks an array of bytes from the four row format preferred
1136// by Rijndael into a single 1d array of bytes. It assumes the input "packed"
1137// is a packed array. Bytes are filled in according to the Rijndael spec.
1138// This function returns a 1d array of bytes.
1139
1140function unpackBytes(packed) {
1141 var result = new Array();
1142 for (var j=0; j<packed[0].length; j++) {
1143 result[result.length] = packed[0][j];
1144 result[result.length] = packed[1][j];
1145 result[result.length] = packed[2][j];
1146 result[result.length] = packed[3][j];
1147 }
1148 return result;
1149}
1150
1151// This function takes a prospective plaintext (string or array of bytes)
1152// and pads it with pseudorandom bytes if its length is not a multiple of the block
1153// size. If plaintext is a string, it is converted to an array of bytes
1154// in the process. The type checking can be made much nicer using the
1155// instanceof operator, but this operator is not available until IE5.0 so I
1156// chose to use the heuristic below.
1157
1158function formatPlaintext(plaintext) {
1159 var bpb = blockSizeInBits / 8; // bytes per block
1160 var fillWithRandomBits;
1161 var i;
1162
1163 // if primitive string or String instance
1164 if ((!((typeof plaintext == "object") &&
1165 ((typeof (plaintext[0])) == "number"))) &&
1166 ((typeof plaintext == "string") || plaintext.indexOf))
1167 {
1168 plaintext = plaintext.split("");
1169 // Unicode issues here (ignoring high byte)
1170 for (i=0; i<plaintext.length; i++) {
1171 plaintext[i] = plaintext[i].charCodeAt(0) & 0xFF;
1172 }
1173 }
1174
1175 i = plaintext.length % bpb;
1176 if (i > 0) {
1177//alert("adding " + (bpb - 1) + " bytes");
1178 // plaintext = plaintext.concat(getRandomBytes(bpb - i));
1179 {
1180 varpaddingBytes;
1181 var ii,cc;
1182
1183 paddingBytes = new Array();
1184 cc = bpb - i;
1185 for (ii=0; ii<cc; ii++) {
1186 paddingBytes[ii] = cc;
1187 }
1188
1189//is("cc", cc);
1190//is(getRandomBytes(bpb - i) + "", paddingBytes + "");
1191 plaintext = plaintext.concat(paddingBytes);
1192 }
1193 }
1194
1195 return plaintext;
1196}
1197
1198// Returns an array containing "howMany" random bytes.
1199
1200function getRandomBytes(howMany) {
1201 var i, bytes = new Array();
1202
1203//alert("getting some random bytes");
1204 for (i = 0; i < howMany; i++) {
1205 bytes[i] = prng.nextInt(255);
1206 }
1207 return bytes;
1208}
1209
1210// rijndaelEncrypt(plaintext, key, mode)
1211// Encrypts the plaintext using the given key and in the given mode.
1212// The parameter "plaintext" can either be a string or an array of bytes.
1213// The parameter "key" must be an array of key bytes. If you have a hex
1214// string representing the key, invoke hexToByteArray() on it to convert it
1215// to an array of bytes. The third parameter "mode" is a string indicating
1216// the encryption mode to use, either "ECB" or "CBC". If the parameter is
1217// omitted, ECB is assumed.
1218//
1219// An array of bytes representing the cihpertext is returned. To convert
1220// this array to hex, invoke byteArrayToHex() on it.
1221
1222function rijndaelEncrypt(plaintext, key, mode) {
1223 var expandedKey, i, aBlock;
1224 var bpb = blockSizeInBits / 8; // bytes per block
1225 var ct; // ciphertext
1226
1227 if (!plaintext || !key)
1228 return;
1229 if (key.length*8 != keySizeInBits)
1230 return;
1231 if (mode == "CBC") {
1232 ct = getRandomBytes(bpb); // get IV
1233//dump("IV", byteArrayToHex(ct));
1234 } else {
1235 mode = "ECB";
1236 ct = new Array();
1237 }
1238
1239 // convert plaintext to byte array and pad with zeros if necessary.
1240 plaintext = formatPlaintext(plaintext);
1241
1242 expandedKey = keyExpansion(key);
1243
1244 for (var block = 0; block < plaintext.length / bpb; block++) {
1245 aBlock = plaintext.slice(block * bpb, (block + 1) * bpb);
1246 if (mode == "CBC") {
1247 for (var i = 0; i < bpb; i++) {
1248 aBlock[i] ^= ct[(block * bpb) + i];
1249 }
1250 }
1251 ct = ct.concat(encrypt(aBlock, expandedKey));
1252 }
1253
1254 return ct;
1255}
1256
1257// rijndaelDecrypt(ciphertext, key, mode)
1258// Decrypts the using the given key and mode. The parameter "ciphertext"
1259// must be an array of bytes. The parameter "key" must be an array of key
1260// bytes. If you have a hex string representing the ciphertext or key,
1261// invoke hexToByteArray() on it to convert it to an array of bytes. The
1262// parameter "mode" is a string, either "CBC" or "ECB".
1263//
1264// An array of bytes representing the plaintext is returned. To convert
1265// this array to a hex string, invoke byteArrayToHex() on it. To convert it
1266// to a string of characters, you can use byteArrayToString().
1267
1268function rijndaelDecrypt(ciphertext, key, mode) {
1269 var expandedKey;
1270 var bpb = blockSizeInBits / 8; // bytes per block
1271 var pt = new Array(); // plaintext array
1272 var aBlock; // a decrypted block
1273 var block; // current block number
1274
1275 if (!ciphertext || !key || typeof ciphertext == "string")
1276 return;
1277 if (key.length*8 != keySizeInBits)
1278 return;
1279 if (!mode) {
1280 mode = "ECB"; // assume ECB if mode omitted
1281 }
1282
1283 expandedKey = keyExpansion(key);
1284
1285 // work backwards to accomodate CBC mode
1286 for (block=(ciphertext.length / bpb)-1; block>0; block--) {
1287 aBlock =
1288 decrypt(ciphertext.slice(block*bpb,(block+1)*bpb), expandedKey);
1289 if (mode == "CBC")
1290 for (var i=0; i<bpb; i++)
1291 pt[(block-1)*bpb + i] = aBlock[i] ^ ciphertext[(block-1)*bpb + i];
1292 else
1293 pt = aBlock.concat(pt);
1294 }
1295
1296 // do last block if ECB (skips the IV in CBC)
1297 if (mode == "ECB")
1298 pt = decrypt(ciphertext.slice(0, bpb), expandedKey).concat(pt);
1299
1300 return pt;
1301}
1302
1303//#############################################################################
1304 //Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (utf-8.js)
1305//#############################################################################
1306
1307
1308 /*Encoding and decoding of Unicode character strings as
1309 UTF-8 byte streams. */
1310
1311 //UNICODE_TO_UTF8 -- Encode Unicode argument string as UTF-8 return value
1312
1313 function unicode_to_utf8(s) {
1314 var utf8 = "";
1315
1316 for (var n = 0; n < s.length; n++) {
1317 var c = s.charCodeAt(n);
1318
1319 if (c <= 0x7F) {
1320 // 0x00 - 0x7F: Emit as single byte, unchanged
1321 utf8 += String.fromCharCode(c);
1322 } else if ((c >= 0x80) && (c <= 0x7FF)) {
1323 // 0x80 - 0x7FF: Output as two byte code, 0xC0 in first byte
1324 // 0x80 in second byte
1325 utf8 += String.fromCharCode((c >> 6) | 0xC0);
1326 utf8 += String.fromCharCode((c & 0x3F) | 0x80);
1327 } else {
1328 // 0x800 - 0xFFFF: Output as three bytes, 0xE0 in first byte
1329 // 0x80 in second byte
1330 // 0x80 in third byte
1331 utf8 += String.fromCharCode((c >> 12) | 0xE0);
1332 utf8 += String.fromCharCode(((c >> 6) & 0x3F) | 0x80);
1333 utf8 += String.fromCharCode((c & 0x3F) | 0x80);
1334 }
1335 }
1336 return utf8;
1337 }
1338
1339 //UTF8_TO_UNICODE -- Decode UTF-8 argument into Unicode string return value
1340
1341 function utf8_to_unicode(utf8) {
1342 var s = "", i = 0, b1, b2, b2;
1343
1344 while (i < utf8.length) {
1345 b1 = utf8.charCodeAt(i);
1346 if (b1 < 0x80) { // One byte code: 0x00 0x7F
1347 s += String.fromCharCode(b1);
1348 i++;
1349 } else if((b1 >= 0xC0) && (b1 < 0xE0)) {// Two byte code: 0x80 - 0x7FF
1350 b2 = utf8.charCodeAt(i + 1);
1351 s += String.fromCharCode(((b1 & 0x1F) << 6) | (b2 & 0x3F));
1352 i += 2;
1353 } else { // Three byte code: 0x800 - 0xFFFF
1354 b2 = utf8.charCodeAt(i + 1);
1355 b3 = utf8.charCodeAt(i + 2);
1356 s += String.fromCharCode(((b1 & 0xF) << 12) |
1357 ((b2 & 0x3F) << 6) |
1358 (b3 & 0x3F));
1359 i += 3;
1360 }
1361 }
1362 return s;
1363 }
1364
1365 /*ENCODE_UTF8 -- Encode string as UTF8 only if it contains
1366 a character of 0x9D (Unicode OPERATING
1367 SYSTEM COMMAND) or a character greater
1368 than 0xFF. This permits all strings
1369 consisting exclusively of 8 bit
1370 graphic characters to be encoded as
1371 themselves. We choose 0x9D as the sentinel
1372 character as opposed to one of the more
1373 logical PRIVATE USE characters because 0x9D
1374 is not overloaded by the regrettable
1375 "Windows-1252" character set. Now such characters
1376 don't belong in JavaScript strings, but you never
1377 know what somebody is going to paste into a
1378 text box, so this choice keeps Windows-encoded
1379 strings from bloating to UTF-8 encoding. */
1380
1381 function encode_utf8(s) {
1382 var i, necessary = false;
1383
1384 for (i = 0; i < s.length; i++) {
1385 if ((s.charCodeAt(i) == 0x9D) ||
1386 (s.charCodeAt(i) > 0xFF)) {
1387 necessary = true;
1388 break;
1389 }
1390 }
1391 if (!necessary) {
1392 return s;
1393 }
1394 return String.fromCharCode(0x9D) + unicode_to_utf8(s);
1395 }
1396
1397 /* DECODE_UTF8 -- Decode a string encoded with encode_utf8
1398 above. If the string begins with the
1399 sentinel character 0x9D (OPERATING
1400 SYSTEM COMMAND), then we decode the
1401 balance as a UTF-8 stream. Otherwise,
1402 the string is output unchanged, as
1403 it's guaranteed to contain only 8 bit
1404 characters excluding 0x9D. */
1405
1406 function decode_utf8(s) {
1407 if ((s.length > 0) && (s.charCodeAt(0) == 0x9D)) {
1408 return utf8_to_unicode(s.substring(1));
1409 }
1410 return s;
1411 }
1412
1413
1414//#############################################################################
1415 //Downloaded on April 26, 2006 from http://pajhome.org.uk/crypt/md5/md5.js
1416//#############################################################################
1417
1418/*
1419 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
1420 * Digest Algorithm, as defined in RFC 1321.
1421 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
1422 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
1423 * Distributed under the BSD License
1424 * See http://pajhome.org.uk/crypt/md5 for more info.
1425 */
1426
1427/*
1428 * Configurable variables. You may need to tweak these to be compatible with
1429 * the server-side, but the defaults work in most cases.
1430 */
1431var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
1432var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
1433var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
1434
1435/*
1436 * These are the functions you'll usually want to call
1437 * They take string arguments and return either hex or base-64 encoded strings
1438 */
1439function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
1440function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
1441function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
1442function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
1443function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
1444function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
1445
1446/*
1447 * Perform a simple self-test to see if the VM is working
1448 */
1449function md5_vm_test()
1450{
1451 return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
1452}
1453
1454/*
1455 * Calculate the MD5 of an array of little-endian words, and a bit length
1456 */
1457function core_md5(x, len)
1458{
1459 /* append padding */
1460 x[len >> 5] |= 0x80 << ((len) % 32);
1461 x[(((len + 64) >>> 9) << 4) + 14] = len;
1462
1463 var a = 1732584193;
1464 var b = -271733879;
1465 var c = -1732584194;
1466 var d = 271733878;
1467
1468 for(var i = 0; i < x.length; i += 16)
1469 {
1470 var olda = a;
1471 var oldb = b;
1472 var oldc = c;
1473 var oldd = d;
1474
1475 a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
1476 d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
1477 c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
1478 b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
1479 a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
1480 d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
1481 c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
1482 b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
1483 a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
1484 d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
1485 c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
1486 b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
1487 a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
1488 d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
1489 c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
1490 b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
1491
1492 a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
1493 d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
1494 c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
1495 b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
1496 a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
1497 d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
1498 c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
1499 b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
1500 a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
1501 d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
1502 c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
1503 b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
1504 a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
1505 d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
1506 c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
1507 b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
1508
1509 a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
1510 d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
1511 c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
1512 b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
1513 a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
1514 d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
1515 c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
1516 b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
1517 a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
1518 d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
1519 c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
1520 b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
1521 a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
1522 d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
1523 c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
1524 b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
1525
1526 a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
1527 d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
1528 c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
1529 b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
1530 a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
1531 d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
1532 c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
1533 b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
1534 a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
1535 d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
1536 c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
1537 b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
1538 a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
1539 d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
1540 c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
1541 b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
1542
1543 a = safe_add(a, olda);
1544 b = safe_add(b, oldb);
1545 c = safe_add(c, oldc);
1546 d = safe_add(d, oldd);
1547 }
1548 return Array(a, b, c, d);
1549
1550}
1551
1552/*
1553 * These functions implement the four basic operations the algorithm uses.
1554 */
1555function md5_cmn(q, a, b, x, s, t)
1556{
1557 return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
1558}
1559function md5_ff(a, b, c, d, x, s, t)
1560{
1561 return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
1562}
1563function md5_gg(a, b, c, d, x, s, t)
1564{
1565 return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
1566}
1567function md5_hh(a, b, c, d, x, s, t)
1568{
1569 return md5_cmn(b ^ c ^ d, a, b, x, s, t);
1570}
1571function md5_ii(a, b, c, d, x, s, t)
1572{
1573 return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
1574}
1575
1576/*
1577 * Calculate the HMAC-MD5, of a key and some data
1578 */
1579function core_hmac_md5(key, data)
1580{
1581 var bkey = str2binl(key);
1582 if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
1583
1584 var ipad = Array(16), opad = Array(16);
1585 for(var i = 0; i < 16; i++)
1586 {
1587 ipad[i] = bkey[i] ^ 0x36363636;
1588 opad[i] = bkey[i] ^ 0x5C5C5C5C;
1589 }
1590
1591 var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
1592 return core_md5(opad.concat(hash), 512 + 128);
1593}
1594
1595/*
1596 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
1597 * to work around bugs in some JS interpreters.
1598 */
1599function safe_add(x, y)
1600{
1601 var lsw = (x & 0xFFFF) + (y & 0xFFFF);
1602 var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
1603 return (msw << 16) | (lsw & 0xFFFF);
1604}
1605
1606/*
1607 * Bitwise rotate a 32-bit number to the left.
1608 */
1609function bit_rol(num, cnt)
1610{
1611 return (num << cnt) | (num >>> (32 - cnt));
1612}
1613
1614/*
1615 * Convert a string to an array of little-endian words
1616 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
1617 */
1618function str2binl(str)
1619{
1620 var bin = Array();
1621 var mask = (1 << chrsz) - 1;
1622 for(var i = 0; i < str.length * chrsz; i += chrsz)
1623 bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
1624 return bin;
1625}
1626
1627/*
1628 * Convert an array of little-endian words to a string
1629 */
1630function binl2str(bin)
1631{
1632 var str = "";
1633 var mask = (1 << chrsz) - 1;
1634 for(var i = 0; i < bin.length * 32; i += chrsz)
1635 str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
1636 return str;
1637}
1638
1639/*
1640 * Convert an array of little-endian words to a hex string.
1641 */
1642function binl2hex(binarray)
1643{
1644 var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
1645 var str = "";
1646 for(var i = 0; i < binarray.length * 4; i++)
1647 {
1648 str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
1649 hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
1650 }
1651 return str;
1652}
1653
1654/*
1655 * Convert an array of little-endian words to a base-64 string
1656 */
1657function binl2b64(binarray)
1658{
1659 var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1660 var str = "";
1661 for(var i = 0; i < binarray.length * 4; i += 3)
1662 {
1663 var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
1664 | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
1665 | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
1666 for(var j = 0; j < 4; j++)
1667 {
1668 if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
1669 else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
1670 }
1671 }
1672 return str;
1673}
1674
1675
1676//#############################################################################
1677//#############################################################################
1678//#############################################################################
1679
1680
1681
1682MochiKit.Base.update(Clipperz.Crypto.Base, {
1683
1684 '__repr__': function () {
1685 return "[" + this.NAME + " " + this.VERSION + "]";
1686 },
1687
1688 'toString': function () {
1689 return this.__repr__();
1690 },
1691
1692 //-----------------------------------------------------------------------------
1693
1694 'encryptUsingSecretKey': function (aKey, aMessage) {
1695//Clipperz.Profile.start("Clipperz.Crypto.Base.encryptUsingSecretKey");
1696 var result;
1697 var plaintext;
1698 varheader;
1699 varkey;
1700
1701 key = hexToByteArray(Clipperz.Crypto.Base.computeHashValue(aKey));
1702
1703 addEntropyTime();
1704 prng = new AESprng(keyFromEntropy());
1705
1706 plaintext = encode_utf8(aMessage);
1707
1708 header = Clipperz.Base.byteArrayToString(hexToByteArray(Clipperz.Crypto.Base.computeMD5HashValue(plaintext)));
1709
1710 // Add message length in bytes to header
1711 i = plaintext.length;
1712 header += String.fromCharCode(i >>> 24);
1713 header += String.fromCharCode(i >>> 16);
1714 header += String.fromCharCode(i >>> 8);
1715 header += String.fromCharCode(i & 0xFF);
1716
1717 //The format of the actual message passed to rijndaelEncrypt
1718 //is:
1719 //
1720 // Bytes Content
1721 // 0-15 MD5 signature of plaintext
1722 // 16-19 Length of plaintext, big-endian order
1723 // 20-end Plaintext
1724 //
1725 //Note that this message will be padded with zero bytes
1726 //to an integral number of AES blocks (blockSizeInBits / 8).
1727 //This does not include the initial vector for CBC
1728 //encryption, which is added internally by rijndaelEncrypt.
1729 result = byteArrayToHex(rijndaelEncrypt(header + plaintext, key, "CBC"));
1730
1731 delete prng;
1732
1733//Clipperz.Profile.stop("Clipperz.Crypto.Base.encryptUsingSecretKey");
1734 return result;
1735 },
1736
1737 //.............................................................................
1738
1739 'decryptUsingSecretKey': function (aKey, aMessage) {
1740//Clipperz.Profile.start("Clipperz.Crypto.Base.decryptUsingSecretKey");
1741 varkey;
1742 var decryptedText;
1743 vartextLength;
1744 varheader;
1745 varheaderDigest;
1746 var plaintext;
1747 var i;
1748
1749 key = hexToByteArray(Clipperz.Crypto.Base.computeHashValue(aKey));
1750
1751 decryptedText = rijndaelDecrypt(hexToByteArray(aMessage), key, "CBC");
1752
1753 header = decryptedText.slice(0, 20);
1754 decryptedText = decryptedText.slice(20);
1755
1756 headerDigest = byteArrayToHex(header.slice(0,16));
1757 textLength = (header[16] << 24) | (header[17] << 16) | (header[18] << 8) | header[19];
1758
1759 if ((textLength < 0) || (textLength > decryptedText.length)) {
1760 // jslog.warning("Message (length " + decryptedText.length + ") truncated. " + textLength + " characters expected.");
1761 //Try to sauve qui peut by setting length to entire message
1762 textLength = decryptedText.length;
1763 }
1764
1765 plainText = "";
1766
1767 for (i=0; i<textLength; i++) {
1768 plainText += String.fromCharCode(decryptedText[i]);
1769 }
1770
1771 if (Clipperz.Crypto.Base.computeMD5HashValue(plainText) != headerDigest) {
1772 // jslog.warning("Message corrupted. Checksum of decrypted message does not match.");
1773 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
1774 // throw new Error("Message corrupted. Checksum of decrypted message does not match. Parsed result: " + decode_utf8(plainText));
1775 }
1776
1777 // That's it; plug plaintext into the result field
1778
1779 result = decode_utf8(plainText);
1780
1781//Clipperz.Profile.stop("Clipperz.Crypto.Base.decryptUsingSecretKey");
1782 return result;
1783 },
1784
1785 //-----------------------------------------------------------------------------
1786
1787 'computeHashValue': function (aMessage) {
1788//Clipperz.Profile.start("Clipperz.Crypto.Base.computeHashValue");
1789 varresult;
1790
1791 result = hex_sha256(aMessage);
1792//Clipperz.Profile.stop("Clipperz.Crypto.Base.computeHashValue");
1793
1794 return result;
1795 },
1796
1797 //.........................................................................
1798
1799 'computeMD5HashValue': function (aMessage) {
1800 varresult;
1801//Clipperz.Profile.start("Clipperz.Crypto.Base.computeMD5HashValue");
1802 result = hex_md5(aMessage);
1803//Clipperz.Profile.stop("Clipperz.Crypto.Base.computeMD5HashValue");
1804
1805 return result;
1806 },
1807
1808 //-----------------------------------------------------------------------------
1809
1810 'generateRandomSeed': function () {
1811//Clipperz.Profile.start("Clipperz.Crypto.Base.generateRandomSeed");
1812 varresult;
1813 var seed;
1814 var prng;
1815 var charA;
1816 var i;
1817
1818 addEntropyTime();
1819
1820 seed = keyFromEntropy();
1821 prng = new AESprng(seed);
1822
1823 result = "";
1824 charA = ("A").charCodeAt(0);
1825
1826 for (i = 0; i < 64; i++) {
1827 result += String.fromCharCode(charA + prng.nextInt(25));
1828 }
1829
1830 delete prng;
1831
1832 result = Clipperz.Crypto.Base.computeHashValue(result);
1833
1834//Clipperz.Profile.stop("Clipperz.Crypto.Base.generateRandomSeed");
1835 return result;
1836 },
1837
1838 //-----------------------------------------------------------------------------
1839
1840 'exception': {
1841 'CorruptedMessage': new MochiKit.Base.NamedError("Clipperz.Crypto.Base.exception.CorruptedMessage")
1842 },
1843
1844 //.........................................................................
1845 __syntaxFix__: "syntax fix"
1846});
1847
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/BigInt.js b/frontend/gamma/js/ClipperzCryptoLibrary/BigInt.js
deleted file mode 100644
index 197cd9a..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/BigInt.js
+++ b/dev/null
@@ -1,1755 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
26
27//#############################################################################
28 //Downloaded on March 05, 2007 from http://www.leemon.com/crypto/BigInt.js
29//#############################################################################
30
31
32////////////////////////////////////////////////////////////////////////////////////////
33// Big Integer Library v. 5.0
34// Created 2000, last modified 2006
35// Leemon Baird
36// www.leemon.com
37//
38// This file is public domain. You can use it for any purpose without restriction.
39// I do not guarantee that it is correct, so use it at your own risk. If you use
40// it for something interesting, I'd appreciate hearing about it. If you find
41// any bugs or make any improvements, I'd appreciate hearing about those too.
42// It would also be nice if my name and address were left in the comments.
43// But none of that is required.
44//
45// This code defines a bigInt library for arbitrary-precision integers.
46// A bigInt is an array of integers storing the value in chunks of bpe bits,
47// little endian (buff[0] is the least significant word).
48// Negative bigInts are stored two's complement.
49// Some functions assume their parameters have at least one leading zero element.
50// Functions with an underscore at the end of the name have unpredictable behavior in case of overflow,
51// so the caller must make sure overflow won't happen.
52// For each function where a parameter is modified, that same
53// variable must not be used as another argument too.
54// So, you cannot square x by doing multMod_(x,x,n).
55// You must use squareMod_(x,n) instead, or do y=dup(x); multMod_(x,y,n).
56//
57// These functions are designed to avoid frequent dynamic memory allocation in the inner loop.
58// For most functions, if it needs a BigInt as a local variable it will actually use
59// a global, and will only allocate to it when it's not the right size. This ensures
60// that when a function is called repeatedly with same-sized parameters, it only allocates
61// memory on the first call.
62//
63// Note that for cryptographic purposes, the calls to Math.random() must
64// be replaced with calls to a better pseudorandom number generator.
65//
66// In the following, "bigInt" means a bigInt with at least one leading zero element,
67// and "integer" means a nonnegative integer less than radix. In some cases, integer
68// can be negative. Negative bigInts are 2s complement.
69//
70// The following functions do not modify their inputs, but dynamically allocate memory every time they are called:
71//
72// function bigInt2str(x,base) //convert a bigInt into a string in a given base, from base 2 up to base 95
73// function dup(x) //returns a copy of bigInt x
74// function findPrimes(n) //return array of all primes less than integer n
75// function int2bigInt(t,n,m) //convert integer t to a bigInt with at least n bits and m array elements
76// function int2bigInt(s,b,n,m) //convert string s in base b to a bigInt with at least n bits and m array elements
77// function trim(x,k) //return a copy of x with exactly k leading zero elements
78//
79// The following functions do not modify their inputs, so there is never a problem with the result being too big:
80//
81// function bitSize(x) //returns how many bits long the bigInt x is, not counting leading zeros
82// function equals(x,y) //is the bigInt x equal to the bigint y?
83// function equalsInt(x,y) //is bigint x equal to integer y?
84// function greater(x,y) //is x>y? (x and y are nonnegative bigInts)
85// function greaterShift(x,y,shift)//is (x <<(shift*bpe)) > y?
86// function isZero(x) //is the bigInt x equal to zero?
87// 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)?
88// function modInt(x,n) //return x mod n for bigInt x and integer n.
89// function negative(x) //is bigInt x negative?
90//
91// The following functions do not modify their inputs, but allocate memory and call functions with underscores
92//
93// function add(x,y) //return (x+y) for bigInts x and y.
94// function addInt(x,n) //return (x+n) where x is a bigInt and n is an integer.
95// function expand(x,n) //return a copy of x with at least n elements, adding leading zeros if needed
96// function inverseMod(x,n) //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
97// function mod(x,n) //return a new bigInt equal to (x mod n) for bigInts x and n.
98// function mult(x,y) //return x*y for bigInts x and y. This is faster when y<x.
99// function multMod(x,y,n) //return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
100// 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.
101// function randTruePrime(k) //return a new, random, k-bit, true prime using Maurer's algorithm.
102// function sub(x,y) //return (x-y) for bigInts x and y. Negative answers will be 2s complement
103//
104// The following functions write a bigInt result to one of the parameters, but
105// the result is never bigger than the original, so there can't be overflow problems:
106//
107// function divInt_(x,n) //do x=floor(x/n) for bigInt x and integer n, and return the remainder
108// function GCD_(x,y) //set x to the greatest common divisor of bigInts x and y, (y is destroyed).
109// function halve_(x) //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
110// function mod_(x,n) //do x=x mod n for bigInts x and n.
111// function rightShift_(x,n) //right shift bigInt x by n bits. 0 <= n < bpe.
112//
113// The following functions write a bigInt result to one of the parameters. The caller is responsible for
114// ensuring it is large enough to hold the result.
115//
116// function addInt_(x,n) //do x=x+n where x is a bigInt and n is an integer
117// function add_(x,y) //do x=x+y for bigInts x and y
118// function addShift_(x,y,ys) //do x=x+(y<<(ys*bpe))
119// function copy_(x,y) //do x=y on bigInts x and y
120// function copyInt_(x,n) //do x=n on bigInt x and integer n
121// function carry_(x) //do carries and borrows so each element of the bigInt x fits in bpe bits.
122// function divide_(x,y,q,r) //divide_ x by y giving quotient q and remainder r
123// 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
124// function inverseMod_(x,n) //do x=x**(-1) mod n, for bigInts x and n. Returns 1 (0) if inverse does (doesn't) exist
125// function inverseModInt_(x,n) //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
126// function leftShift_(x,n) //left shift bigInt x by n bits. n<bpe.
127// function linComb_(x,y,a,b) //do x=a*x+b*y for bigInts x and y and integers a and b
128// function linCombShift_(x,y,b,ys) //do x=x+b*(y<<(ys*bpe)) for bigInts x and y, and integers b and ys
129// function mont_(x,y,n,np) //Montgomery multiplication (see comments where the function is defined)
130// function mult_(x,y) //do x=x*y for bigInts x and y.
131// function multInt_(x,n) //do x=x*n where x is a bigInt and n is an integer.
132// function multMod_(x,y,n) //do x=x*y mod n for bigInts x,y,n.
133// 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.
134// 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.
135// function randTruePrime_(ans,k) //do ans = a random k-bit true random prime (not just probable prime) with 1 in the msb.
136// function squareMod_(x,n) //do x=x*x mod n for bigInts x,n
137// function sub_(x,y) //do x=x-y for bigInts x and y. Negative answers will be 2s complement.
138// function subShift_(x,y,ys) //do x=x-(y<<(ys*bpe)). Negative answers will be 2s complement.
139//
140// The following functions are based on algorithms from the _Handbook of Applied Cryptography_
141// powMod_() = algorithm 14.94, Montgomery exponentiation
142// eGCD_,inverseMod_() = algorithm 14.61, Binary extended GCD_
143// GCD_() = algorothm 14.57, Lehmer's algorithm
144// mont_() = algorithm 14.36, Montgomery multiplication
145// divide_() = algorithm 14.20 Multiple-precision division
146// squareMod_() = algorithm 14.16 Multiple-precision squaring
147// randTruePrime_() = algorithm 4.62, Maurer's algorithm
148// millerRabin() = algorithm 4.24, Miller-Rabin algorithm
149//
150// Profiling shows:
151// randTruePrime_() spends:
152// 10% of its time in calls to powMod_()
153// 85% of its time in calls to millerRabin()
154// millerRabin() spends:
155// 99% of its time in calls to powMod_() (always with a base of 2)
156// powMod_() spends:
157// 94% of its time in calls to mont_() (almost always with x==y)
158//
159// This suggests there are several ways to speed up this library slightly:
160// - convert powMod_ to use a Montgomery form of k-ary window (or maybe a Montgomery form of sliding window)
161// -- this should especially focus on being fast when raising 2 to a power mod n
162// - convert randTruePrime_() to use a minimum r of 1/3 instead of 1/2 with the appropriate change to the test
163// - tune the parameters in randTruePrime_(), including c, m, and recLimit
164// - speed up the single loop in mont_() that takes 95% of the runtime, perhaps by reducing checking
165// within the loop when all the parameters are the same length.
166//
167// There are several ideas that look like they wouldn't help much at all:
168// - replacing trial division in randTruePrime_() with a sieve (that speeds up something taking almost no time anyway)
169// - 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)
170// - speeding up mont_(x,y,n,np) when x==y by doing a non-modular, non-Montgomery square
171// followed by a Montgomery reduction. The intermediate answer will be twice as long as x, so that
172// method would be slower. This is unfortunate because the code currently spends almost all of its time
173// doing mont_(x,x,...), both for randTruePrime_() and powMod_(). A faster method for Montgomery squaring
174// would have a large impact on the speed of randTruePrime_() and powMod_(). HAC has a couple of poorly-worded
175// sentences that seem to imply it's faster to do a non-modular square followed by a single
176// Montgomery reduction, but that's obviously wrong.
177////////////////////////////////////////////////////////////////////////////////////////
178
179//globals
180bpe=0; //bits stored per array element
181mask=0; //AND this with an array element to chop it down to bpe bits
182radix=mask+1; //equals 2^bpe. A single 1 bit to the left of the last bit of mask.
183
184//the digits for converting to different bases
185digitsStr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-';
186
187//initialize the global variables
188for (bpe=0; (1<<(bpe+1)) > (1<<bpe); bpe++); //bpe=number of bits in the mantissa on this platform
189bpe>>=1; //bpe=number of bits in one element of the array representing the bigInt
190mask=(1<<bpe)-1; //AND the mask with an integer to get its bpe least significant bits
191radix=mask+1; //2^bpe. a single 1 bit to the left of the first bit of mask
192one=int2bigInt(1,1,1); //constant used in powMod_()
193
194//the following global variables are scratchpad memory to
195//reduce dynamic memory allocation in the inner loop
196t=new Array(0);
197ss=t; //used in mult_()
198s0=t; //used in multMod_(), squareMod_()
199s1=t; //used in powMod_(), multMod_(), squareMod_()
200s2=t; //used in powMod_(), multMod_()
201s3=t; //used in powMod_()
202s4=t; s5=t; //used in mod_()
203s6=t; //used in bigInt2str()
204s7=t; //used in powMod_()
205T=t; //used in GCD_()
206sa=t; //used in mont_()
207mr_x1=t; mr_r=t; mr_a=t; //used in millerRabin()
208eg_v=t; eg_u=t; eg_A=t; eg_B=t; eg_C=t; eg_D=t; //used in eGCD_(), inverseMod_()
209md_q1=t; md_q2=t; md_q3=t; md_r=t; md_r1=t; md_r2=t; md_tt=t; //used in mod_()
210
211primes=t; pows=t; s_i=t; s_i2=t; s_R=t; s_rm=t; s_q=t; s_n1=t;
212 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_()
213
214////////////////////////////////////////////////////////////////////////////////////////
215
216//return array of all primes less than integer n
217function findPrimes(n) {
218 var i,s,p,ans;
219 s=new Array(n);
220 for (i=0;i<n;i++)
221 s[i]=0;
222 s[0]=2;
223 p=0; //first p elements of s are primes, the rest are a sieve
224 for(;s[p]<n;) { //s[p] is the pth prime
225 for(i=s[p]*s[p]; i<n; i+=s[p]) //mark multiples of s[p]
226 s[i]=1;
227 p++;
228 s[p]=s[p-1]+1;
229 for(; s[p]<n && s[s[p]]; s[p]++); //find next prime (where s[p]==0)
230 }
231 ans=new Array(p);
232 for(i=0;i<p;i++)
233 ans[i]=s[i];
234 return ans;
235}
236
237//does a single round of Miller-Rabin base b consider x to be a possible prime?
238//x is a bigInt, and b is an integer
239function millerRabin(x,b) {
240 var i,j,k,s;
241
242 if (mr_x1.length!=x.length) {
243 mr_x1=dup(x);
244 mr_r=dup(x);
245 mr_a=dup(x);
246 }
247
248 copyInt_(mr_a,b);
249 copy_(mr_r,x);
250 copy_(mr_x1,x);
251
252 addInt_(mr_r,-1);
253 addInt_(mr_x1,-1);
254
255 //s=the highest power of two that divides mr_r
256 k=0;
257 for (i=0;i<mr_r.length;i++)
258 for (j=1;j<mask;j<<=1)
259 if (x[i] & j) {
260 s=(k<mr_r.length+bpe ? k : 0);
261 i=mr_r.length;
262 j=mask;
263 } else
264 k++;
265
266 if (s)
267 rightShift_(mr_r,s);
268
269 powMod_(mr_a,mr_r,x);
270
271 if (!equalsInt(mr_a,1) && !equals(mr_a,mr_x1)) {
272 j=1;
273 while (j<=s-1 && !equals(mr_a,mr_x1)) {
274 squareMod_(mr_a,x);
275 if (equalsInt(mr_a,1)) {
276 return 0;
277 }
278 j++;
279 }
280 if (!equals(mr_a,mr_x1)) {
281 return 0;
282 }
283 }
284 return 1;
285}
286
287//returns how many bits long the bigInt is, not counting leading zeros.
288function bitSize(x) {
289 var j,z,w;
290 for (j=x.length-1; (x[j]==0) && (j>0); j--);
291 for (z=0,w=x[j]; w; (w>>=1),z++);
292 z+=bpe*j;
293 return z;
294}
295
296//return a copy of x with at least n elements, adding leading zeros if needed
297function expand(x,n) {
298 var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0);
299 copy_(ans,x);
300 return ans;
301}
302
303//return a k-bit true random prime using Maurer's algorithm.
304function randTruePrime(k) {
305 var ans=int2bigInt(0,k,0);
306 randTruePrime_(ans,k);
307 return trim(ans,1);
308}
309
310//return a new bigInt equal to (x mod n) for bigInts x and n.
311function mod(x,n) {
312 var ans=dup(x);
313 mod_(ans,n);
314 return trim(ans,1);
315}
316
317//return (x+n) where x is a bigInt and n is an integer.
318function addInt(x,n) {
319 var ans=expand(x,x.length+1);
320 addInt_(ans,n);
321 return trim(ans,1);
322}
323
324//return x*y for bigInts x and y. This is faster when y<x.
325function mult(x,y) {
326 var ans=expand(x,x.length+y.length);
327 mult_(ans,y);
328 return trim(ans,1);
329}
330
331//return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n.
332function powMod(x,y,n) {
333 var ans=expand(x,n.length);
334 powMod_(ans,trim(y,2),trim(n,2),0); //this should work without the trim, but doesn't
335 return trim(ans,1);
336}
337
338//return (x-y) for bigInts x and y. Negative answers will be 2s complement
339function sub(x,y) {
340 var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
341 sub_(ans,y);
342 return trim(ans,1);
343}
344
345//return (x+y) for bigInts x and y.
346function add(x,y) {
347 var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
348 add_(ans,y);
349 return trim(ans,1);
350}
351
352//return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
353function inverseMod(x,n) {
354 var ans=expand(x,n.length);
355 var s;
356 s=inverseMod_(ans,n);
357 return s ? trim(ans,1) : null;
358}
359
360//return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
361function multMod(x,y,n) {
362 var ans=expand(x,n.length);
363 multMod_(ans,y,n);
364 return trim(ans,1);
365}
366
367//generate a k-bit true random prime using Maurer's algorithm,
368//and put it into ans. The bigInt ans must be large enough to hold it.
369function randTruePrime_(ans,k) {
370 var c,m,pm,dd,j,r,B,divisible,z,zz,recSize;
371
372 if (primes.length==0)
373 primes=findPrimes(30000); //check for divisibility by primes <=30000
374
375 if (pows.length==0) {
376 pows=new Array(512);
377 for (j=0;j<512;j++) {
378 pows[j]=Math.pow(2,j/511.-1.);
379 }
380 }
381
382 //c and m should be tuned for a particular machine and value of k, to maximize speed
383 //this was: c=primes[primes.length-1]/k/k; //check using all the small primes. (c=0.1 in HAC)
384 c=0.1;
385 m=20; //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
386 recLimit=20; /*must be at least 2 (was 29)*/ //stop recursion when k <=recLimit
387
388 if (s_i2.length!=ans.length) {
389 s_i2=dup(ans);
390 s_R =dup(ans);
391 s_n1=dup(ans);
392 s_r2=dup(ans);
393 s_d =dup(ans);
394 s_x1=dup(ans);
395 s_x2=dup(ans);
396 s_b =dup(ans);
397 s_n =dup(ans);
398 s_i =dup(ans);
399 s_rm=dup(ans);
400 s_q =dup(ans);
401 s_a =dup(ans);
402 s_aa=dup(ans);
403 }
404
405 if (k <= recLimit) { //generate small random primes by trial division up to its square root
406 pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k)
407 copyInt_(ans,0);
408 for (dd=1;dd;) {
409 dd=0;
410 ans[0]= 1 | (1<<(k-1)) | Math.floor(Math.random()*(1<<k)); //random, k-bit, odd integer, with msb 1
411 for (j=1;(j<primes.length) && ((primes[j]&pm)==primes[j]);j++) { //trial division by all primes 3...sqrt(2^k)
412 if (0==(ans[0]%primes[j])) {
413 dd=1;
414 break;
415 }
416 }
417 }
418 carry_(ans);
419 return;
420 }
421
422 B=c*k*k; //try small primes up to B (or all the primes[] array if the largest is less than B).
423 if (k>2*m) //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
424 for (r=1; k-k*r<=m; )
425 r=pows[Math.floor(Math.random()*512)]; //r=Math.pow(2,Math.random()-1);
426 else
427 r=.5;
428
429 //simulation suggests the more complex algorithm using r=.333 is only slightly faster.
430
431 recSize=Math.floor(r*k)+1;
432
433 randTruePrime_(s_q,recSize);
434 copyInt_(s_i2,0);
435 s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe)); //s_i2=2^(k-2)
436 divide_(s_i2,s_q,s_i,s_rm); //s_i=floor((2^(k-1))/(2q))
437
438 z=bitSize(s_i);
439
440 for (;;) {
441 for (;;) { //generate z-bit numbers until one falls in the range [0,s_i-1]
442 randBigInt_(s_R,z,0);
443 if (greater(s_i,s_R))
444 break;
445 } //now s_R is in the range [0,s_i-1]
446 addInt_(s_R,1); //now s_R is in the range [1,s_i]
447 add_(s_R,s_i); //now s_R is in the range [s_i+1,2*s_i]
448
449 copy_(s_n,s_q);
450 mult_(s_n,s_R);
451 multInt_(s_n,2);
452 addInt_(s_n,1); //s_n=2*s_R*s_q+1
453
454 copy_(s_r2,s_R);
455 multInt_(s_r2,2); //s_r2=2*s_R
456
457 //check s_n for divisibility by small primes up to B
458 for (divisible=0,j=0; (j<primes.length) && (primes[j]<B); j++)
459 if (modInt(s_n,primes[j])==0) {
460 divisible=1;
461 break;
462 }
463
464 if (!divisible) //if it passes small primes check, then try a single Miller-Rabin base 2
465 if (!millerRabin(s_n,2)) //this line represents 75% of the total runtime for randTruePrime_
466 divisible=1;
467
468 if (!divisible) { //if it passes that test, continue checking s_n
469 addInt_(s_n,-3);
470 for (j=s_n.length-1;(s_n[j]==0) && (j>0); j--); //strip leading zeros
471 for (zz=0,w=s_n[j]; w; (w>>=1),zz++);
472 zz+=bpe*j; //zz=number of bits in s_n, ignoring leading zeros
473 for (;;) { //generate z-bit numbers until one falls in the range [0,s_n-1]
474 randBigInt_(s_a,zz,0);
475 if (greater(s_n,s_a))
476 break;
477 } //now s_a is in the range [0,s_n-1]
478 addInt_(s_n,3); //now s_a is in the range [0,s_n-4]
479 addInt_(s_a,2); //now s_a is in the range [2,s_n-2]
480 copy_(s_b,s_a);
481 copy_(s_n1,s_n);
482 addInt_(s_n1,-1);
483 powMod_(s_b,s_n1,s_n); //s_b=s_a^(s_n-1) modulo s_n
484 addInt_(s_b,-1);
485 if (isZero(s_b)) {
486 copy_(s_b,s_a);
487 powMod_(s_b,s_r2,s_n);
488 addInt_(s_b,-1);
489 copy_(s_aa,s_n);
490 copy_(s_d,s_b);
491 GCD_(s_d,s_n); //if s_b and s_n are relatively prime, then s_n is a prime
492 if (equalsInt(s_d,1)) {
493 copy_(ans,s_aa);
494 return; //if we've made it this far, then s_n is absolutely guaranteed to be prime
495 }
496 }
497 }
498 }
499}
500
501//set b to an n-bit random BigInt. If s=1, then nth bit (most significant bit) is set to 1.
502//array b must be big enough to hold the result. Must have n>=1
503function randBigInt_(b,n,s) {
504 var i,a;
505 for (i=0;i<b.length;i++)
506 b[i]=0;
507 a=Math.floor((n-1)/bpe)+1; //# array elements to hold the BigInt
508 for (i=0;i<a;i++) {
509 b[i]=Math.floor(Math.random()*(1<<(bpe-1)));
510 }
511 b[a-1] &= (2<<((n-1)%bpe))-1;
512 if (s)
513 b[a-1] |= (1<<((n-1)%bpe));
514}
515
516//set x to the greatest common divisor of x and y.
517//x,y are bigInts with the same number of elements. y is destroyed.
518function GCD_(x,y) {
519 var i,xp,yp,A,B,C,D,q,sing;
520 if (T.length!=x.length)
521 T=dup(x);
522
523 sing=1;
524 while (sing) { //while y has nonzero elements other than y[0]
525 sing=0;
526 for (i=1;i<y.length;i++) //check if y has nonzero elements other than 0
527 if (y[i]) {
528 sing=1;
529 break;
530 }
531 if (!sing) break; //quit when y all zero elements except possibly y[0]
532
533 for (i=x.length;!x[i] && i>=0;i--); //find most significant element of x
534 xp=x[i];
535 yp=y[i];
536 A=1; B=0; C=0; D=1;
537 while ((yp+C) && (yp+D)) {
538 q =Math.floor((xp+A)/(yp+C));
539 qp=Math.floor((xp+B)/(yp+D));
540 if (q!=qp)
541 break;
542 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)
543 t= B-q*D; B=D; D=t;
544 t=xp-q*yp; xp=yp; yp=t;
545 }
546 if (B) {
547 copy_(T,x);
548 linComb_(x,y,A,B); //x=A*x+B*y
549 linComb_(y,T,D,C); //y=D*y+C*T
550 } else {
551 mod_(x,y);
552 copy_(T,x);
553 copy_(x,y);
554 copy_(y,T);
555 }
556 }
557 if (y[0]==0)
558 return;
559 t=modInt(x,y[0]);
560 copyInt_(x,y[0]);
561 y[0]=t;
562 while (y[0]) {
563 x[0]%=y[0];
564 t=x[0]; x[0]=y[0]; y[0]=t;
565 }
566}
567
568//do x=x**(-1) mod n, for bigInts x and n.
569//If no inverse exists, it sets x to zero and returns 0, else it returns 1.
570//The x array must be at least as large as the n array.
571function inverseMod_(x,n) {
572 var k=1+2*Math.max(x.length,n.length);
573
574 if(!(x[0]&1) && !(n[0]&1)) { //if both inputs are even, then inverse doesn't exist
575 copyInt_(x,0);
576 return 0;
577 }
578
579 if (eg_u.length!=k) {
580 eg_u=new Array(k);
581 eg_v=new Array(k);
582 eg_A=new Array(k);
583 eg_B=new Array(k);
584 eg_C=new Array(k);
585 eg_D=new Array(k);
586 }
587
588 copy_(eg_u,x);
589 copy_(eg_v,n);
590 copyInt_(eg_A,1);
591 copyInt_(eg_B,0);
592 copyInt_(eg_C,0);
593 copyInt_(eg_D,1);
594 for (;;) {
595 while(!(eg_u[0]&1)) { //while eg_u is even
596 halve_(eg_u);
597 if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2
598 halve_(eg_A);
599 halve_(eg_B);
600 } else {
601 add_(eg_A,n); halve_(eg_A);
602 sub_(eg_B,x); halve_(eg_B);
603 }
604 }
605
606 while (!(eg_v[0]&1)) { //while eg_v is even
607 halve_(eg_v);
608 if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2
609 halve_(eg_C);
610 halve_(eg_D);
611 } else {
612 add_(eg_C,n); halve_(eg_C);
613 sub_(eg_D,x); halve_(eg_D);
614 }
615 }
616
617 if (!greater(eg_v,eg_u)) { //eg_v <= eg_u
618 sub_(eg_u,eg_v);
619 sub_(eg_A,eg_C);
620 sub_(eg_B,eg_D);
621 } else { //eg_v > eg_u
622 sub_(eg_v,eg_u);
623 sub_(eg_C,eg_A);
624 sub_(eg_D,eg_B);
625 }
626
627 if (equalsInt(eg_u,0)) {
628 if (negative(eg_C)) //make sure answer is nonnegative
629 add_(eg_C,n);
630 copy_(x,eg_C);
631
632 if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse
633 copyInt_(x,0);
634 return 0;
635 }
636 return 1;
637 }
638 }
639}
640
641//return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
642function inverseModInt_(x,n) {
643 var a=1,b=0,t;
644 for (;;) {
645 if (x==1) return a;
646 if (x==0) return 0;
647 b-=a*Math.floor(n/x);
648 n%=x;
649
650 if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to +=
651 if (n==0) return 0;
652 a-=b*Math.floor(x/n);
653 x%=n;
654 }
655}
656
657//Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that:
658// v = GCD_(x,y) = a*x-b*y
659//The bigInts v, a, b, must have exactly as many elements as the larger of x and y.
660function eGCD_(x,y,v,a,b) {
661 var g=0;
662 var k=Math.max(x.length,y.length);
663 if (eg_u.length!=k) {
664 eg_u=new Array(k);
665 eg_A=new Array(k);
666 eg_B=new Array(k);
667 eg_C=new Array(k);
668 eg_D=new Array(k);
669 }
670 while(!(x[0]&1) && !(y[0]&1)) { //while x and y both even
671 halve_(x);
672 halve_(y);
673 g++;
674 }
675 copy_(eg_u,x);
676 copy_(v,y);
677 copyInt_(eg_A,1);
678 copyInt_(eg_B,0);
679 copyInt_(eg_C,0);
680 copyInt_(eg_D,1);
681 for (;;) {
682 while(!(eg_u[0]&1)) { //while u is even
683 halve_(eg_u);
684 if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2
685 halve_(eg_A);
686 halve_(eg_B);
687 } else {
688 add_(eg_A,y); halve_(eg_A);
689 sub_(eg_B,x); halve_(eg_B);
690 }
691 }
692
693 while (!(v[0]&1)) { //while v is even
694 halve_(v);
695 if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2
696 halve_(eg_C);
697 halve_(eg_D);
698 } else {
699 add_(eg_C,y); halve_(eg_C);
700 sub_(eg_D,x); halve_(eg_D);
701 }
702 }
703
704 if (!greater(v,eg_u)) { //v<=u
705 sub_(eg_u,v);
706 sub_(eg_A,eg_C);
707 sub_(eg_B,eg_D);
708 } else { //v>u
709 sub_(v,eg_u);
710 sub_(eg_C,eg_A);
711 sub_(eg_D,eg_B);
712 }
713 if (equalsInt(eg_u,0)) {
714 if (negative(eg_C)) { //make sure a (C)is nonnegative
715 add_(eg_C,y);
716 sub_(eg_D,x);
717 }
718 multInt_(eg_D,-1); ///make sure b (D) is nonnegative
719 copy_(a,eg_C);
720 copy_(b,eg_D);
721 leftShift_(v,g);
722 return;
723 }
724 }
725}
726
727
728//is bigInt x negative?
729function negative(x) {
730 return ((x[x.length-1]>>(bpe-1))&1);
731}
732
733
734//is (x << (shift*bpe)) > y?
735//x and y are nonnegative bigInts
736//shift is a nonnegative integer
737function greaterShift(x,y,shift) {
738 var kx=x.length, ky=y.length;
739 k=((kx+shift)<ky) ? (kx+shift) : ky;
740 for (i=ky-1-shift; i<kx && i>=0; i++)
741 if (x[i]>0)
742 return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger
743 for (i=kx-1+shift; i<ky; i++)
744 if (y[i]>0)
745 return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger
746 for (i=k-1; i>=shift; i--)
747 if (x[i-shift]>y[i]) return 1;
748 else if (x[i-shift]<y[i]) return 0;
749 return 0;
750}
751
752//is x > y? (x and y both nonnegative)
753function greater(x,y) {
754 var i;
755 var k=(x.length<y.length) ? x.length : y.length;
756
757 for (i=x.length;i<y.length;i++)
758 if (y[i])
759 return 0; //y has more digits
760
761 for (i=y.length;i<x.length;i++)
762 if (x[i])
763 return 1; //x has more digits
764
765 for (i=k-1;i>=0;i--)
766 if (x[i]>y[i])
767 return 1;
768 else if (x[i]<y[i])
769 return 0;
770 return 0;
771}
772
773//divide_ x by y giving quotient q and remainder r. (q=floor(x/y), r=x mod y). All 4 are bigints.
774//x must have at least one leading zero element.
775//y must be nonzero.
776//q and r must be arrays that are exactly the same length as x.
777//the x array must have at least as many elements as y.
778function divide_(x,y,q,r) {
779 var kx, ky;
780 var i,j,y1,y2,c,a,b;
781 copy_(r,x);
782 for (ky=y.length;y[ky-1]==0;ky--); //kx,ky is number of elements in x,y, not including leading zeros
783 for (kx=r.length;r[kx-1]==0 && kx>ky;kx--);
784
785 //normalize: ensure the most significant element of y has its highest bit set
786 b=y[ky-1];
787 for (a=0; b; a++)
788 b>>=1;
789 a=bpe-a; //a is how many bits to shift so that the high order bit of y is leftmost in its array element
790 leftShift_(y,a); //multiply both by 1<<a now, then divide_ both by that at the end
791 leftShift_(r,a);
792
793 copyInt_(q,0); // q=0
794 while (!greaterShift(y,r,kx-ky)) { // while (leftShift_(y,kx-ky) <= r) {
795 subShift_(r,y,kx-ky); // r=r-leftShift_(y,kx-ky)
796 q[kx-ky]++; // q[kx-ky]++;
797 } // }
798
799 for (i=kx-1; i>=ky; i--) {
800 if (r[i]==y[ky-1])
801 q[i-ky]=mask;
802 else
803 q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]);
804
805 //The following for(;;) loop is equivalent to the commented while loop,
806 //except that the uncommented version avoids overflow.
807 //The commented loop comes from HAC, which assumes r[-1]==y[-1]==0
808 // while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2])
809 // q[i-ky]--;
810 for (;;) {
811 y2=(ky>1 ? y[ky-2] : 0)*q[i-ky];
812 c=y2>>bpe;
813 y2=y2 & mask;
814 y1=c+q[i-ky]*y[ky-1];
815 c=y1>>bpe;
816 y1=y1 & mask;
817
818 if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i])
819 q[i-ky]--;
820 else
821 break;
822 }
823
824 linCombShift_(r,y,-q[i-ky],i-ky); //r=r-q[i-ky]*leftShift_(y,i-ky)
825 if (negative(r)) {
826 addShift_(r,y,i-ky); //r=r+leftShift_(y,i-ky)
827 q[i-ky]--;
828 }
829 }
830
831 rightShift_(y,a); //undo the normalization step
832 rightShift_(r,a); //undo the normalization step
833}
834
835//do carries and borrows so each element of the bigInt x fits in bpe bits.
836function carry_(x) {
837 var i,k,c,b;
838 k=x.length;
839 c=0;
840 for (i=0;i<k;i++) {
841 c+=x[i];
842 b=0;
843 if (c<0) {
844 b=-(c>>bpe);
845 c+=b*radix;
846 }
847 x[i]=c & mask;
848 c=(c>>bpe)-b;
849 }
850}
851
852//return x mod n for bigInt x and integer n.
853function modInt(x,n) {
854 var i,c=0;
855 for (i=x.length-1; i>=0; i--)
856 c=(c*radix+x[i])%n;
857 return c;
858}
859
860//convert the integer t into a bigInt with at least the given number of bits.
861//the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word)
862//Pad the array with leading zeros so that it has at least minSize elements.
863//There will always be at least one leading 0 element.
864function int2bigInt(t,bits,minSize) {
865 var i,k;
866 k=Math.ceil(bits/bpe)+1;
867 k=minSize>k ? minSize : k;
868 buff=new Array(k);
869 copyInt_(buff,t);
870 return buff;
871}
872
873//return the bigInt given a string representation in a given base.
874//Pad the array with leading zeros so that it has at least minSize elements.
875//If base=-1, then it reads in a space-separated list of array elements in decimal.
876//The array will always have at least one leading zero, unless base=-1.
877function str2bigInt(s,base,minSize) {
878 var d, i, j, x, y, kk;
879 var k=s.length;
880 if (base==-1) { //comma-separated list of array elements in decimal
881 x=new Array(0);
882 for (;;) {
883 y=new Array(x.length+1);
884 for (i=0;i<x.length;i++)
885 y[i+1]=x[i];
886 y[0]=parseInt(s,10);
887 x=y;
888 d=s.indexOf(',',0);
889 if (d<1)
890 break;
891 s=s.substring(d+1);
892 if (s.length==0)
893 break;
894 }
895 if (x.length<minSize) {
896 y=new Array(minSize);
897 copy_(y,x);
898 return y;
899 }
900 return x;
901 }
902
903 x=int2bigInt(0,base*k,0);
904 for (i=0;i<k;i++) {
905 d=digitsStr.indexOf(s.substring(i,i+1),0);
906 if (base<=36 && d>=36) //convert lowercase to uppercase if base<=36
907 d-=26;
908 if (d<base && d>=0) { //ignore illegal characters
909 multInt_(x,base);
910 addInt_(x,d);
911 }
912 }
913
914 for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros
915 k=minSize>k+1 ? minSize : k+1;
916 y=new Array(k);
917 kk=k<x.length ? k : x.length;
918 for (i=0;i<kk;i++)
919 y[i]=x[i];
920 for (;i<k;i++)
921 y[i]=0;
922 return y;
923}
924
925//is bigint x equal to integer y?
926//y must have less than bpe bits
927function equalsInt(x,y) {
928 var i;
929 if (x[0]!=y)
930 return 0;
931 for (i=1;i<x.length;i++)
932 if (x[i])
933 return 0;
934 return 1;
935}
936
937//are bigints x and y equal?
938//this works even if x and y are different lengths and have arbitrarily many leading zeros
939function equals(x,y) {
940 var i;
941 var k=x.length<y.length ? x.length : y.length;
942 for (i=0;i<k;i++)
943 if (x[i]!=y[i])
944 return 0;
945 if (x.length>y.length) {
946 for (;i<x.length;i++)
947 if (x[i])
948 return 0;
949 } else {
950 for (;i<y.length;i++)
951 if (y[i])
952 return 0;
953 }
954 return 1;
955}
956
957//is the bigInt x equal to zero?
958function isZero(x) {
959 var i;
960 for (i=0;i<x.length;i++)
961 if (x[i])
962 return 0;
963 return 1;
964}
965
966//convert a bigInt into a string in a given base, from base 2 up to base 95.
967//Base -1 prints the contents of the array representing the number.
968function bigInt2str(x,base) {
969 var i,t,s="";
970
971 if (s6.length!=x.length)
972 s6=dup(x);
973 else
974 copy_(s6,x);
975
976 if (base==-1) { //return the list of array contents
977 for (i=x.length-1;i>0;i--)
978 s+=x[i]+',';
979 s+=x[0];
980 }
981 else { //return it in the given base
982 while (!isZero(s6)) {
983 t=divInt_(s6,base); //t=s6 % base; s6=floor(s6/base);
984 s=digitsStr.substring(t,t+1)+s;
985 }
986 }
987 if (s.length==0)
988 s="0";
989 return s;
990}
991
992//returns a duplicate of bigInt x
993function dup(x) {
994 var i;
995 buff=new Array(x.length);
996 copy_(buff,x);
997 return buff;
998}
999
1000//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).
1001function copy_(x,y) {
1002 var i;
1003 var k=x.length<y.length ? x.length : y.length;
1004 for (i=0;i<k;i++)
1005 x[i]=y[i];
1006 for (i=k;i<x.length;i++)
1007 x[i]=0;
1008}
1009
1010//do x=y on bigInt x and integer y.
1011function copyInt_(x,n) {
1012 var i,c;
1013 for (c=n,i=0;i<x.length;i++) {
1014 x[i]=c & mask;
1015 c>>=bpe;
1016 }
1017}
1018
1019//do x=x+n where x is a bigInt and n is an integer.
1020//x must be large enough to hold the result.
1021function addInt_(x,n) {
1022 var i,k,c,b;
1023 x[0]+=n;
1024 k=x.length;
1025 c=0;
1026 for (i=0;i<k;i++) {
1027 c+=x[i];
1028 b=0;
1029 if (c<0) {
1030 b=-(c>>bpe);
1031 c+=b*radix;
1032 }
1033 x[i]=c & mask;
1034 c=(c>>bpe)-b;
1035 if (!c) return; //stop carrying as soon as the carry_ is zero
1036 }
1037}
1038
1039//right shift bigInt x by n bits. 0 <= n < bpe.
1040function rightShift_(x,n) {
1041 var i;
1042 var k=Math.floor(n/bpe);
1043 if (k) {
1044 for (i=0;i<x.length-k;i++) //right shift x by k elements
1045 x[i]=x[i+k];
1046 for (;i<x.length;i++)
1047 x[i]=0;
1048 n%=bpe;
1049 }
1050 for (i=0;i<x.length-1;i++) {
1051 x[i]=mask & ((x[i+1]<<(bpe-n)) | (x[i]>>n));
1052 }
1053 x[i]>>=n;
1054}
1055
1056//do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
1057function halve_(x) {
1058 var i;
1059 for (i=0;i<x.length-1;i++) {
1060 x[i]=mask & ((x[i+1]<<(bpe-1)) | (x[i]>>1));
1061 }
1062 x[i]=(x[i]>>1) | (x[i] & (radix>>1)); //most significant bit stays the same
1063}
1064
1065//left shift bigInt x by n bits.
1066function leftShift_(x,n) {
1067 var i;
1068 var k=Math.floor(n/bpe);
1069 if (k) {
1070 for (i=x.length; i>=k; i--) //left shift x by k elements
1071 x[i]=x[i-k];
1072 for (;i>=0;i--)
1073 x[i]=0;
1074 n%=bpe;
1075 }
1076 if (!n)
1077 return;
1078 for (i=x.length-1;i>0;i--) {
1079 x[i]=mask & ((x[i]<<n) | (x[i-1]>>(bpe-n)));
1080 }
1081 x[i]=mask & (x[i]<<n);
1082}
1083
1084//do x=x*n where x is a bigInt and n is an integer.
1085//x must be large enough to hold the result.
1086function multInt_(x,n) {
1087 var i,k,c,b;
1088 if (!n)
1089 return;
1090 k=x.length;
1091 c=0;
1092 for (i=0;i<k;i++) {
1093 c+=x[i]*n;
1094 b=0;
1095 if (c<0) {
1096 b=-(c>>bpe);
1097 c+=b*radix;
1098 }
1099 x[i]=c & mask;
1100 c=(c>>bpe)-b;
1101 }
1102}
1103
1104//do x=floor(x/n) for bigInt x and integer n, and return the remainder
1105function divInt_(x,n) {
1106 var i,r=0,s;
1107 for (i=x.length-1;i>=0;i--) {
1108 s=r*radix+x[i];
1109 x[i]=Math.floor(s/n);
1110 r=s%n;
1111 }
1112 return r;
1113}
1114
1115//do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b.
1116//x must be large enough to hold the answer.
1117function linComb_(x,y,a,b) {
1118 var i,c,k,kk;
1119 k=x.length<y.length ? x.length : y.length;
1120 kk=x.length;
1121 for (c=0,i=0;i<k;i++) {
1122 c+=a*x[i]+b*y[i];
1123 x[i]=c & mask;
1124 c>>=bpe;
1125 }
1126 for (i=k;i<kk;i++) {
1127 c+=a*x[i];
1128 x[i]=c & mask;
1129 c>>=bpe;
1130 }
1131}
1132
1133//do the linear combination x=a*x+b*(y<<(ys*bpe)) for bigInts x and y, and integers a, b and ys.
1134//x must be large enough to hold the answer.
1135function linCombShift_(x,y,b,ys) {
1136 var i,c,k,kk;
1137 k=x.length<ys+y.length ? x.length : ys+y.length;
1138 kk=x.length;
1139 for (c=0,i=ys;i<k;i++) {
1140 c+=x[i]+b*y[i-ys];
1141 x[i]=c & mask;
1142 c>>=bpe;
1143 }
1144 for (i=k;c && i<kk;i++) {
1145 c+=x[i];
1146 x[i]=c & mask;
1147 c>>=bpe;
1148 }
1149}
1150
1151//do x=x+(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
1152//x must be large enough to hold the answer.
1153function addShift_(x,y,ys) {
1154 var i,c,k,kk;
1155 k=x.length<ys+y.length ? x.length : ys+y.length;
1156 kk=x.length;
1157 for (c=0,i=ys;i<k;i++) {
1158 c+=x[i]+y[i-ys];
1159 x[i]=c & mask;
1160 c>>=bpe;
1161 }
1162 for (i=k;c && i<kk;i++) {
1163 c+=x[i];
1164 x[i]=c & mask;
1165 c>>=bpe;
1166 }
1167}
1168
1169//do x=x-(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
1170//x must be large enough to hold the answer.
1171function subShift_(x,y,ys) {
1172 var i,c,k,kk;
1173 k=x.length<ys+y.length ? x.length : ys+y.length;
1174 kk=x.length;
1175 for (c=0,i=ys;i<k;i++) {
1176 c+=x[i]-y[i-ys];
1177 x[i]=c & mask;
1178 c>>=bpe;
1179 }
1180 for (i=k;c && i<kk;i++) {
1181 c+=x[i];
1182 x[i]=c & mask;
1183 c>>=bpe;
1184 }
1185}
1186
1187//do x=x-y for bigInts x and y.
1188//x must be large enough to hold the answer.
1189//negative answers will be 2s complement
1190function sub_(x,y) {
1191 var i,c,k,kk;
1192 k=x.length<y.length ? x.length : y.length;
1193 for (c=0,i=0;i<k;i++) {
1194 c+=x[i]-y[i];
1195 x[i]=c & mask;
1196 c>>=bpe;
1197 }
1198 for (i=k;c && i<x.length;i++) {
1199 c+=x[i];
1200 x[i]=c & mask;
1201 c>>=bpe;
1202 }
1203}
1204
1205//do x=x+y for bigInts x and y.
1206//x must be large enough to hold the answer.
1207function add_(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. This is faster when y<x.
1223function mult_(x,y) {
1224 var i;
1225 if (ss.length!=2*x.length)
1226 ss=new Array(2*x.length);
1227 copyInt_(ss,0);
1228 for (i=0;i<y.length;i++)
1229 if (y[i])
1230 linCombShift_(ss,x,y[i],i); //ss=1*ss+y[i]*(x<<(i*bpe))
1231 copy_(x,ss);
1232}
1233
1234//do x=x mod n for bigInts x and n.
1235function mod_(x,n) {
1236 if (s4.length!=x.length)
1237 s4=dup(x);
1238 else
1239 copy_(s4,x);
1240 if (s5.length!=x.length)
1241 s5=dup(x);
1242 divide_(s4,n,s5,x); //x = remainder of s4 / n
1243}
1244
1245//do x=x*y mod n for bigInts x,y,n.
1246//for greater speed, let y<x.
1247function multMod_(x,y,n) {
1248 var i;
1249 if (s0.length!=2*x.length)
1250 s0=new Array(2*x.length);
1251 copyInt_(s0,0);
1252 for (i=0;i<y.length;i++)
1253 if (y[i])
1254 linCombShift_(s0,x,y[i],i); //s0=1*s0+y[i]*(x<<(i*bpe))
1255 mod_(s0,n);
1256 copy_(x,s0);
1257}
1258
1259//do x=x*x mod n for bigInts x,n.
1260function squareMod_(x,n) {
1261 var i,j,d,c,kx,kn,k;
1262 for (kx=x.length; kx>0 && !x[kx-1]; kx--); //ignore leading zeros in x
1263 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
1264 if (s0.length!=k)
1265 s0=new Array(k);
1266 copyInt_(s0,0);
1267 for (i=0;i<kx;i++) {
1268 c=s0[2*i]+x[i]*x[i];
1269 s0[2*i]=c & mask;
1270 c>>=bpe;
1271 for (j=i+1;j<kx;j++) {
1272 c=s0[i+j]+2*x[i]*x[j]+c;
1273 s0[i+j]=(c & mask);
1274 c>>=bpe;
1275 }
1276 s0[i+kx]=c;
1277 }
1278 mod_(s0,n);
1279 copy_(x,s0);
1280}
1281
1282//return x with exactly k leading zero elements
1283function trim(x,k) {
1284 var i,y;
1285 for (i=x.length; i>0 && !x[i-1]; i--);
1286 y=new Array(i+k);
1287 copy_(y,x);
1288 return y;
1289}
1290
1291//do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation. 0**0=1.
1292//this is faster when n is odd. x usually needs to have as many elements as n.
1293function powMod_(x,y,n) {
1294 var k1,k2,kn,np;
1295 if(s7.length!=n.length)
1296 s7=dup(n);
1297
1298 //for even modulus, use a simple square-and-multiply algorithm,
1299 //rather than using the more complex Montgomery algorithm.
1300 if ((n[0]&1)==0) {
1301 copy_(s7,x);
1302 copyInt_(x,1);
1303 while(!equalsInt(y,0)) {
1304 if (y[0]&1)
1305 multMod_(x,s7,n);
1306 divInt_(y,2);
1307 squareMod_(s7,n);
1308 }
1309 return;
1310 }
1311
1312 //calculate np from n for the Montgomery multiplications
1313 copyInt_(s7,0);
1314 for (kn=n.length;kn>0 && !n[kn-1];kn--);
1315 np=radix-inverseModInt_(modInt(n,radix),radix);
1316 s7[kn]=1;
1317 multMod_(x ,s7,n); // x = x * 2**(kn*bp) mod n
1318
1319 if (s3.length!=x.length)
1320 s3=dup(x);
1321 else
1322 copy_(s3,x);
1323
1324 for (k1=y.length-1;k1>0 & !y[k1]; k1--); //k1=first nonzero element of y
1325 if (y[k1]==0) { //anything to the 0th power is 1
1326 copyInt_(x,1);
1327 return;
1328 }
1329 for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1); //k2=position of first 1 bit in y[k1]
1330 for (;;) {
1331 if (!(k2>>=1)) { //look at next bit of y
1332 k1--;
1333 if (k1<0) {
1334 mont_(x,one,n,np);
1335 return;
1336 }
1337 k2=1<<(bpe-1);
1338 }
1339 mont_(x,x,n,np);
1340
1341 if (k2 & y[k1]) //if next bit is a 1
1342 mont_(x,s3,n,np);
1343 }
1344}
1345
1346//do x=x*y*Ri mod n for bigInts x,y,n,
1347// where Ri = 2**(-kn*bpe) mod n, and kn is the
1348// number of elements in the n array, not
1349// counting leading zeros.
1350//x must be large enough to hold the answer.
1351//It's OK if x and y are the same variable.
1352//must have:
1353// x,y < n
1354// n is odd
1355// np = -(n^(-1)) mod radix
1356function mont_(x,y,n,np) {
1357 var i,j,c,ui,t;
1358 var kn=n.length;
1359 var ky=y.length;
1360
1361 if (sa.length!=kn)
1362 sa=new Array(kn);
1363
1364 for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n
1365 //this function sometimes gives wrong answers when the next line is uncommented
1366 //for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y
1367
1368 copyInt_(sa,0);
1369
1370 //the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large keys
1371 for (i=0; i<kn; i++) {
1372 t=sa[0]+x[i]*y[0];
1373 ui=((t & mask) * np) & mask; //the inner "& mask" is needed on Macintosh MSIE, but not windows MSIE
1374 c=(t+ui*n[0]) >> bpe;
1375 t=x[i];
1376
1377 //do sa=(sa+x[i]*y+ui*n)/b where b=2**bpe
1378 for (j=1;j<ky;j++) {
1379 c+=sa[j]+t*y[j]+ui*n[j];
1380 sa[j-1]=c & mask;
1381 c>>=bpe;
1382 }
1383 for (;j<kn;j++) {
1384 c+=sa[j]+ui*n[j];
1385 sa[j-1]=c & mask;
1386 c>>=bpe;
1387 }
1388 sa[j-1]=c & mask;
1389 }
1390
1391 if (!greater(n,sa))
1392 sub_(sa,n);
1393 copy_(x,sa);
1394}
1395
1396
1397
1398
1399//#############################################################################
1400//#############################################################################
1401//#############################################################################
1402//#############################################################################
1403//#############################################################################
1404//#############################################################################
1405//#############################################################################
1406
1407
1408
1409
1410
1411//#############################################################################
1412
1413Clipperz.Crypto.BigInt = function (aValue, aBase) {
1414 varbase;
1415 varvalue;
1416
1417 if (typeof(aValue) == 'object') {
1418 this._internalValue = aValue;
1419 } else {
1420 if (typeof(aValue) == 'undefined') {
1421 value = "0";
1422 } else {
1423 value = aValue + "";
1424 }
1425
1426 if (typeof(aBase) == 'undefined') {
1427 base = 10;
1428 } else {
1429 base = aBase;
1430 }
1431
1432 this._internalValue = str2bigInt(value, base, 1, 1);
1433 }
1434
1435 return this;
1436}
1437
1438//=============================================================================
1439
1440MochiKit.Base.update(Clipperz.Crypto.BigInt.prototype, {
1441
1442 'clone': function() {
1443 return new Clipperz.Crypto.BigInt(this.internalValue());
1444 },
1445
1446 //-------------------------------------------------------------------------
1447
1448 'internalValue': function () {
1449 return this._internalValue;
1450 },
1451
1452 //-------------------------------------------------------------------------
1453
1454 'isBigInt': true,
1455
1456 //-------------------------------------------------------------------------
1457
1458 'toString': function(aBase) {
1459 return this.asString(aBase);
1460 },
1461
1462 //-------------------------------------------------------------------------
1463
1464 'asString': function (aBase, minimumLength) {
1465 varresult;
1466 varbase;
1467
1468 if (typeof(aBase) == 'undefined') {
1469 base = 10;
1470 } else {
1471 base = aBase;
1472 }
1473
1474 result = bigInt2str(this.internalValue(), base).toLowerCase();
1475
1476 if ((typeof(minimumLength) != 'undefined') && (result.length < minimumLength)) {
1477 var i, c;
1478 //MochiKit.Logging.logDebug(">>> FIXING BigInt.asString length issue")
1479 c = (minimumLength - result.length);
1480 for (i=0; i<c; i++) {
1481 result = '0' + result;
1482 }
1483 }
1484
1485 return result;
1486 },
1487
1488 //-------------------------------------------------------------------------
1489
1490 'asByteArray': function() {
1491 return new Clipperz.ByteArray("0x" + this.asString(16), 16);
1492 },
1493
1494 //-------------------------------------------------------------------------
1495
1496 'equals': function (aValue) {
1497 var result;
1498
1499 if (aValue.isBigInt) {
1500 result = equals(this.internalValue(), aValue.internalValue());
1501 } else if (typeof(aValue) == "number") {
1502 result = equalsInt(this.internalValue(), aValue);
1503 } else {
1504 throw Clipperz.Crypt.BigInt.exception.UnknownType;
1505 }
1506
1507 return result;
1508 },
1509
1510 //-------------------------------------------------------------------------
1511
1512 'compare': function(aValue) {
1513/*
1514 var result;
1515 var thisAsString;
1516 var aValueAsString;
1517
1518 thisAsString = this.asString(10);
1519 aValueAsString = aValue.asString(10);
1520
1521 result = MochiKit.Base.compare(thisAsString.length, aValueAsString.length);
1522 if (result == 0) {
1523 result = MochiKit.Base.compare(thisAsString, aValueAsString);
1524 }
1525
1526 return result;
1527*/
1528 var result;
1529
1530 if (equals(this.internalValue(), aValue.internalValue())) {
1531 result = 0;
1532 } else if (greater(this.internalValue(), aValue.internalValue())) {
1533 result = 1;
1534 } else {
1535 result = -1;
1536 }
1537
1538 return result;
1539 },
1540
1541 //-------------------------------------------------------------------------
1542
1543 'add': function (aValue) {
1544 var result;
1545
1546 if (aValue.isBigInt) {
1547 result = add(this.internalValue(), aValue.internalValue());
1548 } else {
1549 result = addInt(this.internalValue(), aValue);
1550 }
1551
1552 return new Clipperz.Crypto.BigInt(result);
1553 },
1554
1555 //-------------------------------------------------------------------------
1556
1557 'subtract': function (aValue) {
1558 var result;
1559 var value;
1560
1561 if (aValue.isBigInt) {
1562 value = aValue;
1563 } else {
1564 value = new Clipperz.Crypto.BigInt(aValue);
1565 }
1566
1567 result = sub(this.internalValue(), value.internalValue());
1568
1569 return new Clipperz.Crypto.BigInt(result);
1570 },
1571
1572 //-------------------------------------------------------------------------
1573
1574 'multiply': function (aValue, aModule) {
1575 var result;
1576 var value;
1577
1578 if (aValue.isBigInt) {
1579 value = aValue;
1580 } else {
1581 value = new Clipperz.Crypto.BigInt(aValue);
1582 }
1583
1584 if (typeof(aModule) == 'undefined') {
1585 result = mult(this.internalValue(), value.internalValue());
1586 } else {
1587 if (greater(this.internalValue(), value.internalValue())) {
1588 result = multMod(this.internalValue(), value.internalValue(), aModule);
1589 } else {
1590 result = multMod(value.internalValue(), this.internalValue(), aModule);
1591 }
1592 }
1593
1594 return new Clipperz.Crypto.BigInt(result);
1595 },
1596
1597 //-------------------------------------------------------------------------
1598
1599 'module': function (aModule) {
1600 varresult;
1601 var module;
1602
1603 if (aModule.isBigInt) {
1604 module = aModule;
1605 } else {
1606 module = new Clipperz.Crypto.BigInt(aModule);
1607 }
1608
1609 result = mod(this.internalValue(), module.internalValue());
1610
1611 return new Clipperz.Crypto.BigInt(result);
1612 },
1613
1614 //-------------------------------------------------------------------------
1615
1616 'powerModule': function(aValue, aModule) {
1617 varresult;
1618 varvalue;
1619 var module;
1620
1621 if (aValue.isBigInt) {
1622 value = aValue;
1623 } else {
1624 value = new Clipperz.Crypto.BigInt(aValue);
1625 }
1626
1627 if (aModule.isBigInt) {
1628 module = aModule;
1629 } else {
1630 module = new Clipperz.Crypto.BigInt(aModule);
1631 }
1632
1633 if (aValue == -1) {
1634 result = inverseMod(this.internalValue(), module.internalValue());
1635 } else {
1636 result = powMod(this.internalValue(), value.internalValue(), module.internalValue());
1637 }
1638
1639 return new Clipperz.Crypto.BigInt(result);
1640 },
1641
1642 //-------------------------------------------------------------------------
1643
1644 'xor': function(aValue) {
1645 var result;
1646 varthisByteArray;
1647 var aValueByteArray;
1648 var xorArray;
1649
1650 thisByteArray = new Clipperz.ByteArray("0x" + this.asString(16), 16);
1651 aValueByteArray = new Clipperz.ByteArray("0x" + aValue.asString(16), 16);
1652 xorArray = thisByteArray.xorMergeWithBlock(aValueByteArray, 'right');
1653 result = new Clipperz.Crypto.BigInt(xorArray.toHexString(), 16);
1654
1655 return result;
1656 },
1657
1658 //-------------------------------------------------------------------------
1659
1660 'shiftLeft': function(aNumberOfBitsToShift) {
1661 var result;
1662 var internalResult;
1663 var wholeByteToShift;
1664 var bitsLeftToShift;
1665
1666 wholeByteToShift = Math.floor(aNumberOfBitsToShift / 8);
1667 bitsLeftToShift = aNumberOfBitsToShift % 8;
1668
1669 if (wholeByteToShift == 0) {
1670 internalResult = this.internalValue();
1671 } else {
1672 var hexValue;
1673 var i,c;
1674
1675 hexValue = this.asString(16);
1676 c = wholeByteToShift;
1677 for (i=0; i<c; i++) {
1678 hexValue += "00";
1679 }
1680 internalResult = str2bigInt(hexValue, 16, 1, 1);
1681 }
1682
1683 if (bitsLeftToShift > 0) {
1684 leftShift_(internalResult, bitsLeftToShift);
1685 }
1686 result = new Clipperz.Crypto.BigInt(internalResult);
1687
1688 return result;
1689 },
1690
1691 //-------------------------------------------------------------------------
1692
1693 'bitSize': function() {
1694 return bitSize(this.internalValue());
1695 },
1696
1697 //-------------------------------------------------------------------------
1698
1699 'isBitSet': function(aBitPosition) {
1700 var result;
1701
1702 if (this.asByteArray().bitAtIndex(aBitPosition) == 0) {
1703 result = false;
1704 } else {
1705 result = true;
1706 };
1707
1708 return result;
1709 },
1710
1711 //-------------------------------------------------------------------------
1712 __syntaxFix__: "syntax fix"
1713
1714});
1715
1716//#############################################################################
1717
1718Clipperz.Crypto.BigInt.randomPrime = function(aBitSize) {
1719 return new Clipperz.Crypto.BigInt(randTruePrime(aBitSize));
1720}
1721
1722//#############################################################################
1723//#############################################################################
1724
1725Clipperz.Crypto.BigInt.ZERO = new Clipperz.Crypto.BigInt(0);
1726
1727//#############################################################################
1728
1729Clipperz.Crypto.BigInt.equals = function(a, b) {
1730 return a.equals(b);
1731}
1732
1733Clipperz.Crypto.BigInt.add = function(a, b) {
1734 return a.add(b);
1735}
1736
1737Clipperz.Crypto.BigInt.subtract = function(a, b) {
1738 return a.subtract(b);
1739}
1740
1741Clipperz.Crypto.BigInt.multiply = function(a, b, module) {
1742 return a.multiply(b, module);
1743}
1744
1745Clipperz.Crypto.BigInt.module = function(a, module) {
1746 return a.module(module);
1747}
1748
1749Clipperz.Crypto.BigInt.powerModule = function(a, b, module) {
1750 return a.powerModule(b, module);
1751}
1752
1753Clipperz.Crypto.BigInt.exception = {
1754 UnknownType: new MochiKit.Base.NamedError("Clipperz.Crypto.BigInt.exception.UnknownType")
1755}
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/BigInt_scoped.js b/frontend/gamma/js/ClipperzCryptoLibrary/BigInt_scoped.js
deleted file mode 100644
index bc60330..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/BigInt_scoped.js
+++ b/dev/null
@@ -1,1644 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
26
27if (typeof(Leemon) == 'undefined') { Leemon = {}; }
28if (typeof(Baird.Crypto) == 'undefined') { Baird.Crypto = {}; }
29if (typeof(Baird.Crypto.BigInt) == 'undefined') { Baird.Crypto.BigInt = {}; }
30
31
32//#############################################################################
33 //Downloaded on March 05, 2007 from http://www.leemon.com/crypto/BigInt.js
34//#############################################################################
35
36////////////////////////////////////////////////////////////////////////////////////////
37// Big Integer Library v. 5.0
38// Created 2000, last modified 2006
39// Leemon Baird
40// www.leemon.com
41//
42// This file is public domain. You can use it for any purpose without restriction.
43// I do not guarantee that it is correct, so use it at your own risk. If you use
44// it for something interesting, I'd appreciate hearing about it. If you find
45// any bugs or make any improvements, I'd appreciate hearing about those too.
46// It would also be nice if my name and address were left in the comments.
47// But none of that is required.
48//
49// This code defines a bigInt library for arbitrary-precision integers.
50// A bigInt is an array of integers storing the value in chunks of bpe bits,
51// little endian (buff[0] is the least significant word).
52// Negative bigInts are stored two's complement.
53// Some functions assume their parameters have at least one leading zero element.
54// Functions with an underscore at the end of the name have unpredictable behavior in case of overflow,
55// so the caller must make sure overflow won't happen.
56// For each function where a parameter is modified, that same
57// variable must not be used as another argument too.
58// So, you cannot square x by doing multMod_(x,x,n).
59// You must use squareMod_(x,n) instead, or do y=dup(x); multMod_(x,y,n).
60//
61// These functions are designed to avoid frequent dynamic memory allocation in the inner loop.
62// For most functions, if it needs a BigInt as a local variable it will actually use
63// a global, and will only allocate to it when it's not the right size. This ensures
64// that when a function is called repeatedly with same-sized parameters, it only allocates
65// memory on the first call.
66//
67// Note that for cryptographic purposes, the calls to Math.random() must
68// be replaced with calls to a better pseudorandom number generator.
69//
70// In the following, "bigInt" means a bigInt with at least one leading zero element,
71// and "integer" means a nonnegative integer less than radix. In some cases, integer
72// can be negative. Negative bigInts are 2s complement.
73//
74// The following functions do not modify their inputs, but dynamically allocate memory every time they are called:
75//
76// function bigInt2str(x,base) //convert a bigInt into a string in a given base, from base 2 up to base 95
77// function dup(x) //returns a copy of bigInt x
78// function findPrimes(n) //return array of all primes less than integer n
79// function int2bigInt(t,n,m) //convert integer t to a bigInt with at least n bits and m array elements
80// function str2bigInt(s,b,n,m) //convert string s in base b to a bigInt with at least n bits and m array elements
81// function trim(x,k) //return a copy of x with exactly k leading zero elements
82//
83// The following functions do not modify their inputs, so there is never a problem with the result being too big:
84//
85// function bitSize(x) //returns how many bits long the bigInt x is, not counting leading zeros
86// function equals(x,y) //is the bigInt x equal to the bigint y?
87// function equalsInt(x,y) //is bigint x equal to integer y?
88// function greater(x,y) //is x>y? (x and y are nonnegative bigInts)
89// function greaterShift(x,y,shift)//is (x <<(shift*bpe)) > y?
90// function isZero(x) //is the bigInt x equal to zero?
91// 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)?
92// function modInt(x,n) //return x mod n for bigInt x and integer n.
93// function negative(x) //is bigInt x negative?
94//
95// The following functions do not modify their inputs, but allocate memory and call functions with underscores
96//
97// function add(x,y) //return (x+y) for bigInts x and y.
98// function addInt(x,n) //return (x+n) where x is a bigInt and n is an integer.
99// function expand(x,n) //return a copy of x with at least n elements, adding leading zeros if needed
100// function inverseMod(x,n) //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
101// function mod(x,n) //return a new bigInt equal to (x mod n) for bigInts x and n.
102// function mult(x,y) //return x*y for bigInts x and y. This is faster when y<x.
103// function multMod(x,y,n) //return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
104// 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.
105// function randTruePrime(k) //return a new, random, k-bit, true prime using Maurer's algorithm.
106// function sub(x,y) //return (x-y) for bigInts x and y. Negative answers will be 2s complement
107//
108// The following functions write a bigInt result to one of the parameters, but
109// the result is never bigger than the original, so there can't be overflow problems:
110//
111// function divInt_(x,n) //do x=floor(x/n) for bigInt x and integer n, and return the remainder
112// function GCD_(x,y) //set x to the greatest common divisor of bigInts x and y, (y is destroyed).
113// function halve_(x) //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
114// function mod_(x,n) //do x=x mod n for bigInts x and n.
115// function rightShift_(x,n) //right shift bigInt x by n bits. 0 <= n < bpe.
116//
117// The following functions write a bigInt result to one of the parameters. The caller is responsible for
118// ensuring it is large enough to hold the result.
119//
120// function addInt_(x,n) //do x=x+n where x is a bigInt and n is an integer
121// function add_(x,y) //do x=x+y for bigInts x and y
122// function addShift_(x,y,ys) //do x=x+(y<<(ys*bpe))
123// function copy_(x,y) //do x=y on bigInts x and y
124// function copyInt_(x,n) //do x=n on bigInt x and integer n
125// function carry_(x) //do carries and borrows so each element of the bigInt x fits in bpe bits.
126// function divide_(x,y,q,r) //divide_ x by y giving quotient q and remainder r
127// 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
128// function inverseMod_(x,n) //do x=x**(-1) mod n, for bigInts x and n. Returns 1 (0) if inverse does (doesn't) exist
129// function inverseModInt_(x,n) //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
130// function leftShift_(x,n) //left shift bigInt x by n bits. n<bpe.
131// function linComb_(x,y,a,b) //do x=a*x+b*y for bigInts x and y and integers a and b
132// function linCombShift_(x,y,b,ys) //do x=x+b*(y<<(ys*bpe)) for bigInts x and y, and integers b and ys
133// function mont_(x,y,n,np) //Montgomery multiplication (see comments where the function is defined)
134// function mult_(x,y) //do x=x*y for bigInts x and y.
135// function multInt_(x,n) //do x=x*n where x is a bigInt and n is an integer.
136// function multMod_(x,y,n) //do x=x*y mod n for bigInts x,y,n.
137// 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.
138// 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.
139// function randTruePrime_(ans,k) //do ans = a random k-bit true random prime (not just probable prime) with 1 in the msb.
140// function squareMod_(x,n) //do x=x*x mod n for bigInts x,n
141// function sub_(x,y) //do x=x-y for bigInts x and y. Negative answers will be 2s complement.
142// function subShift_(x,y,ys) //do x=x-(y<<(ys*bpe)). Negative answers will be 2s complement.
143//
144// The following functions are based on algorithms from the _Handbook of Applied Cryptography_
145// powMod_() = algorithm 14.94, Montgomery exponentiation
146// eGCD_,inverseMod_() = algorithm 14.61, Binary extended GCD_
147// GCD_() = algorothm 14.57, Lehmer's algorithm
148// mont_() = algorithm 14.36, Montgomery multiplication
149// divide_() = algorithm 14.20 Multiple-precision division
150// squareMod_() = algorithm 14.16 Multiple-precision squaring
151// randTruePrime_() = algorithm 4.62, Maurer's algorithm
152// millerRabin() = algorithm 4.24, Miller-Rabin algorithm
153//
154// Profiling shows:
155// randTruePrime_() spends:
156// 10% of its time in calls to powMod_()
157// 85% of its time in calls to millerRabin()
158// millerRabin() spends:
159// 99% of its time in calls to powMod_() (always with a base of 2)
160// powMod_() spends:
161// 94% of its time in calls to mont_() (almost always with x==y)
162//
163// This suggests there are several ways to speed up this library slightly:
164// - convert powMod_ to use a Montgomery form of k-ary window (or maybe a Montgomery form of sliding window)
165// -- this should especially focus on being fast when raising 2 to a power mod n
166// - convert randTruePrime_() to use a minimum r of 1/3 instead of 1/2 with the appropriate change to the test
167// - tune the parameters in randTruePrime_(), including c, m, and recLimit
168// - speed up the single loop in mont_() that takes 95% of the runtime, perhaps by reducing checking
169// within the loop when all the parameters are the same length.
170//
171// There are several ideas that look like they wouldn't help much at all:
172// - replacing trial division in randTruePrime_() with a sieve (that speeds up something taking almost no time anyway)
173// - 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)
174// - speeding up mont_(x,y,n,np) when x==y by doing a non-modular, non-Montgomery square
175// followed by a Montgomery reduction. The intermediate answer will be twice as long as x, so that
176// method would be slower. This is unfortunate because the code currently spends almost all of its time
177// doing mont_(x,x,...), both for randTruePrime_() and powMod_(). A faster method for Montgomery squaring
178// would have a large impact on the speed of randTruePrime_() and powMod_(). HAC has a couple of poorly-worded
179// sentences that seem to imply it's faster to do a non-modular square followed by a single
180// Montgomery reduction, but that's obviously wrong.
181////////////////////////////////////////////////////////////////////////////////////////
182
183//
184 //The whole library has been moved into the Baird.Crypto.BigInt scope by Giulio Cesare Solaroli <giulio.cesare@clipperz.com>
185//
186Baird.Crypto.BigInt.VERSION = "5.0";
187Baird.Crypto.BigInt.NAME = "Baird.Crypto.BigInt";
188
189MochiKit.Base.update(Baird.Crypto.BigInt, {
190 //globals
191 'bpe': 0, //bits stored per array element
192 'mask': 0, //AND this with an array element to chop it down to bpe bits
193 'radix': Baird.Crypto.BigInt.mask + 1,//equals 2^bpe. A single 1 bit to the left of the last bit of mask.
194
195 //the digits for converting to different bases
196 'digitsStr': '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-',
197
198//initialize the global variables
199for (bpe=0; (1<<(bpe+1)) > (1<<bpe); bpe++); //bpe=number of bits in the mantissa on this platform
200bpe>>=1; //bpe=number of bits in one element of the array representing the bigInt
201mask=(1<<bpe)-1; //AND the mask with an integer to get its bpe least significant bits
202radix=mask+1; //2^bpe. a single 1 bit to the left of the first bit of mask
203one=int2bigInt(1,1,1); //constant used in powMod_()
204
205//the following global variables are scratchpad memory to
206//reduce dynamic memory allocation in the inner loop
207t=new Array(0);
208ss=t; //used in mult_()
209s0=t; //used in multMod_(), squareMod_()
210s1=t; //used in powMod_(), multMod_(), squareMod_()
211s2=t; //used in powMod_(), multMod_()
212s3=t; //used in powMod_()
213s4=t; s5=t; //used in mod_()
214s6=t; //used in bigInt2str()
215s7=t; //used in powMod_()
216T=t; //used in GCD_()
217sa=t; //used in mont_()
218mr_x1=t; mr_r=t; mr_a=t; //used in millerRabin()
219eg_v=t; eg_u=t; eg_A=t; eg_B=t; eg_C=t; eg_D=t; //used in eGCD_(), inverseMod_()
220md_q1=t; md_q2=t; md_q3=t; md_r=t; md_r1=t; md_r2=t; md_tt=t; //used in mod_()
221
222primes=t; pows=t; s_i=t; s_i2=t; s_R=t; s_rm=t; s_q=t; s_n1=t;
223 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_()
224
225////////////////////////////////////////////////////////////////////////////////////////
226
227 //return array of all primes less than integer n
228 'findPrimes': function(n) {
229 var i,s,p,ans;
230 s=new Array(n);
231 for (i=0;i<n;i++)
232 s[i]=0;
233 s[0]=2;
234 p=0; //first p elements of s are primes, the rest are a sieve
235 for(;s[p]<n;) { //s[p] is the pth prime
236 for(i=s[p]*s[p]; i<n; i+=s[p]) //mark multiples of s[p]
237 s[i]=1;
238 p++;
239 s[p]=s[p-1]+1;
240 for(; s[p]<n && s[s[p]]; s[p]++); //find next prime (where s[p]==0)
241 }
242 ans=new Array(p);
243 for(i=0;i<p;i++)
244 ans[i]=s[i];
245 return ans;
246 },
247
248 //does a single round of Miller-Rabin base b consider x to be a possible prime?
249 //x is a bigInt, and b is an integer
250 'millerRabin': function(x,b) {
251 var i,j,k,s;
252
253 if (mr_x1.length!=x.length) {
254 mr_x1=dup(x);
255 mr_r=dup(x);
256 mr_a=dup(x);
257 }
258
259 copyInt_(mr_a,b);
260 copy_(mr_r,x);
261 copy_(mr_x1,x);
262
263 addInt_(mr_r,-1);
264 addInt_(mr_x1,-1);
265
266 //s=the highest power of two that divides mr_r
267 k=0;
268 for (i=0;i<mr_r.length;i++)
269 for (j=1;j<mask;j<<=1)
270 if (x[i] & j) {
271 s=(k<mr_r.length+bpe ? k : 0);
272 i=mr_r.length;
273 j=mask;
274 } else
275 k++;
276
277 if (s)
278 rightShift_(mr_r,s);
279
280 powMod_(mr_a,mr_r,x);
281
282 if (!equalsInt(mr_a,1) && !equals(mr_a,mr_x1)) {
283 j=1;
284 while (j<=s-1 && !equals(mr_a,mr_x1)) {
285 squareMod_(mr_a,x);
286 if (equalsInt(mr_a,1)) {
287 return 0;
288 }
289 j++;
290 }
291 if (!equals(mr_a,mr_x1)) {
292 return 0;
293 }
294 }
295
296 return 1;
297 },
298
299 //returns how many bits long the bigInt is, not counting leading zeros.
300 'bitSize': function(x) {
301 var j,z,w;
302 for (j=x.length-1; (x[j]==0) && (j>0); j--);
303 for (z=0,w=x[j]; w; (w>>=1),z++);
304 z+=bpe*j;
305 return z;
306 },
307
308 //return a copy of x with at least n elements, adding leading zeros if needed
309 'expand': function(x,n) {
310 var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0);
311 copy_(ans,x);
312 return ans;
313 },
314
315 //return a k-bit true random prime using Maurer's algorithm.
316 'randTruePrime': function(k) {
317 var ans=int2bigInt(0,k,0);
318 randTruePrime_(ans,k);
319 return trim(ans,1);
320 },
321
322 //return a new bigInt equal to (x mod n) for bigInts x and n.
323 'mod': function(x,n) {
324 var ans=dup(x);
325 mod_(ans,n);
326 return trim(ans,1);
327 },
328
329 //return (x+n) where x is a bigInt and n is an integer.
330 'addInt': function(x,n) {
331 var ans=expand(x,x.length+1);
332 addInt_(ans,n);
333 return trim(ans,1);
334 },
335
336 //return x*y for bigInts x and y. This is faster when y<x.
337 'mult': function(x,y) {
338 var ans=expand(x,x.length+y.length);
339 mult_(ans,y);
340 return trim(ans,1);
341 },
342
343 //return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n.
344 'powMod': function(x,y,n) {
345 var ans=expand(x,n.length);
346 powMod_(ans,trim(y,2),trim(n,2),0); //this should work without the trim, but doesn't
347 return trim(ans,1);
348 },
349
350 //return (x-y) for bigInts x and y. Negative answers will be 2s complement
351 'sub': function(x,y) {
352 var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
353 sub_(ans,y);
354 return trim(ans,1);
355 },
356
357 //return (x+y) for bigInts x and y.
358 'add': function(x,y) {
359 var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
360 add_(ans,y);
361 return trim(ans,1);
362 },
363
364 //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
365 'inverseMod': function(x,n) {
366 var ans=expand(x,n.length);
367 var s;
368 s=inverseMod_(ans,n);
369 return s ? trim(ans,1) : null;
370 },
371
372 //return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
373 'multMod': function(x,y,n) {
374 var ans=expand(x,n.length);
375 multMod_(ans,y,n);
376 return trim(ans,1);
377 },
378
379 //generate a k-bit true random prime using Maurer's algorithm,
380 //and put it into ans. The bigInt ans must be large enough to hold it.
381 'randTruePrime_': function(ans,k) {
382 var c,m,pm,dd,j,r,B,divisible,z,zz,recSize;
383
384 if (primes.length==0)
385 primes=findPrimes(30000); //check for divisibility by primes <=30000
386
387 if (pows.length==0) {
388 pows=new Array(512);
389 for (j=0;j<512;j++) {
390 pows[j]=Math.pow(2,j/511.-1.);
391 }
392 }
393
394 //c and m should be tuned for a particular machine and value of k, to maximize speed
395 //this was: c=primes[primes.length-1]/k/k; //check using all the small primes. (c=0.1 in HAC)
396 c=0.1;
397 m=20; //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
398 recLimit=20; /*must be at least 2 (was 29)*/ //stop recursion when k <=recLimit
399
400 if (s_i2.length!=ans.length) {
401 s_i2=dup(ans);
402 s_R =dup(ans);
403 s_n1=dup(ans);
404 s_r2=dup(ans);
405 s_d =dup(ans);
406 s_x1=dup(ans);
407 s_x2=dup(ans);
408 s_b =dup(ans);
409 s_n =dup(ans);
410 s_i =dup(ans);
411 s_rm=dup(ans);
412 s_q =dup(ans);
413 s_a =dup(ans);
414 s_aa=dup(ans);
415 }
416
417 if (k <= recLimit) { //generate small random primes by trial division up to its square root
418 pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k)
419 copyInt_(ans,0);
420 for (dd=1;dd;) {
421 dd=0;
422 ans[0]= 1 | (1<<(k-1)) | Math.floor(Math.random()*(1<<k)); //random, k-bit, odd integer, with msb 1
423 for (j=1;(j<primes.length) && ((primes[j]&pm)==primes[j]);j++) { //trial division by all primes 3...sqrt(2^k)
424 if (0==(ans[0]%primes[j])) {
425 dd=1;
426 break;
427 }
428 }
429 }
430 carry_(ans);
431 return;
432 }
433
434 B=c*k*k; //try small primes up to B (or all the primes[] array if the largest is less than B).
435 if (k>2*m) //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
436 for (r=1; k-k*r<=m; )
437 r=pows[Math.floor(Math.random()*512)]; //r=Math.pow(2,Math.random()-1);
438 else
439 r=.5;
440
441 //simulation suggests the more complex algorithm using r=.333 is only slightly faster.
442
443 recSize=Math.floor(r*k)+1;
444
445 randTruePrime_(s_q,recSize);
446 copyInt_(s_i2,0);
447 s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe)); //s_i2=2^(k-2)
448 divide_(s_i2,s_q,s_i,s_rm); //s_i=floor((2^(k-1))/(2q))
449
450 z=bitSize(s_i);
451
452 for (;;) {
453 for (;;) { //generate z-bit numbers until one falls in the range [0,s_i-1]
454 randBigInt_(s_R,z,0);
455 if (greater(s_i,s_R))
456 break;
457 } //now s_R is in the range [0,s_i-1]
458 addInt_(s_R,1); //now s_R is in the range [1,s_i]
459 add_(s_R,s_i); //now s_R is in the range [s_i+1,2*s_i]
460
461 copy_(s_n,s_q);
462 mult_(s_n,s_R);
463 multInt_(s_n,2);
464 addInt_(s_n,1); //s_n=2*s_R*s_q+1
465
466 copy_(s_r2,s_R);
467 multInt_(s_r2,2); //s_r2=2*s_R
468
469 //check s_n for divisibility by small primes up to B
470 for (divisible=0,j=0; (j<primes.length) && (primes[j]<B); j++)
471 if (modInt(s_n,primes[j])==0) {
472 divisible=1;
473 break;
474 }
475
476 if (!divisible) //if it passes small primes check, then try a single Miller-Rabin base 2
477 if (!millerRabin(s_n,2)) //this line represents 75% of the total runtime for randTruePrime_
478 divisible=1;
479
480 if (!divisible) { //if it passes that test, continue checking s_n
481 addInt_(s_n,-3);
482 for (j=s_n.length-1;(s_n[j]==0) && (j>0); j--); //strip leading zeros
483 for (zz=0,w=s_n[j]; w; (w>>=1),zz++);
484 zz+=bpe*j; //zz=number of bits in s_n, ignoring leading zeros
485 for (;;) { //generate z-bit numbers until one falls in the range [0,s_n-1]
486 randBigInt_(s_a,zz,0);
487 if (greater(s_n,s_a))
488 break;
489 } //now s_a is in the range [0,s_n-1]
490 addInt_(s_n,3); //now s_a is in the range [0,s_n-4]
491 addInt_(s_a,2); //now s_a is in the range [2,s_n-2]
492 copy_(s_b,s_a);
493 copy_(s_n1,s_n);
494 addInt_(s_n1,-1);
495 powMod_(s_b,s_n1,s_n); //s_b=s_a^(s_n-1) modulo s_n
496 addInt_(s_b,-1);
497 if (isZero(s_b)) {
498 copy_(s_b,s_a);
499 powMod_(s_b,s_r2,s_n);
500 addInt_(s_b,-1);
501 copy_(s_aa,s_n);
502 copy_(s_d,s_b);
503 GCD_(s_d,s_n); //if s_b and s_n are relatively prime, then s_n is a prime
504 if (equalsInt(s_d,1)) {
505 copy_(ans,s_aa);
506 return; //if we've made it this far, then s_n is absolutely guaranteed to be prime
507 }
508 }
509 }
510 }
511 },
512
513 //set b to an n-bit random BigInt. If s=1, then nth bit (most significant bit) is set to 1.
514 //array b must be big enough to hold the result. Must have n>=1
515 'randBigInt_': function(b,n,s) {
516 var i,a;
517 for (i=0;i<b.length;i++)
518 b[i]=0;
519 a=Math.floor((n-1)/bpe)+1; //# array elements to hold the BigInt
520 for (i=0;i<a;i++) {
521 b[i]=Math.floor(Math.random()*(1<<(bpe-1)));
522 }
523 b[a-1] &= (2<<((n-1)%bpe))-1;
524 if (s)
525 b[a-1] |= (1<<((n-1)%bpe));
526 },
527
528 //set x to the greatest common divisor of x and y.
529 //x,y are bigInts with the same number of elements. y is destroyed.
530 'GCD_': function(x,y) {
531 var i,xp,yp,A,B,C,D,q,sing;
532 if (T.length!=x.length)
533 T=dup(x);
534
535 sing=1;
536 while (sing) { //while y has nonzero elements other than y[0]
537 sing=0;
538 for (i=1;i<y.length;i++) //check if y has nonzero elements other than 0
539 if (y[i]) {
540 sing=1;
541 break;
542 }
543 if (!sing) break; //quit when y all zero elements except possibly y[0]
544
545 for (i=x.length;!x[i] && i>=0;i--); //find most significant element of x
546 xp=x[i];
547 yp=y[i];
548 A=1; B=0; C=0; D=1;
549 while ((yp+C) && (yp+D)) {
550 q =Math.floor((xp+A)/(yp+C));
551 qp=Math.floor((xp+B)/(yp+D));
552 if (q!=qp)
553 break;
554 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)
555 t= B-q*D; B=D; D=t;
556 t=xp-q*yp; xp=yp; yp=t;
557 }
558 if (B) {
559 copy_(T,x);
560 linComb_(x,y,A,B); //x=A*x+B*y
561 linComb_(y,T,D,C); //y=D*y+C*T
562 } else {
563 mod_(x,y);
564 copy_(T,x);
565 copy_(x,y);
566 copy_(y,T);
567 }
568 }
569 if (y[0]==0)
570 return;
571 t=modInt(x,y[0]);
572 copyInt_(x,y[0]);
573 y[0]=t;
574 while (y[0]) {
575 x[0]%=y[0];
576 t=x[0]; x[0]=y[0]; y[0]=t;
577 }
578 },
579
580//do x=x**(-1) mod n, for bigInts x and n.
581//If no inverse exists, it sets x to zero and returns 0, else it returns 1.
582//The x array must be at least as large as the n array.
583function inverseMod_(x,n) {
584 var k=1+2*Math.max(x.length,n.length);
585
586 if(!(x[0]&1) && !(n[0]&1)) { //if both inputs are even, then inverse doesn't exist
587 copyInt_(x,0);
588 return 0;
589 }
590
591 if (eg_u.length!=k) {
592 eg_u=new Array(k);
593 eg_v=new Array(k);
594 eg_A=new Array(k);
595 eg_B=new Array(k);
596 eg_C=new Array(k);
597 eg_D=new Array(k);
598 }
599
600 copy_(eg_u,x);
601 copy_(eg_v,n);
602 copyInt_(eg_A,1);
603 copyInt_(eg_B,0);
604 copyInt_(eg_C,0);
605 copyInt_(eg_D,1);
606 for (;;) {
607 while(!(eg_u[0]&1)) { //while eg_u is even
608 halve_(eg_u);
609 if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2
610 halve_(eg_A);
611 halve_(eg_B);
612 } else {
613 add_(eg_A,n); halve_(eg_A);
614 sub_(eg_B,x); halve_(eg_B);
615 }
616 }
617
618 while (!(eg_v[0]&1)) { //while eg_v is even
619 halve_(eg_v);
620 if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2
621 halve_(eg_C);
622 halve_(eg_D);
623 } else {
624 add_(eg_C,n); halve_(eg_C);
625 sub_(eg_D,x); halve_(eg_D);
626 }
627 }
628
629 if (!greater(eg_v,eg_u)) { //eg_v <= eg_u
630 sub_(eg_u,eg_v);
631 sub_(eg_A,eg_C);
632 sub_(eg_B,eg_D);
633 } else { //eg_v > eg_u
634 sub_(eg_v,eg_u);
635 sub_(eg_C,eg_A);
636 sub_(eg_D,eg_B);
637 }
638
639 if (equalsInt(eg_u,0)) {
640 if (negative(eg_C)) //make sure answer is nonnegative
641 add_(eg_C,n);
642 copy_(x,eg_C);
643
644 if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse
645 copyInt_(x,0);
646 return 0;
647 }
648 return 1;
649 }
650 }
651}
652
653//return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
654function inverseModInt_(x,n) {
655 var a=1,b=0,t;
656 for (;;) {
657 if (x==1) return a;
658 if (x==0) return 0;
659 b-=a*Math.floor(n/x);
660 n%=x;
661
662 if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to +=
663 if (n==0) return 0;
664 a-=b*Math.floor(x/n);
665 x%=n;
666 }
667}
668
669//Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that:
670// v = GCD_(x,y) = a*x-b*y
671//The bigInts v, a, b, must have exactly as many elements as the larger of x and y.
672function eGCD_(x,y,v,a,b) {
673 var g=0;
674 var k=Math.max(x.length,y.length);
675 if (eg_u.length!=k) {
676 eg_u=new Array(k);
677 eg_A=new Array(k);
678 eg_B=new Array(k);
679 eg_C=new Array(k);
680 eg_D=new Array(k);
681 }
682 while(!(x[0]&1) && !(y[0]&1)) { //while x and y both even
683 halve_(x);
684 halve_(y);
685 g++;
686 }
687 copy_(eg_u,x);
688 copy_(v,y);
689 copyInt_(eg_A,1);
690 copyInt_(eg_B,0);
691 copyInt_(eg_C,0);
692 copyInt_(eg_D,1);
693 for (;;) {
694 while(!(eg_u[0]&1)) { //while u is even
695 halve_(eg_u);
696 if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2
697 halve_(eg_A);
698 halve_(eg_B);
699 } else {
700 add_(eg_A,y); halve_(eg_A);
701 sub_(eg_B,x); halve_(eg_B);
702 }
703 }
704
705 while (!(v[0]&1)) { //while v is even
706 halve_(v);
707 if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2
708 halve_(eg_C);
709 halve_(eg_D);
710 } else {
711 add_(eg_C,y); halve_(eg_C);
712 sub_(eg_D,x); halve_(eg_D);
713 }
714 }
715
716 if (!greater(v,eg_u)) { //v<=u
717 sub_(eg_u,v);
718 sub_(eg_A,eg_C);
719 sub_(eg_B,eg_D);
720 } else { //v>u
721 sub_(v,eg_u);
722 sub_(eg_C,eg_A);
723 sub_(eg_D,eg_B);
724 }
725 if (equalsInt(eg_u,0)) {
726 if (negative(eg_C)) { //make sure a (C)is nonnegative
727 add_(eg_C,y);
728 sub_(eg_D,x);
729 }
730 multInt_(eg_D,-1); ///make sure b (D) is nonnegative
731 copy_(a,eg_C);
732 copy_(b,eg_D);
733 leftShift_(v,g);
734 return;
735 }
736 }
737}
738
739
740//is bigInt x negative?
741function negative(x) {
742 return ((x[x.length-1]>>(bpe-1))&1);
743}
744
745
746//is (x << (shift*bpe)) > y?
747//x and y are nonnegative bigInts
748//shift is a nonnegative integer
749function greaterShift(x,y,shift) {
750 var kx=x.length, ky=y.length;
751 k=((kx+shift)<ky) ? (kx+shift) : ky;
752 for (i=ky-1-shift; i<kx && i>=0; i++)
753 if (x[i]>0)
754 return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger
755 for (i=kx-1+shift; i<ky; i++)
756 if (y[i]>0)
757 return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger
758 for (i=k-1; i>=shift; i--)
759 if (x[i-shift]>y[i]) return 1;
760 else if (x[i-shift]<y[i]) return 0;
761 return 0;
762}
763
764//is x > y? (x and y both nonnegative)
765function greater(x,y) {
766 var i;
767 var k=(x.length<y.length) ? x.length : y.length;
768
769 for (i=x.length;i<y.length;i++)
770 if (y[i])
771 return 0; //y has more digits
772
773 for (i=y.length;i<x.length;i++)
774 if (x[i])
775 return 1; //x has more digits
776
777 for (i=k-1;i>=0;i--)
778 if (x[i]>y[i])
779 return 1;
780 else if (x[i]<y[i])
781 return 0;
782 return 0;
783}
784
785//divide_ x by y giving quotient q and remainder r. (q=floor(x/y), r=x mod y). All 4 are bigints.
786//x must have at least one leading zero element.
787//y must be nonzero.
788//q and r must be arrays that are exactly the same length as x.
789//the x array must have at least as many elements as y.
790function divide_(x,y,q,r) {
791 var kx, ky;
792 var i,j,y1,y2,c,a,b;
793 copy_(r,x);
794 for (ky=y.length;y[ky-1]==0;ky--); //kx,ky is number of elements in x,y, not including leading zeros
795 for (kx=r.length;r[kx-1]==0 && kx>ky;kx--);
796
797 //normalize: ensure the most significant element of y has its highest bit set
798 b=y[ky-1];
799 for (a=0; b; a++)
800 b>>=1;
801 a=bpe-a; //a is how many bits to shift so that the high order bit of y is leftmost in its array element
802 leftShift_(y,a); //multiply both by 1<<a now, then divide_ both by that at the end
803 leftShift_(r,a);
804
805 copyInt_(q,0); // q=0
806 while (!greaterShift(y,r,kx-ky)) { // while (leftShift_(y,kx-ky) <= r) {
807 subShift_(r,y,kx-ky); // r=r-leftShift_(y,kx-ky)
808 q[kx-ky]++; // q[kx-ky]++;
809 } // }
810
811 for (i=kx-1; i>=ky; i--) {
812 if (r[i]==y[ky-1])
813 q[i-ky]=mask;
814 else
815 q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]);
816
817 //The following for(;;) loop is equivalent to the commented while loop,
818 //except that the uncommented version avoids overflow.
819 //The commented loop comes from HAC, which assumes r[-1]==y[-1]==0
820 // while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2])
821 // q[i-ky]--;
822 for (;;) {
823 y2=(ky>1 ? y[ky-2] : 0)*q[i-ky];
824 c=y2>>bpe;
825 y2=y2 & mask;
826 y1=c+q[i-ky]*y[ky-1];
827 c=y1>>bpe;
828 y1=y1 & mask;
829
830 if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i])
831 q[i-ky]--;
832 else
833 break;
834 }
835
836 linCombShift_(r,y,-q[i-ky],i-ky); //r=r-q[i-ky]*leftShift_(y,i-ky)
837 if (negative(r)) {
838 addShift_(r,y,i-ky); //r=r+leftShift_(y,i-ky)
839 q[i-ky]--;
840 }
841 }
842
843 rightShift_(y,a); //undo the normalization step
844 rightShift_(r,a); //undo the normalization step
845}
846
847//do carries and borrows so each element of the bigInt x fits in bpe bits.
848function carry_(x) {
849 var i,k,c,b;
850 k=x.length;
851 c=0;
852 for (i=0;i<k;i++) {
853 c+=x[i];
854 b=0;
855 if (c<0) {
856 b=-(c>>bpe);
857 c+=b*radix;
858 }
859 x[i]=c & mask;
860 c=(c>>bpe)-b;
861 }
862}
863
864//return x mod n for bigInt x and integer n.
865function modInt(x,n) {
866 var i,c=0;
867 for (i=x.length-1; i>=0; i--)
868 c=(c*radix+x[i])%n;
869 return c;
870}
871
872//convert the integer t into a bigInt with at least the given number of bits.
873//the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word)
874//Pad the array with leading zeros so that it has at least minSize elements.
875//There will always be at least one leading 0 element.
876function int2bigInt(t,bits,minSize) {
877 var i,k;
878 k=Math.ceil(bits/bpe)+1;
879 k=minSize>k ? minSize : k;
880 buff=new Array(k);
881 copyInt_(buff,t);
882 return buff;
883}
884
885//return the bigInt given a string representation in a given base.
886//Pad the array with leading zeros so that it has at least minSize elements.
887//If base=-1, then it reads in a space-separated list of array elements in decimal.
888//The array will always have at least one leading zero, unless base=-1.
889function str2bigInt(s,base,minSize) {
890 var d, i, j, x, y, kk;
891 var k=s.length;
892 if (base==-1) { //comma-separated list of array elements in decimal
893 x=new Array(0);
894 for (;;) {
895 y=new Array(x.length+1);
896 for (i=0;i<x.length;i++)
897 y[i+1]=x[i];
898 y[0]=parseInt(s,10);
899 x=y;
900 d=s.indexOf(',',0);
901 if (d<1)
902 break;
903 s=s.substring(d+1);
904 if (s.length==0)
905 break;
906 }
907 if (x.length<minSize) {
908 y=new Array(minSize);
909 copy_(y,x);
910 return y;
911 }
912 return x;
913 }
914
915 x=int2bigInt(0,base*k,0);
916 for (i=0;i<k;i++) {
917 d=digitsStr.indexOf(s.substring(i,i+1),0);
918 if (base<=36 && d>=36) //convert lowercase to uppercase if base<=36
919 d-=26;
920 if (d<base && d>=0) { //ignore illegal characters
921 multInt_(x,base);
922 addInt_(x,d);
923 }
924 }
925
926 for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros
927 k=minSize>k+1 ? minSize : k+1;
928 y=new Array(k);
929 kk=k<x.length ? k : x.length;
930 for (i=0;i<kk;i++)
931 y[i]=x[i];
932 for (;i<k;i++)
933 y[i]=0;
934 return y;
935}
936
937//is bigint x equal to integer y?
938//y must have less than bpe bits
939function equalsInt(x,y) {
940 var i;
941 if (x[0]!=y)
942 return 0;
943 for (i=1;i<x.length;i++)
944 if (x[i])
945 return 0;
946 return 1;
947}
948
949//are bigints x and y equal?
950//this works even if x and y are different lengths and have arbitrarily many leading zeros
951function equals(x,y) {
952 var i;
953 var k=x.length<y.length ? x.length : y.length;
954 for (i=0;i<k;i++)
955 if (x[i]!=y[i])
956 return 0;
957 if (x.length>y.length) {
958 for (;i<x.length;i++)
959 if (x[i])
960 return 0;
961 } else {
962 for (;i<y.length;i++)
963 if (y[i])
964 return 0;
965 }
966 return 1;
967}
968
969//is the bigInt x equal to zero?
970function isZero(x) {
971 var i;
972 for (i=0;i<x.length;i++)
973 if (x[i])
974 return 0;
975 return 1;
976}
977
978//convert a bigInt into a string in a given base, from base 2 up to base 95.
979//Base -1 prints the contents of the array representing the number.
980function bigInt2str(x,base) {
981 var i,t,s="";
982
983 if (s6.length!=x.length)
984 s6=dup(x);
985 else
986 copy_(s6,x);
987
988 if (base==-1) { //return the list of array contents
989 for (i=x.length-1;i>0;i--)
990 s+=x[i]+',';
991 s+=x[0];
992 }
993 else { //return it in the given base
994 while (!isZero(s6)) {
995 t=divInt_(s6,base); //t=s6 % base; s6=floor(s6/base);
996 s=digitsStr.substring(t,t+1)+s;
997 }
998 }
999 if (s.length==0)
1000 s="0";
1001 return s;
1002}
1003
1004//returns a duplicate of bigInt x
1005function dup(x) {
1006 var i;
1007 buff=new Array(x.length);
1008 copy_(buff,x);
1009 return buff;
1010}
1011
1012//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).
1013function copy_(x,y) {
1014 var i;
1015 var k=x.length<y.length ? x.length : y.length;
1016 for (i=0;i<k;i++)
1017 x[i]=y[i];
1018 for (i=k;i<x.length;i++)
1019 x[i]=0;
1020}
1021
1022//do x=y on bigInt x and integer y.
1023function copyInt_(x,n) {
1024 var i,c;
1025 for (c=n,i=0;i<x.length;i++) {
1026 x[i]=c & mask;
1027 c>>=bpe;
1028 }
1029}
1030
1031//do x=x+n where x is a bigInt and n is an integer.
1032//x must be large enough to hold the result.
1033function addInt_(x,n) {
1034 var i,k,c,b;
1035 x[0]+=n;
1036 k=x.length;
1037 c=0;
1038 for (i=0;i<k;i++) {
1039 c+=x[i];
1040 b=0;
1041 if (c<0) {
1042 b=-(c>>bpe);
1043 c+=b*radix;
1044 }
1045 x[i]=c & mask;
1046 c=(c>>bpe)-b;
1047 if (!c) return; //stop carrying as soon as the carry_ is zero
1048 }
1049}
1050
1051//right shift bigInt x by n bits. 0 <= n < bpe.
1052function rightShift_(x,n) {
1053 var i;
1054 var k=Math.floor(n/bpe);
1055 if (k) {
1056 for (i=0;i<x.length-k;i++) //right shift x by k elements
1057 x[i]=x[i+k];
1058 for (;i<x.length;i++)
1059 x[i]=0;
1060 n%=bpe;
1061 }
1062 for (i=0;i<x.length-1;i++) {
1063 x[i]=mask & ((x[i+1]<<(bpe-n)) | (x[i]>>n));
1064 }
1065 x[i]>>=n;
1066}
1067
1068//do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
1069function halve_(x) {
1070 var i;
1071 for (i=0;i<x.length-1;i++) {
1072 x[i]=mask & ((x[i+1]<<(bpe-1)) | (x[i]>>1));
1073 }
1074 x[i]=(x[i]>>1) | (x[i] & (radix>>1)); //most significant bit stays the same
1075}
1076
1077//left shift bigInt x by n bits.
1078function leftShift_(x,n) {
1079 var i;
1080 var k=Math.floor(n/bpe);
1081 if (k) {
1082 for (i=x.length; i>=k; i--) //left shift x by k elements
1083 x[i]=x[i-k];
1084 for (;i>=0;i--)
1085 x[i]=0;
1086 n%=bpe;
1087 }
1088 if (!n)
1089 return;
1090 for (i=x.length-1;i>0;i--) {
1091 x[i]=mask & ((x[i]<<n) | (x[i-1]>>(bpe-n)));
1092 }
1093 x[i]=mask & (x[i]<<n);
1094}
1095
1096//do x=x*n where x is a bigInt and n is an integer.
1097//x must be large enough to hold the result.
1098function multInt_(x,n) {
1099 var i,k,c,b;
1100 if (!n)
1101 return;
1102 k=x.length;
1103 c=0;
1104 for (i=0;i<k;i++) {
1105 c+=x[i]*n;
1106 b=0;
1107 if (c<0) {
1108 b=-(c>>bpe);
1109 c+=b*radix;
1110 }
1111 x[i]=c & mask;
1112 c=(c>>bpe)-b;
1113 }
1114}
1115
1116//do x=floor(x/n) for bigInt x and integer n, and return the remainder
1117function divInt_(x,n) {
1118 var i,r=0,s;
1119 for (i=x.length-1;i>=0;i--) {
1120 s=r*radix+x[i];
1121 x[i]=Math.floor(s/n);
1122 r=s%n;
1123 }
1124 return r;
1125}
1126
1127//do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b.
1128//x must be large enough to hold the answer.
1129function linComb_(x,y,a,b) {
1130 var i,c,k,kk;
1131 k=x.length<y.length ? x.length : y.length;
1132 kk=x.length;
1133 for (c=0,i=0;i<k;i++) {
1134 c+=a*x[i]+b*y[i];
1135 x[i]=c & mask;
1136 c>>=bpe;
1137 }
1138 for (i=k;i<kk;i++) {
1139 c+=a*x[i];
1140 x[i]=c & mask;
1141 c>>=bpe;
1142 }
1143}
1144
1145//do the linear combination x=a*x+b*(y<<(ys*bpe)) for bigInts x and y, and integers a, b and ys.
1146//x must be large enough to hold the answer.
1147function linCombShift_(x,y,b,ys) {
1148 var i,c,k,kk;
1149 k=x.length<ys+y.length ? x.length : ys+y.length;
1150 kk=x.length;
1151 for (c=0,i=ys;i<k;i++) {
1152 c+=x[i]+b*y[i-ys];
1153 x[i]=c & mask;
1154 c>>=bpe;
1155 }
1156 for (i=k;c && i<kk;i++) {
1157 c+=x[i];
1158 x[i]=c & mask;
1159 c>>=bpe;
1160 }
1161}
1162
1163//do x=x+(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
1164//x must be large enough to hold the answer.
1165function addShift_(x,y,ys) {
1166 var i,c,k,kk;
1167 k=x.length<ys+y.length ? x.length : ys+y.length;
1168 kk=x.length;
1169 for (c=0,i=ys;i<k;i++) {
1170 c+=x[i]+y[i-ys];
1171 x[i]=c & mask;
1172 c>>=bpe;
1173 }
1174 for (i=k;c && i<kk;i++) {
1175 c+=x[i];
1176 x[i]=c & mask;
1177 c>>=bpe;
1178 }
1179}
1180
1181//do x=x-(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
1182//x must be large enough to hold the answer.
1183function subShift_(x,y,ys) {
1184 var i,c,k,kk;
1185 k=x.length<ys+y.length ? x.length : ys+y.length;
1186 kk=x.length;
1187 for (c=0,i=ys;i<k;i++) {
1188 c+=x[i]-y[i-ys];
1189 x[i]=c & mask;
1190 c>>=bpe;
1191 }
1192 for (i=k;c && i<kk;i++) {
1193 c+=x[i];
1194 x[i]=c & mask;
1195 c>>=bpe;
1196 }
1197}
1198
1199//do x=x-y for bigInts x and y.
1200//x must be large enough to hold the answer.
1201//negative answers will be 2s complement
1202function sub_(x,y) {
1203 var i,c,k,kk;
1204 k=x.length<y.length ? x.length : y.length;
1205 for (c=0,i=0;i<k;i++) {
1206 c+=x[i]-y[i];
1207 x[i]=c & mask;
1208 c>>=bpe;
1209 }
1210 for (i=k;c && i<x.length;i++) {
1211 c+=x[i];
1212 x[i]=c & mask;
1213 c>>=bpe;
1214 }
1215}
1216
1217//do x=x+y for bigInts x and y.
1218//x must be large enough to hold the answer.
1219function add_(x,y) {
1220 var i,c,k,kk;
1221 k=x.length<y.length ? x.length : y.length;
1222 for (c=0,i=0;i<k;i++) {
1223 c+=x[i]+y[i];
1224 x[i]=c & mask;
1225 c>>=bpe;
1226 }
1227 for (i=k;c && i<x.length;i++) {
1228 c+=x[i];
1229 x[i]=c & mask;
1230 c>>=bpe;
1231 }
1232}
1233
1234//do x=x*y for bigInts x and y. This is faster when y<x.
1235function mult_(x,y) {
1236 var i;
1237 if (ss.length!=2*x.length)
1238 ss=new Array(2*x.length);
1239 copyInt_(ss,0);
1240 for (i=0;i<y.length;i++)
1241 if (y[i])
1242 linCombShift_(ss,x,y[i],i); //ss=1*ss+y[i]*(x<<(i*bpe))
1243 copy_(x,ss);
1244}
1245
1246//do x=x mod n for bigInts x and n.
1247function mod_(x,n) {
1248 if (s4.length!=x.length)
1249 s4=dup(x);
1250 else
1251 copy_(s4,x);
1252 if (s5.length!=x.length)
1253 s5=dup(x);
1254 divide_(s4,n,s5,x); //x = remainder of s4 / n
1255}
1256
1257//do x=x*y mod n for bigInts x,y,n.
1258//for greater speed, let y<x.
1259function multMod_(x,y,n) {
1260 var i;
1261 if (s0.length!=2*x.length)
1262 s0=new Array(2*x.length);
1263 copyInt_(s0,0);
1264 for (i=0;i<y.length;i++)
1265 if (y[i])
1266 linCombShift_(s0,x,y[i],i); //s0=1*s0+y[i]*(x<<(i*bpe))
1267 mod_(s0,n);
1268 copy_(x,s0);
1269}
1270
1271//do x=x*x mod n for bigInts x,n.
1272function squareMod_(x,n) {
1273 var i,j,d,c,kx,kn,k;
1274 for (kx=x.length; kx>0 && !x[kx-1]; kx--); //ignore leading zeros in x
1275 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
1276 if (s0.length!=k)
1277 s0=new Array(k);
1278 copyInt_(s0,0);
1279 for (i=0;i<kx;i++) {
1280 c=s0[2*i]+x[i]*x[i];
1281 s0[2*i]=c & mask;
1282 c>>=bpe;
1283 for (j=i+1;j<kx;j++) {
1284 c=s0[i+j]+2*x[i]*x[j]+c;
1285 s0[i+j]=(c & mask);
1286 c>>=bpe;
1287 }
1288 s0[i+kx]=c;
1289 }
1290 mod_(s0,n);
1291 copy_(x,s0);
1292}
1293
1294//return x with exactly k leading zero elements
1295function trim(x,k) {
1296 var i,y;
1297 for (i=x.length; i>0 && !x[i-1]; i--);
1298 y=new Array(i+k);
1299 copy_(y,x);
1300 return y;
1301}
1302
1303//do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation. 0**0=1.
1304//this is faster when n is odd. x usually needs to have as many elements as n.
1305function powMod_(x,y,n) {
1306 var k1,k2,kn,np;
1307 if(s7.length!=n.length)
1308 s7=dup(n);
1309
1310 //for even modulus, use a simple square-and-multiply algorithm,
1311 //rather than using the more complex Montgomery algorithm.
1312 if ((n[0]&1)==0) {
1313 copy_(s7,x);
1314 copyInt_(x,1);
1315 while(!equalsInt(y,0)) {
1316 if (y[0]&1)
1317 multMod_(x,s7,n);
1318 divInt_(y,2);
1319 squareMod_(s7,n);
1320 }
1321 return;
1322 }
1323
1324 //calculate np from n for the Montgomery multiplications
1325 copyInt_(s7,0);
1326 for (kn=n.length;kn>0 && !n[kn-1];kn--);
1327 np=radix-inverseModInt_(modInt(n,radix),radix);
1328 s7[kn]=1;
1329 multMod_(x ,s7,n); // x = x * 2**(kn*bp) mod n
1330
1331 if (s3.length!=x.length)
1332 s3=dup(x);
1333 else
1334 copy_(s3,x);
1335
1336 for (k1=y.length-1;k1>0 & !y[k1]; k1--); //k1=first nonzero element of y
1337 if (y[k1]==0) { //anything to the 0th power is 1
1338 copyInt_(x,1);
1339 return;
1340 }
1341 for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1); //k2=position of first 1 bit in y[k1]
1342 for (;;) {
1343 if (!(k2>>=1)) { //look at next bit of y
1344 k1--;
1345 if (k1<0) {
1346 mont_(x,one,n,np);
1347 return;
1348 }
1349 k2=1<<(bpe-1);
1350 }
1351 mont_(x,x,n,np);
1352
1353 if (k2 & y[k1]) //if next bit is a 1
1354 mont_(x,s3,n,np);
1355 }
1356}
1357
1358//do x=x*y*Ri mod n for bigInts x,y,n,
1359// where Ri = 2**(-kn*bpe) mod n, and kn is the
1360// number of elements in the n array, not
1361// counting leading zeros.
1362//x must be large enough to hold the answer.
1363//It's OK if x and y are the same variable.
1364//must have:
1365// x,y < n
1366// n is odd
1367// np = -(n^(-1)) mod radix
1368function mont_(x,y,n,np) {
1369 var i,j,c,ui,t;
1370 var kn=n.length;
1371 var ky=y.length;
1372
1373 if (sa.length!=kn)
1374 sa=new Array(kn);
1375
1376 for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n
1377 //this function sometimes gives wrong answers when the next line is uncommented
1378 //for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y
1379
1380 copyInt_(sa,0);
1381
1382 //the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large keys
1383 for (i=0; i<kn; i++) {
1384 t=sa[0]+x[i]*y[0];
1385 ui=((t & mask) * np) & mask; //the inner "& mask" is needed on Macintosh MSIE, but not windows MSIE
1386 c=(t+ui*n[0]) >> bpe;
1387 t=x[i];
1388
1389 //do sa=(sa+x[i]*y+ui*n)/b where b=2**bpe
1390 for (j=1;j<ky;j++) {
1391 c+=sa[j]+t*y[j]+ui*n[j];
1392 sa[j-1]=c & mask;
1393 c>>=bpe;
1394 }
1395 for (;j<kn;j++) {
1396 c+=sa[j]+ui*n[j];
1397 sa[j-1]=c & mask;
1398 c>>=bpe;
1399 }
1400 sa[j-1]=c & mask;
1401 }
1402
1403 if (!greater(n,sa))
1404 sub_(sa,n);
1405 copy_(x,sa);
1406}
1407
1408
1409
1410
1411//#############################################################################
1412//#############################################################################
1413//#############################################################################
1414//#############################################################################
1415//#############################################################################
1416//#############################################################################
1417//#############################################################################
1418
1419
1420
1421
1422
1423//#############################################################################
1424
1425Clipperz.Crypto.BigInt = function (aValue, aBase) {
1426 varbase;
1427 varvalue;
1428
1429 if (typeof(aValue) == 'object') {
1430 this._internalValue = aValue;
1431 } else {
1432 if (typeof(aValue) == 'undefined') {
1433 value = "0";
1434 } else {
1435 value = aValue + "";
1436 }
1437
1438 if (typeof(aBase) == 'undefined') {
1439 base = 10;
1440 } else {
1441 base = aBase;
1442 }
1443
1444 this._internalValue = str2bigInt(value, base, 1, 1);
1445 }
1446
1447 return this;
1448}
1449
1450//=============================================================================
1451
1452MochiKit.Base.update(Clipperz.Crypto.BigInt.prototype, {
1453
1454 //-------------------------------------------------------------------------
1455
1456 'internalValue': function () {
1457 return this._internalValue;
1458 },
1459
1460 //-------------------------------------------------------------------------
1461
1462 'isBigInt': true,
1463
1464 //-------------------------------------------------------------------------
1465
1466 'toString': function(aBase) {
1467 return this.asString(aBase);
1468 },
1469
1470 //-------------------------------------------------------------------------
1471
1472 'asString': function (aBase) {
1473 varbase;
1474
1475 if (typeof(aBase) == 'undefined') {
1476 base = 10;
1477 } else {
1478 base = aBase;
1479 }
1480
1481 return bigInt2str(this.internalValue(), base).toLowerCase();
1482 },
1483
1484 //-------------------------------------------------------------------------
1485
1486 'equals': function (aValue) {
1487 var result;
1488
1489 if (aValue.isBigInt) {
1490 result = equals(this.internalValue(), aValue.internalValue());
1491 } else if (typeof(aValue) == "number") {
1492 result = equalsInt(this.internalValue(), aValue);
1493 } else {
1494 throw Clipperz.Crypt.BigInt.exception.UnknownType;
1495 }
1496
1497 return result;
1498 },
1499
1500 //-------------------------------------------------------------------------
1501
1502 'add': function (aValue) {
1503 var result;
1504
1505 if (aValue.isBigInt) {
1506 result = add(this.internalValue(), aValue.internalValue());
1507 } else {
1508 result = addInt(this.internalValue(), aValue);
1509 }
1510
1511 return new Clipperz.Crypto.BigInt(result);
1512 },
1513
1514 //-------------------------------------------------------------------------
1515
1516 'subtract': function (aValue) {
1517 var result;
1518 var value;
1519
1520 if (aValue.isBigInt) {
1521 value = aValue;
1522 } else {
1523 value = new Clipperz.Crypto.BigInt(aValue);
1524 }
1525
1526 result = sub(this.internalValue(), value.internalValue());
1527
1528 return new Clipperz.Crypto.BigInt(result);
1529 },
1530
1531 //-------------------------------------------------------------------------
1532
1533 'multiply': function (aValue, aModule) {
1534 var result;
1535 var value;
1536
1537 if (aValue.isBigInt) {
1538 value = aValue;
1539 } else {
1540 value = new Clipperz.Crypto.BigInt(aValue);
1541 }
1542
1543 if (typeof(aModule) == 'undefined') {
1544 result = mult(this.internalValue(), value.internalValue());
1545 } else {
1546 result = multMod(this.internalValue(), value.internalValue(), aModule);
1547 }
1548
1549 return new Clipperz.Crypto.BigInt(result);
1550 },
1551
1552 //-------------------------------------------------------------------------
1553
1554 'module': function (aModule) {
1555 varresult;
1556 var module;
1557
1558 if (aModule.isBigInt) {
1559 module = aModule;
1560 } else {
1561 module = new Clipperz.Crypto.BigInt(aModule);
1562 }
1563
1564 result = mod(this.internalValue(), module.internalValue());
1565
1566 return new Clipperz.Crypto.BigInt(result);
1567 },
1568
1569 //-------------------------------------------------------------------------
1570
1571 'powerModule': function(aValue, aModule) {
1572 varresult;
1573 varvalue;
1574 var module;
1575
1576 if (aValue.isBigInt) {
1577 value = aValue;
1578 } else {
1579 value = new Clipperz.Crypto.BigInt(aValue);
1580 }
1581
1582 if (aModule.isBigInt) {
1583 module = aModule;
1584 } else {
1585 module = new Clipperz.Crypto.BigInt(aModule);
1586 }
1587
1588 if (aValue == -1) {
1589 result = inverseMod(this.internalValue(), module.internalValue());
1590 } else {
1591 result = powMod(this.internalValue(), value.internalValue(), module.internalValue());
1592 }
1593
1594 return new Clipperz.Crypto.BigInt(result);
1595 },
1596
1597 //-------------------------------------------------------------------------
1598
1599 'bitSize': function() {
1600 return bitSize(this.internalValue());
1601 },
1602
1603 //-------------------------------------------------------------------------
1604 __syntaxFix__: "syntax fix"
1605
1606});
1607
1608//#############################################################################
1609
1610Clipperz.Crypto.BigInt.randomPrime = function(aBitSize) {
1611 return new Clipperz.Crypto.BigInt(randTruePrime(aBitSize));
1612}
1613
1614//#############################################################################
1615//#############################################################################
1616//#############################################################################
1617
1618Clipperz.Crypto.BigInt.equals = function(a, b) {
1619 return a.equals(b);
1620}
1621
1622Clipperz.Crypto.BigInt.add = function(a, b) {
1623 return a.add(b);
1624}
1625
1626Clipperz.Crypto.BigInt.subtract = function(a, b) {
1627 return a.subtract(b);
1628}
1629
1630Clipperz.Crypto.BigInt.multiply = function(a, b, module) {
1631 return a.multiply(b, module);
1632}
1633
1634Clipperz.Crypto.BigInt.module = function(a, module) {
1635 return a.module(module);
1636}
1637
1638Clipperz.Crypto.BigInt.powerModule = function(a, b, module) {
1639 return a.powerModule(b, module);
1640}
1641
1642Clipperz.Crypto.BigInt.exception = {
1643 UnknownType: new MochiKit.Base.NamedError("Clipperz.Crypto.BigInt.exception.UnknownType")
1644}
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/ByteArray.js b/frontend/gamma/js/ClipperzCryptoLibrary/ByteArray.js
deleted file mode 100644
index aca1c00..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/ByteArray.js
+++ b/dev/null
@@ -1,1496 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25
26//=============================================================================
27
28Clipperz.ByteArray_abstract = function(args) {
29 return this;
30}
31
32Clipperz.ByteArray_abstract.prototype = MochiKit.Base.update(null, {
33
34 //-------------------------------------------------------------------------
35
36 'toString': function() {
37 return "Clipperz.ByteArray_abstract";
38 },
39
40 //-------------------------------------------------------------------------
41
42 'equals': function(aValue) {
43 return (this.compare(aValue) == 0);
44 },
45
46 //-------------------------------------------------------------------------
47
48 'compare': function(aValue) {
49 var result;
50 var i;
51
52 result = MochiKit.Base.compare(this.length(), aValue.length());
53 i = this.length();
54
55 while ((result == 0) && (i>0)) {
56 i--;
57 result = MochiKit.Base.compare(this.byteAtIndex(i), aValue.byteAtIndex(i));
58 }
59
60 return result;
61 },
62
63 //-------------------------------------------------------------------------
64
65 'clone': function() {
66 throw Clipperz.Base.exception.AbstractMethod;
67 },
68
69 //-------------------------------------------------------------------------
70
71 'newInstance': function() {
72 throw Clipperz.Base.exception.AbstractMethod;
73 },
74
75 //-------------------------------------------------------------------------
76
77 'reset': function() {
78 throw Clipperz.Base.exception.AbstractMethod;
79 },
80
81 //-------------------------------------------------------------------------
82
83 'length': function() {
84 throw Clipperz.Base.exception.AbstractMethod;
85 },
86
87 //-------------------------------------------------------------------------
88
89 'checkByteValue': function(aValue) {
90//Clipperz.log("aValue", aValue.toString(16));
91//Clipperz.log("(aValue & 0xff)", (aValue & 0xff).toString(16));
92
93 if ((aValue & 0xff) != aValue) {
94 MochiKit.Logging.logError("Clipperz.ByteArray.appendByte: the provided value (0x" + aValue.toString(16) + ") is not a byte value.");
95 throw Clipperz.ByteArray.exception.InvalidValue;
96 }
97 },
98
99 //-------------------------------------------------------------------------
100
101 'xorMergeWithBlock': function(aBlock, anAllignment, paddingMode) {
102 var result;
103 var a, b;
104 var aLength;
105 var bLength;
106 var i, c;
107
108 if (this.length() > aBlock.length()) {
109 a = this;
110 b = aBlock;
111 } else {
112 a = aBlock;
113 b = this;
114 }
115
116 aLength = a.length();
117 bLength = b.length();
118
119 if (aLength != bLength) {
120 if (paddingMode == 'truncate') {
121 if (anAllignment == 'left') {
122 a = a.split(0, bLength);
123 } else {
124 a = a.split(aLength - bLength);
125 }
126 } else {
127 var ii, cc;
128 var padding;
129
130 // padding = new Clipperz.ByteArray();
131 padding = this.newInstance();
132 cc = aLength - bLength;
133 for (ii=0; ii<cc; ii++) {
134 padding.appendByte(0);
135 }
136
137 if (anAllignment == 'left') {
138 b = b.appendBlock(padding);
139 } else {
140 b = padding.appendBlock(b);
141 }
142 }
143 }
144
145
146 // result = new Clipperz.ByteArray();
147 result = this.newInstance();
148 c = a.length();
149 for (i=0; i<c; i++) {
150 result.appendByte(a.byteAtIndex(i) ^ b.byteAtIndex(i));
151 }
152
153 return result;
154 },
155
156 //-------------------------------------------------------------------------
157/*
158 'shiftLeft': function(aNumberOfBitsToShift) {
159 var result;
160
161 result = this.clone(); //???????????
162
163 return result;
164 },
165 */
166 //-------------------------------------------------------------------------
167
168 'appendBlock': function(aBlock) {
169 throw Clipperz.Base.exception.AbstractMethod;
170 },
171
172 //-------------------------------------------------------------------------
173
174 'appendByte': function(aValue) {
175 throw Clipperz.Base.exception.AbstractMethod;
176 },
177
178 'appendBytes': function(args) {
179 varvalues;
180 vari,c;
181
182 if (args.constructor == Array) {
183 values = args;
184 } else {
185 values = arguments;
186 }
187
188 c = values.length;
189 for (i=0; i<c; i++) {
190 this.appendByte(values[i]);
191 }
192
193 return this;
194 },
195
196 //-------------------------------------------------------------------------
197
198 'appendWord': function(aValue, isLittleEndian) {
199 var result;
200 var processAsLittleEndian;
201
202 processAsLittleEndian = isLittleEndian === true ? true : false;
203
204 if (processAsLittleEndian) {
205 result = this.appendBytes( (aValue) & 0xff, (aValue >> 8) & 0xff, (aValue >> 16) & 0xff, (aValue >> 24) & 0xff ); //little endian
206 } else {
207 result = this.appendBytes( (aValue >> 24) & 0xff, (aValue >> 16) & 0xff, (aValue >> 8) & 0xff, (aValue) & 0xff ); //big endian - DEFAULT
208 }
209
210 return result;
211 },
212
213 'appendWords': function(args) {
214 varvalues;
215 vari,c;
216
217 if (args.constructor == Array) {
218 values = args;
219 } else {
220 values = arguments;
221 }
222
223 c = values.length;
224 for (i=0; i<c; i++) {
225 this.appendWord(values[i], false);
226 }
227
228 return this;
229 },
230
231 //-------------------------------------------------------------------------
232
233 'appendBigEndianWords': function(args) {
234 varvalues;
235 vari,c;
236
237 if (args.constructor == Array) {
238 values = args;
239 } else {
240 values = arguments;
241 }
242
243 c = values.length;
244 for (i=0; i<c; i++) {
245 this.appendWord(values[i], true);
246 }
247
248 return this;
249 },
250
251 //-------------------------------------------------------------------------
252
253 'appendBinaryString': function (aBinaryString) {
254 var i,c;
255
256 c = aBinaryString.length;
257 for (i=0; i<c; i++) {
258 this.appendByte(aBinaryString.charCodeAt(i));
259 };
260
261 return this;
262 },
263
264 //-------------------------------------------------------------------------
265
266 'byteAtIndex': function(anIndex) {
267 throw Clipperz.Base.exception.AbstractMethod;
268 },
269
270 'setByteAtIndex': function(aValue, anIndex) {
271 throw Clipperz.Base.exception.AbstractMethod;
272 },
273
274 //-------------------------------------------------------------------------
275
276 'bitAtIndex': function(aBitPosition) {
277 var result;
278 varbytePosition;
279 var bitPositionInSelectedByte;
280 var selectedByte;
281 var selectedByteMask;
282
283 bytePosition = this.length() - Math.ceil((aBitPosition + 1)/ 8);
284 bitPositionInSelectedByte = aBitPosition % 8;
285 selectedByte = this.byteAtIndex(bytePosition);
286
287 if (bitPositionInSelectedByte > 0) {
288 selectedByteMask = (1 << bitPositionInSelectedByte);
289 } else {
290 selectedByteMask = 1;
291 }
292 result = selectedByte & selectedByteMask ? 1 : 0;
293//console.log("aBitPosition: " + aBitPosition + ", length: " + this.length() + ", bytePosition: " + bytePosition + ", bitPositionInSelectedByte: " + bitPositionInSelectedByte + ", selectedByteMask: " + selectedByteMask);
294
295 return result;
296 },
297
298 //-------------------------------------------------------------------------
299
300 'bitBlockAtIndexWithSize': function(aBitPosition, aSize) {
301 var result;
302 var bitValue;
303 var i,c;
304
305 result = 0;
306 c = aSize;
307 for (i=0; i<c; i++) {
308 bitValue = this.bitAtIndex(aBitPosition + i);
309 result = result | bitValue << i;
310 }
311
312 return result;
313 },
314
315 //-------------------------------------------------------------------------
316
317 'asString': function() {
318 varresult;
319 varlength;
320 vari;
321
322//var startTime = new Date();
323
324 //# result = "";
325 result = [];
326
327 i = 0;
328 length = this.length();
329
330 while (i < length) {
331 varcurrentCharacter;
332 varcurrentByte;
333 varunicode;
334
335 currentByte = this.byteAtIndex(i);
336
337 if ((currentByte & 0x80) == 0x00 ) { //0xxxxxxx
338 unicode = currentByte;
339 currentCharacter = String.fromCharCode(unicode);
340 } else if ((currentByte & 0xe0) == 0xc0 ) { //110xxxxx 10xxxxxx
341 unicode = (currentByte & 0x1f) << 6;
342 i++; currentByte = this.byteAtIndex(i);
343 unicode = unicode | (currentByte & 0x3f);
344
345 currentCharacter = String.fromCharCode(unicode);
346 } else if ((currentByte & 0xf0) == 0xe0 ) { //1110xxxx 10xxxxxx 10xxxxxx
347 unicode = (currentByte & 0x0f) << (6+6);
348 i++; currentByte = this.byteAtIndex(i);
349 unicode = unicode | ((currentByte & 0x3f) << 6);
350 i++; currentByte = this.byteAtIndex(i);
351 unicode = unicode | (currentByte & 0x3f);
352
353 currentCharacter = String.fromCharCode(unicode);
354 } else { //11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
355 unicode = (currentByte & 0x07) << (6+6+6);
356 i++; currentByte = this.byteAtIndex(i);
357 unicode = unicode | ((currentByte & 0x3f) << (6+6));
358 i++; currentByte = this.byteAtIndex(i);
359 unicode = unicode | ((currentByte & 0x3f) << 6);
360 i++; currentByte = this.byteAtIndex(i);
361 unicode = unicode | (currentByte & 0x3f);
362
363 currentCharacter = String.fromCharCode(unicode);
364 }
365
366 // result += currentCharacter;
367 result.push(currentCharacter);
368 i++;
369 }
370
371//MochiKit.Logging.logDebug("[" + (new Date() - startTime) + "] ByteArray.asString");
372
373 // return result;
374 return result.join("");
375 },
376
377 //-------------------------------------------------------------------------
378
379 'toHexString': function() {
380 throw Clipperz.Base.exception.AbstractMethod;
381 },
382
383 //-------------------------------------------------------------------------
384
385 'base64map': "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
386 'base64mapIndex': "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(''),
387 //'base64mapInvertedIndex': {
388 // 'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9,
389 // 'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16, 'R': 17, 'S': 18, 'T': 19,
390 // 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24, 'Z': 25, 'a': 26, 'b': 27, 'c': 28, 'd': 29,
391 // 'e': 30, 'f': 31, 'g': 32, 'h': 33, 'i': 34, 'j': 35, 'k': 36, 'l': 37, 'm': 38, 'n': 39,
392 // 'o': 40, 'p': 41, 'q': 42, 'r': 43, 's': 44, 't': 45, 'u': 46, 'v': 47, 'w': 48, 'x': 49,
393 // 'y': 50, 'z': 51, '0': 52, '1': 53, '2': 54, '3': 55, '4': 56, '5': 57, '6': 58, '7': 59,
394 // '8': 60, '9': 61, '+': 62, '/': 63,
395 // "=": -1},
396
397 //-------------------------------------------------------------------------
398
399 'appendBase64String': function(aValue) {
400 var i;
401 var length;
402
403 length = aValue.length;
404
405 if ((length % 4) != 0) {
406 MochiKit.Logging.logError("the value passed to the 'ByteArray.setBase64Value' is not correct");
407 throw Clipperz.ByteArray.exception.InvalidValue;
408 }
409
410 i = 0;
411 while (i<length) {
412 var value1, value2, value3, value4;
413 var byte1, byte2, byte3;
414
415 value1 = this.base64map.indexOf(aValue.charAt(i));
416 value2 = this.base64map.indexOf(aValue.charAt(i+1));
417 value3 = this.base64map.indexOf(aValue.charAt(i+2));
418 value4 = this.base64map.indexOf(aValue.charAt(i+3));
419
420 // value1 = this.base64mapInvertedIndex[aValue.charAt(i)];
421 // value2 = this.base64mapInvertedIndex[aValue.charAt(i+1)];
422 // value3 = this.base64mapInvertedIndex[aValue.charAt(i+2)];
423 // value4 = this.base64mapInvertedIndex[aValue.charAt(i+3)];
424
425 byte1 = (value1 << 2) | ((value2 & 0x30) >> 4);
426 if (value3 != -1) {
427 byte2 = ((value2 & 0x0f) << 4) | ((value3 & 0x3c) >> 2);
428
429 if (value4 != -1) {
430 byte3 = ((value3 & 0x03) << 6) | (value4);
431 } else {
432 byte3 = null;
433 }
434 } else {
435 byte2 = null;
436 byte3 = null;
437 }
438
439 this.appendByte(byte1);
440 this.appendByte(byte2);
441 this.appendByte(byte3);
442
443 i += 4;
444 }
445
446 return this;
447 },
448
449 //-------------------------------------------------------------------------
450
451 'toBase64String': function() {
452 var result;
453 var length;
454 var i;
455 var byte1, byte2, byte3;
456 var char1, char2, char3, char4;
457
458 i = 0;
459 length = this.length();
460 result = new Array(Math.ceil(length/3));
461
462 while (i < length) {
463 byte1 = this.byteAtIndex(i);
464 if ((i+2) < length) {
465 byte2 = this.byteAtIndex(i+1);
466 byte3 = this.byteAtIndex(i+2);
467 } else if ((i+2) == length) {
468 byte2 = this.byteAtIndex(i+1);
469 byte3 = null;
470 } else {
471 byte2 = null;
472 byte3 = null;
473 }
474
475 char1 = this.base64mapIndex[byte1 >> 2];
476 if (byte2 != null) {
477 char2 = this.base64mapIndex[((byte1 & 0x03) << 4) | ((byte2 & 0xf0) >> 4)];
478 if (byte3 != null) {
479 char3 = this.base64mapIndex[((byte2 & 0x0f) << 2) | ((byte3 & 0xc0) >> 6)];
480 char4 = this.base64mapIndex[(byte3 & 0x3f)];
481 } else {
482 char3 = this.base64mapIndex[(byte2 & 0x0f) << 2];
483 char4 = "=";
484 }
485 } else {
486 char2 = this.base64mapIndex[(byte1 & 0x03) << 4];
487 char3 = "=";
488 char4 = "=";
489 }
490
491 result.push(char1 + char2 + char3 + char4);
492
493 i += 3;
494 }
495
496 return result.join("");
497 },
498
499 //-------------------------------------------------------------------------
500
501 'base32map': "0123456789abcdefghjkmnpqrstvwxyz",
502 'base32mapIndex': "0123456789abcdefghjkmnpqrstvwxyz".split(''),
503
504 //-------------------------------------------------------------------------
505
506 'appendBase32String': function(aValue) {
507 var value;
508 var i;
509 var length;
510 var value1, value2, value3, value4, value5, value6, value7, value8;
511 var byte1, byte2, byte3, byte4, byte5;
512
513 value = aValue.toLowerCase();
514 value = value.replace(/[\s\-]/g, '');
515 value = value.replace(/[0o]/g, '0');
516 value = value.replace(/[1il]/g, '1');
517
518 length = value.length;
519
520 if ((length % 8) != 0) {
521 MochiKit.Logging.logError("the value passed to the 'ByteArray.setBase32Value' is not correct");
522 throw Clipperz.ByteArray.exception.InvalidValue;
523 }
524
525 i = 0;
526 while (i<length) {
527 value1 = this.base32map.indexOf(value.charAt(i));
528 value2 = this.base32map.indexOf(value.charAt(i+1));
529 value3 = this.base32map.indexOf(value.charAt(i+2));
530 value4 = this.base32map.indexOf(value.charAt(i+3));
531 value5 = this.base32map.indexOf(value.charAt(i+4));
532 value6 = this.base32map.indexOf(value.charAt(i+5));
533 value7 = this.base32map.indexOf(value.charAt(i+6));
534 value8 = this.base32map.indexOf(value.charAt(i+7));
535
536 byte1 = byte2 = byte3 = byte4 = byte5 = null;
537
538 byte1 = (value1 << 3) | ((value2 & 0x1c) >> 2);
539 if (value3 != -1) {
540 byte2 = ((value2 & 0x03) << 6) | (value3 << 1) | ((value4 & 0x10) >> 4);
541 if (value5 != -1) {
542 byte3 = ((value4 & 0x0f) << 4) | ((value5 & 0x1e) >> 1);
543 if (value6 != -1) {
544 byte4 = ((value5 & 0x01) << 7) | (value6 << 2) | ((value7 & 0x18) >> 3);
545 if (value8 != -1) {
546 byte5 = ((value7 & 0x07) << 5) | (value8);
547 }
548 }
549 }
550 }
551
552 this.appendByte(byte1);
553 this.appendByte(byte2);
554 this.appendByte(byte3);
555 this.appendByte(byte4);
556 this.appendByte(byte5);
557
558 i += 8;
559 }
560
561 return this;
562 },
563
564 //-------------------------------------------------------------------------
565
566 'toBase32String': function() {
567 var result;
568 var length;
569 var i;
570 var byte1, byte2, byte3, byte4, byte5;
571 var char1, char2, char3, char4, char5, char6, char7, char8;
572
573 i = 0;
574 length = this.length();
575 result = new Array(Math.ceil(length/5));
576
577 while (i < length) {
578 byte1 = this.byteAtIndex(i);
579
580 if ((i+4) < length) {
581 byte2 = this.byteAtIndex(i+1);
582 byte3 = this.byteAtIndex(i+2);
583 byte4 = this.byteAtIndex(i+3);
584 byte5 = this.byteAtIndex(i+4);
585 } else if ((i+4) == length) {
586 byte2 = this.byteAtIndex(i+1);
587 byte3 = this.byteAtIndex(i+2);
588 byte4 = this.byteAtIndex(i+3);
589 byte5 = null;
590 } else if ((i+3) == length) {
591 byte2 = this.byteAtIndex(i+1);
592 byte3 = this.byteAtIndex(i+2);
593 byte4 = null;
594 byte5 = null;
595 } else if ((i+2) == length) {
596 byte2 = this.byteAtIndex(i+1);
597 byte3 = null;
598 byte4 = null;
599 byte5 = null;
600 } else {
601 byte2 = null;
602 byte3 = null;
603 byte4 = null;
604 byte5 = null;
605 }
606
607
608 char1 = this.base32mapIndex[byte1 >> 3];
609 char2 = char3 = char4 = char5 = char6 = char7 = char8 = "=";
610
611 if (byte2 != null) {
612 char2 = this.base32mapIndex[((byte1 & 0x07) << 2) | ((byte2 & 0xc0) >> 6)];
613 char3 = this.base32mapIndex[((byte2 & 0x3e) >> 1)];
614 if (byte3 != null) {
615 char4 = this.base32mapIndex[((byte2 & 0x01) << 4) | ((byte3 & 0xf0) >> 4)];
616 if (byte4 != null) {
617 char5 = this.base32mapIndex[((byte3 & 0x0f) << 1) | ((byte4 & 0x80) >> 7)];
618 char6 = this.base32mapIndex[(byte4 & 0x7c) >> 2];
619 if (byte5 != null) {
620 char7 = this.base32mapIndex[((byte4 & 0x03) << 3) | ((byte5 & 0xe0) >> 5)];
621 char8 = this.base32mapIndex[(byte5 & 0x1f)];
622 } else {
623 char7 = this.base32mapIndex[(byte4 & 0x03) << 3];
624 }
625 } else {
626 char5 = this.base32mapIndex[(byte3 & 0x0f) << 1];
627 }
628
629 } else {
630 char4 = this.base32mapIndex[(byte2 & 0x01) << 4];
631 }
632 } else {
633 char2 = this.base32mapIndex[(byte1 & 0x07) << 2];
634 }
635
636 result.push(char1 + char2 + char3 + char4 + char5 + char6 + char7 + char8);
637 i += 5;
638 }
639
640 return result.join("");
641 },
642
643 //-------------------------------------------------------------------------
644
645 'toBinaryString': function () {
646 vari, c;
647 var result;
648
649 result = '';
650
651 c = this.length();
652 for (i=0; i<c; i++) {
653 result += String.fromCharCode(this.byteAtIndex(i));
654 }
655
656 return result;
657 },
658
659
660 //-------------------------------------------------------------------------
661
662 'split': function(aStartingIndex, anEndingIndex) {
663 throw Clipperz.Base.exception.AbstractMethod;
664 },
665
666 //-------------------------------------------------------------------------
667
668 'increment': function() {
669 var i;
670 var done;
671
672 done = false;
673 i = this.length() - 1;
674
675 while ((i>=0) && (done == false)) {
676 var currentByteValue;
677
678 currentByteValue = this.byteAtIndex(i);
679
680 if (currentByteValue == 0xff) {
681 this.setByteAtIndex(0, i);
682 if (i>= 0) {
683 i --;
684 } else {
685 done = true;
686 }
687 } else {
688 this.setByteAtIndex(currentByteValue + 1, i);
689 done = true;
690 }
691 }
692 },
693
694 //-------------------------------------------------------------------------
695
696 'arrayValues': function() {
697 throw Clipperz.Base.exception.AbstractMethod;
698 },
699
700 //-------------------------------------------------------------------------
701 __syntaxFix__: "syntax fix"
702
703});
704
705//=============================================================================
706//
707 //Clipperz.ByteArray_hex
708//
709//=============================================================================
710/*
711Clipperz.ByteArray_hex = function (args) {
712 this._value = "";
713
714 if (typeof(args) != 'undefined') {
715 if (args.constructor == Array) {
716 this.appendBytes(args);
717 } else if (args.constructor == String) {
718 if (args.indexOf("0x") == 0) {
719 varvalue;
720
721 value = args.substring(2).toLowerCase();
722 if (/[0123456789abcdef]* /.test(value)) { the space in the regexp shoud be removed if the code is activate
723 if ((value.length % 2) == 0) {
724 this._value = value;
725 } else {
726 this._value = "0" + value;
727 }
728 } else {
729MochiKit.Logging.logError("Clipperz.ByteArray should be inizialized with an hex string.");
730 throw Clipperz.ByteArray.exception.InvalidValue;
731 }
732 } else {
733 varvalue;
734 vari,c;
735
736 c = args.length;
737 value = new Array(c);
738 for (i=0; i<c; i++) {
739 value.push(Clipperz.ByteArray.unicodeToUtf8HexString(args.charCodeAt(i)));
740 }
741
742 this._value = value.join("");
743 }
744 } else {
745 this.appendBytes(MochiKit.Base.extend(null, arguments));
746 }
747 }
748 return this;
749}
750
751Clipperz.ByteArray_hex.prototype = MochiKit.Base.update(new Clipperz.ByteArray_abstract(), {
752
753 //-------------------------------------------------------------------------
754
755 'toString': function() {
756 return "Clipperz.ByteArray_hex";
757 },
758
759 //-------------------------------------------------------------------------
760
761 'clone': function() {
762 var result;
763
764 result = this.newInstance();
765 result._value = this._value;
766
767 return result;
768 },
769
770 //-------------------------------------------------------------------------
771
772 'newInstance': function() {
773 return new Clipperz.ByteArray_hex();
774 },
775
776 //-------------------------------------------------------------------------
777
778 'reset': function() {
779 this._value = "";
780 },
781
782 //-------------------------------------------------------------------------
783
784 'length': function() {
785 return (this._value.length / 2);
786 },
787
788 //-------------------------------------------------------------------------
789
790 'appendBlock': function(aBlock) {
791 this._value = this._value += aBlock.toHexString().substring(2);
792
793 return this;
794 },
795
796 //-------------------------------------------------------------------------
797
798 'appendByte': function(aValue) {
799 if (aValue != null) {
800 this.checkByteValue(aValue);
801 this._value += Clipperz.ByteArray.byteToHex(aValue);
802 }
803
804 return this;
805 },
806
807 //-------------------------------------------------------------------------
808
809 'byteAtIndex': function(anIndex) {
810 return parseInt(this._value.substr(anIndex*2, 2), 16);
811 },
812
813 'setByteAtIndex': function(aValue, anIndex) {
814 varmissingBytes;
815
816 this.checkByteValue(aValue);
817
818 missingBytes = anIndex - this.length();
819
820 if (missingBytes < 0) {
821 varcurrentValue;
822 varfirstCutIndex;
823 var secondCutIndex;
824
825 firstCutIndex = anIndex * 2;
826 secondCutIndex = firstCutIndex + 2;
827 currentValue = this._value;
828 this._value =currentValue.substring(0, firstCutIndex) +
829 Clipperz.ByteArray.byteToHex(aValue) +
830 currentValue.substring(secondCutIndex);
831 } else if (missingBytes == 0) {
832 this.appendByte(aValue);
833 } else {
834 var i,c;
835
836 c = missingBytes;
837 for (i=0; i<c; i++) {
838 this.appendByte(0);
839 }
840
841 this.appendByte(aValue);
842 }
843 },
844
845 //-------------------------------------------------------------------------
846
847 'toHexString': function() {
848 return "0x" + this._value;
849 },
850
851 //-------------------------------------------------------------------------
852
853 'split': function(aStartingIndex, anEndingIndex) {
854 var result;
855 varstartingIndex;
856 var endingIndex;
857
858 result = this.newInstance();
859
860 startingIndex = aStartingIndex * 2;
861 if (typeof(anEndingIndex) != 'undefined') {
862 endingIndex = anEndingIndex * 2;
863 result._value = this._value.substring(startingIndex, endingIndex);
864 } else {
865 result._value = this._value.substring(startingIndex);
866 }
867
868 return result;
869 },
870
871 //-------------------------------------------------------------------------
872
873 'arrayValues': function() {
874 var result;
875 var i,c;
876
877 c = this.length();
878
879 result = new Array(c);
880 for (i=0; i<c; i++) {
881 result[i] = this.byteAtIndex(i);
882 }
883
884 return result;
885 },
886
887 //-------------------------------------------------------------------------
888 __syntaxFix__: "syntax fix"
889});
890*/
891
892//=============================================================================
893//
894 //Clipperz.ByteArray_array
895//
896//=============================================================================
897
898Clipperz.ByteArray_array = function (args) {
899 if (typeof(args) != 'undefined') {
900 if (args.constructor == Array) {
901 this._value = args.slice(0);
902 } else if (args.constructor == String) {
903 var result;
904 varvalue;
905 var i, c;
906
907 if (args.indexOf("0x") == 0) {
908
909 value = args.substring(2).toLowerCase();
910 if (/[0123456789abcdef]*/.test(value)) {
911 if ((value.length % 2) != 0) {
912 value = "0" + value;
913 }
914 } else {
915MochiKit.Logging.logError("Clipperz.ByteArray should be inizialized with an hex string.");
916 throw Clipperz.ByteArray.exception.InvalidValue;
917 }
918
919 c = value.length / 2
920 result = new Array(c);
921 for (i=0; i<c; i++) {
922 result[i] = parseInt(value.substr(i*2, 2), 16);
923 }
924
925 } else {
926 var unicode;
927 result = [];
928 c = args.length;
929 for (i=0; i<c; i++) {
930 // Clipperz.ByteArray.pushUtf8BytesOfUnicodeChar(result, args.charCodeAt(i));
931
932 unicode = args.charCodeAt(i);
933 if (unicode <= 0x7f) { //0x00000000 - 0x0000007f -> 0xxxxxxx
934 result.push(unicode);
935 // } else if ((unicode >= 0x80) && (unicode <= 0x7ff)) { //0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
936 } else if (unicode <= 0x7ff) { //0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
937 result.push((unicode >> 6) | 0xc0);
938 result.push((unicode & 0x3F) | 0x80);
939 // } else if ((unicode >= 0x0800) && (unicode <= 0xffff)) { //0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
940 } else if (unicode <= 0xffff) { //0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
941 result.push((unicode >> 12) | 0xe0);
942 result.push(((unicode >> 6) & 0x3f) | 0x80);
943 result.push((unicode & 0x3f) | 0x80);
944 } else { //0x00010000 - 0x001fffff -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
945 result.push((unicode >> 18) | 0xf0);
946 result.push(((unicode >> 12) & 0x3f) | 0x80);
947 result.push(((unicode >> 6) & 0x3f) | 0x80);
948 result.push((unicode & 0x3f) | 0x80);
949 }
950 }
951 }
952
953
954 this._value = result;
955 } else {
956 this._value = [];
957 this.appendBytes(MochiKit.Base.extend(null, arguments));
958 }
959 } else {
960 this._value = [];
961 }
962
963 return this;
964}
965
966Clipperz.ByteArray_array.prototype = MochiKit.Base.update(new Clipperz.ByteArray_abstract(), {
967
968 //-------------------------------------------------------------------------
969
970 'toString': function() {
971 return "Clipperz.ByteArray_array";
972 },
973
974 //-------------------------------------------------------------------------
975
976 'clone': function() {
977 var result;
978
979 result = this.newInstance();
980 result.appendBytes(this._value);
981
982 return result;
983 },
984
985 //-------------------------------------------------------------------------
986
987 'newInstance': function() {
988 return new Clipperz.ByteArray_array();
989 },
990
991 //-------------------------------------------------------------------------
992
993 'reset': function() {
994 this._value = [];
995 },
996
997 //-------------------------------------------------------------------------
998
999 'length': function() {
1000 return (this._value.length);
1001 },
1002
1003 //-------------------------------------------------------------------------
1004
1005 'appendBlock': function(aBlock) {
1006 MochiKit.Base.extend(this._value, aBlock._value);
1007
1008 return this;
1009 },
1010
1011 //-------------------------------------------------------------------------
1012
1013 'appendByte': function(aValue) {
1014 if (aValue != null) {
1015 this.checkByteValue(aValue);
1016 this._value.push(aValue);
1017 }
1018
1019 return this;
1020 },
1021
1022 //-------------------------------------------------------------------------
1023
1024 'byteAtIndex': function(anIndex) {
1025 return this._value[anIndex];
1026 },
1027
1028 'setByteAtIndex': function(aValue, anIndex) {
1029 varmissingBytes;
1030
1031 this.checkByteValue(aValue);
1032
1033 missingBytes = anIndex - this.length();
1034
1035 if (missingBytes < 0) {
1036 this._value[anIndex] = aValue;
1037 } else if (missingBytes == 0) {
1038 this._value.push(aValue);
1039 } else {
1040 var i,c;
1041
1042 c = missingBytes;
1043 for (i=0; i<c; i++) {
1044 this._value.push(0);
1045 }
1046
1047 this._value.push(aValue);
1048 }
1049 },
1050
1051 //-------------------------------------------------------------------------
1052
1053 'toHexString': function() {
1054 var result;
1055 var i, c;
1056
1057 result = "0x";
1058 c = this.length();
1059 for (i=0; i<c; i++) {
1060 result += Clipperz.ByteArray.byteToHex(this._value[i]);
1061 }
1062
1063 return result;
1064 },
1065
1066 //-------------------------------------------------------------------------
1067
1068 'split': function(aStartingIndex, anEndingIndex) {
1069 var result;
1070
1071 result = this.newInstance();
1072 result._value = this._value.slice(aStartingIndex, anEndingIndex ? anEndingIndex : this.length());
1073
1074 return result;
1075 },
1076
1077 //-------------------------------------------------------------------------
1078
1079 'arrayValues': function() {
1080 return this._value.slice(0);
1081 },
1082
1083 //-------------------------------------------------------------------------
1084 __syntaxFix__: "syntax fix"
1085});
1086
1087
1088
1089
1090
1091//=============================================================================
1092//
1093 //Clipperz.ByteArray_string
1094//
1095//=============================================================================
1096/*
1097Clipperz.ByteArray_string = function (args) {
1098 this._value = "";
1099
1100 if (typeof(args) != 'undefined') {
1101 if (args.constructor == Array) {
1102 this.appendBytes(args);
1103 } else if (args.constructor == String) {
1104 var result;
1105 varvalue;
1106 var i, c;
1107
1108 if (args.indexOf("0x") == 0) {
1109
1110 value = args.substring(2).toLowerCase();
1111 if (/[0123456789abcdef]* /.test(value)) { the space in the regexp shoud be removed if the code is activated
1112 if ((value.length % 2) != 0) {
1113 value = "0" + value;
1114 }
1115 } else {
1116MochiKit.Logging.logError("Clipperz.ByteArray should be inizialized with an hex string.");
1117 throw Clipperz.ByteArray.exception.InvalidValue;
1118 }
1119 } else {
1120 value = "";
1121 c = args.length;
1122 for (i=0; i<c; i++) {
1123 value += Clipperz.ByteArray.unicodeToUtf8HexString(args.charCodeAt(i));
1124 }
1125 }
1126
1127 c = value.length / 2
1128 for (i=0; i<c; i++) {
1129 this.appendByte(parseInt(value.substr(i*2, 2), 16));
1130 }
1131 } else {
1132 this.appendBytes(MochiKit.Base.extend(null, arguments));
1133 }
1134 }
1135
1136 return this;
1137}
1138
1139Clipperz.ByteArray_string.prototype = MochiKit.Base.update(new Clipperz.ByteArray_abstract(), {
1140
1141 //-------------------------------------------------------------------------
1142
1143 'toString': function() {
1144 return "Clipperz.ByteArray_string";
1145 },
1146
1147 //-------------------------------------------------------------------------
1148
1149 'clone': function() {
1150 var result;
1151
1152 result = this.newInstance();
1153 result._value = this._value;
1154
1155 return result;
1156 },
1157
1158 //-------------------------------------------------------------------------
1159
1160 'newInstance': function() {
1161 return new Clipperz.ByteArray_string();
1162 },
1163
1164 //-------------------------------------------------------------------------
1165
1166 'reset': function() {
1167 this._value = "";
1168 },
1169
1170 //-------------------------------------------------------------------------
1171
1172 'length': function() {
1173 return (this._value.length);
1174 },
1175
1176 //-------------------------------------------------------------------------
1177
1178 'appendBlock': function(aBlock) {
1179 this._value += aBlock._value;
1180
1181 return this;
1182 },
1183
1184 //-------------------------------------------------------------------------
1185
1186 'appendByte': function(aValue) {
1187 if (aValue != null) {
1188 this.checkByteValue(aValue);
1189 this._value += String.fromCharCode(aValue);
1190 }
1191
1192 return this;
1193 },
1194
1195 //-------------------------------------------------------------------------
1196
1197 'byteAtIndex': function(anIndex) {
1198 return this._value.charCodeAt(anIndex);
1199 },
1200
1201 'setByteAtIndex': function(aValue, anIndex) {
1202 varmissingBytes;
1203
1204 this.checkByteValue(aValue);
1205
1206 missingBytes = anIndex - this.length();
1207
1208 if (missingBytes < 0) {
1209 this._value = this._value.substring(0, anIndex) + String.fromCharCode(aValue) + this._value.substring(anIndex + 1);
1210 } else if (missingBytes == 0) {
1211 this.appendByte(aValue);
1212 } else {
1213 var i,c;
1214
1215 c = missingBytes;
1216 for (i=0; i<c; i++) {
1217 this.appendByte(0);
1218 }
1219
1220 this.appendByte(aValue);
1221 }
1222 },
1223
1224 //-------------------------------------------------------------------------
1225
1226 'toHexString': function() {
1227 var result;
1228 var i, c;
1229
1230 result = "0x";
1231 c = this.length();
1232 for (i=0; i<c; i++) {
1233 result += Clipperz.ByteArray.byteToHex(this.byteAtIndex(i));
1234 }
1235
1236 return result;
1237 },
1238
1239 //-------------------------------------------------------------------------
1240
1241 'split': function(aStartingIndex, anEndingIndex) {
1242 var result;
1243 result = this.newInstance();
1244 result._value = this._value.substring(aStartingIndex, anEndingIndex ? anEndingIndex : this.length());
1245
1246 return result;
1247 },
1248
1249 //-------------------------------------------------------------------------
1250
1251 'arrayValues': function() {
1252 var result;
1253 var i,c;
1254
1255 c = this.length();
1256
1257 result = new Array(c);
1258 for (i=0; i<c; i++) {
1259 result[i] = this.byteAtIndex(i);
1260 }
1261
1262 return result;
1263 },
1264
1265 //-------------------------------------------------------------------------
1266 __syntaxFix__: "syntax fix"
1267});
1268*/
1269
1270//=============================================================================
1271//
1272 //Clipperz.ByteArray
1273//
1274//=============================================================================
1275
1276Clipperz.ByteArray = Clipperz.ByteArray_array;
1277//Clipperz.ByteArray = Clipperz.ByteArray_string;
1278//Clipperz.ByteArray = Clipperz.ByteArray_hex;
1279
1280//#############################################################################
1281
1282Clipperz.ByteArray.byteToHex = function(aByte) {
1283 return ((aByte < 16) ? "0" : "") + aByte.toString(16);
1284}
1285
1286
1287Clipperz.ByteArray.unicodeToUtf8HexString = function(aUnicode) {
1288 var result;
1289 varself;
1290
1291 self = Clipperz.ByteArray;
1292
1293 if (aUnicode <= 0x7f) { //0x00000000 - 0x0000007f -> 0xxxxxxx
1294 result = self.byteToHex(aUnicode);
1295 // } else if ((aUnicode >= 0x80) && (aUnicode <= 0x7ff)) { //0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
1296 } else if (aUnicode <= 0x7ff) { //0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
1297 result = self.byteToHex((aUnicode >> 6) | 0xc0);
1298 result += self.byteToHex((aUnicode & 0x3F) | 0x80);
1299 // } else if ((aUnicode >= 0x0800) && (aUnicode <= 0xffff)) { //0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
1300 } else if (aUnicode <= 0xffff) { //0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
1301 result = self.byteToHex((aUnicode >> 12) | 0xe0);
1302 result += self.byteToHex(((aUnicode >> 6) & 0x3f) | 0x80);
1303 result += self.byteToHex((aUnicode & 0x3f) | 0x80);
1304 } else { //0x00010000 - 0x001fffff -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
1305 result = self.byteToHex((aUnicode >> 18) | 0xf0);
1306 result += self.byteToHex(((aUnicode >> 12) & 0x3f) | 0x80);
1307 result += self.byteToHex(((aUnicode >> 6) & 0x3f) | 0x80);
1308 result += self.byteToHex((aUnicode & 0x3f) | 0x80);
1309 }
1310
1311 return result;
1312}
1313
1314Clipperz.ByteArray.pushUtf8BytesOfUnicodeChar = function(anArray, aUnicode) {
1315 varself;
1316
1317 self = Clipperz.ByteArray;
1318
1319 if (aUnicode <= 0x7f) { //0x00000000 - 0x0000007f -> 0xxxxxxx
1320 anArray.push(aUnicode);
1321 // } else if ((aUnicode >= 0x80) && (aUnicode <= 0x7ff)) { //0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
1322 } else if (aUnicode <= 0x7ff) { //0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
1323 anArray.push((aUnicode >> 6) | 0xc0);
1324 anArray.push((aUnicode & 0x3F) | 0x80);
1325 // } else if ((aUnicode >= 0x0800) && (aUnicode <= 0xffff)) { //0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
1326 } else if (aUnicode <= 0xffff) { //0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
1327 anArray.push((aUnicode >> 12) | 0xe0);
1328 anArray.push(((aUnicode >> 6) & 0x3f) | 0x80);
1329 anArray.push((aUnicode & 0x3f) | 0x80);
1330 } else { //0x00010000 - 0x001fffff -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
1331 anArray.push((aUnicode >> 18) | 0xf0);
1332 anArray.push(((aUnicode >> 12) & 0x3f) | 0x80);
1333 anArray.push(((aUnicode >> 6) & 0x3f) | 0x80);
1334 anArray.push((aUnicode & 0x3f) | 0x80);
1335 }
1336}
1337
1338Clipperz.ByteArray.prefixMatchingBits = function (aValue, bValue) {
1339 varresult;
1340 var i,c;
1341
1342 result = 0;
1343
1344 c = Math.min(aValue.length(), bValue.length());
1345 i = 0;
1346 while (i<c && (aValue.byteAtIndex(i) == bValue.byteAtIndex(i))) {
1347 result += 8;
1348 i++;
1349 }
1350
1351 if (i<c) {
1352 varxorValue;
1353
1354 xorValue = (aValue.byteAtIndex(i) ^ bValue.byteAtIndex(i));
1355
1356 if (xorValue >= 128) {
1357 result += 0;
1358 } else if (xorValue >= 64) {
1359 result += 1;
1360 } else if (xorValue >= 32) {
1361 result += 2;
1362 } else if (xorValue >= 16) {
1363 result += 3;
1364 } else if (xorValue >= 8) {
1365 result += 4;
1366 } else if (xorValue >= 4) {
1367 result += 5;
1368 } else if (xorValue >= 2) {
1369 result += 6;
1370 } else if (xorValue >= 1) {
1371 result += 7;
1372 }
1373 }
1374
1375 return result;
1376};
1377
1378Clipperz.ByteArray.exception = {
1379 InvalidValue: new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.InvalidValue")
1380};
1381
1382//#############################################################################
1383
1384Clipperz.ByteArrayIterator = function(args) {
1385 args = args || {};
1386
1387 this._byteArray = args.byteArray;
1388 this._blockSize = args.blockSize;
1389 this._finalPadding = args.finalPadding || false;
1390
1391 this._currentPosition = 0;
1392
1393 return this;
1394}
1395
1396Clipperz.ByteArrayIterator.prototype = MochiKit.Base.update(null, {
1397
1398 //-------------------------------------------------------------------------
1399
1400 'toString': function() {
1401 return "Clipperz.ByteArrayIterator";
1402 },
1403
1404 //-------------------------------------------------------------------------
1405
1406 'blockSize': function() {
1407 var result;
1408
1409 result = this._blockSize;
1410
1411 return result;
1412 },
1413
1414 //-------------------------------------------------------------------------
1415
1416 'currentPosition': function() {
1417 var result;
1418
1419 result = this._currentPosition;
1420
1421 return result;
1422 },
1423
1424 //-------------------------------------------------------------------------
1425
1426 'byteArray': function() {
1427 var result;
1428
1429 result = this._byteArray;
1430
1431 return result;
1432 },
1433
1434 //-------------------------------------------------------------------------
1435
1436 'finalPadding': function() {
1437 var result;
1438
1439 result = this._finalPadding;
1440
1441 return result;
1442 },
1443
1444 //-------------------------------------------------------------------------
1445
1446 'nextBlock': function() {
1447 var result;
1448 var currentPosition;
1449 varbyteArrayLength;
1450
1451 currentPosition = this._currentPosition;
1452 byteArrayLength = this.byteArray().length();
1453
1454 if (currentPosition < byteArrayLength) {
1455 var i,c;
1456
1457 c = this.blockSize();
1458 result = new Array(c);
1459 for (i=0; i<c; i++) {
1460 if (currentPosition < byteArrayLength) {
1461 result[i] = this.byteArray().byteAtIndex(currentPosition);
1462 currentPosition++;
1463 } else if (this.finalPadding() == true) {
1464 result[i] = 0;
1465 }
1466 }
1467
1468 this._currentPosition = currentPosition;
1469 } else {
1470 result = null;
1471 }
1472
1473 return result;
1474 },
1475
1476 //-------------------------------------------------------------------------
1477
1478 'nextBlockArray': function() {
1479 var result;
1480 var nextBlock;
1481
1482 nextBlock = this.nextBlock();
1483
1484 if (nextBlock != null) {
1485 result = new Clipperz.ByteArray(nextBlock);
1486 } else {
1487 result = null;
1488 }
1489
1490 return result;
1491 },
1492
1493 //-----------------------------------------------------------------------------
1494 __syntaxFix__: "syntax fix"
1495
1496});
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Curve.js b/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Curve.js
deleted file mode 100644
index 9c61bab..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Curve.js
+++ b/dev/null
@@ -1,545 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24//try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 //throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
26//}
27if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
28if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
29
30Clipperz.Crypto.ECC.BinaryField.Curve = function(args) {
31 args = args || {};
32
33 this._modulus = args.modulus;
34
35 this._a = args.a;
36 this._b = args.b;
37 this._G = args.G;
38 this._r = args.r;
39 this._h = args.h;
40
41 this._finiteField = null;
42
43 return this;
44}
45
46Clipperz.Crypto.ECC.BinaryField.Curve.prototype = MochiKit.Base.update(null, {
47
48 'asString': function() {
49 return "Clipperz.Crypto.ECC.BinaryField.Curve";
50 },
51
52 //-----------------------------------------------------------------------------
53
54 'modulus': function() {
55 return this._modulus;
56 },
57
58 'a': function() {
59 return this._a;
60 },
61
62 'b': function() {
63 return this._b;
64 },
65
66 'G': function() {
67 return this._G;
68 },
69
70 'r': function() {
71 return this._r;
72 },
73
74 'h': function() {
75 return this._h;
76 },
77
78 //-----------------------------------------------------------------------------
79
80 'finiteField': function() {
81 if (this._finiteField == null) {
82 this._finiteField = new Clipperz.Crypto.ECC.BinaryField.FiniteField({modulus:this.modulus()})
83 }
84
85 return this._finiteField;
86 },
87
88 //-----------------------------------------------------------------------------
89
90 'negate': function(aPointA) {
91 var result;
92
93 result = new Clipperz.Crypto.ECC.Point({x:aPointA.x(), y:this.finiteField().add(aPointA.y(), aPointA.x())})
94
95 return result;
96 },
97
98 //-----------------------------------------------------------------------------
99
100 'add': function(aPointA, aPointB) {
101 var result;
102
103//console.log(">>> ECC.BinaryField.Curve.add");
104 if (aPointA.isZero()) {
105//console.log("--- pointA == zero");
106 result = aPointB;
107 } else if (aPointB.isZero()) {
108//console.log("--- pointB == zero");
109 result = aPointA;
110 } else if ((aPointA.x().compare(aPointB.x()) == 0) && ((aPointA.y().compare(aPointB.y()) != 0) || aPointB.x().isZero())) {
111//console.log("compare A.x - B.x: ", aPointA.x().compare(aPointB.x()));
112//console.log("compare A.y - B.y: ", (aPointA.y().compare(aPointB.y()) != 0));
113//console.log("compare B.x.isZero(): ", aPointB.x().isZero());
114
115//console.log("--- result = zero");
116 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
117 } else {
118//console.log("--- result = ELSE");
119 varf2m;
120 var x, y;
121 var lambda;
122 var aX, aY, bX, bY;
123
124 aX = aPointA.x()._value;
125 aY = aPointA.y()._value;
126 bX = aPointB.x()._value;
127 bY = aPointB.y()._value;
128
129 f2m = this.finiteField();
130
131 if (aPointA.x().compare(aPointB.x()) != 0) {
132//console.log(" a.x != b.x");
133 lambda =f2m._fastMultiply(
134 f2m._add(aY, bY),
135 f2m._inverse(f2m._add(aX, bX))
136 );
137 x = f2m._add(this.a()._value, f2m._square(lambda));
138 f2m._overwriteAdd(x, lambda);
139 f2m._overwriteAdd(x, aX);
140 f2m._overwriteAdd(x, bX);
141 } else {
142//console.log(" a.x == b.x");
143 lambda = f2m._add(bX, f2m._fastMultiply(bY, f2m._inverse(bX)));
144//console.log(" lambda: " + lambda.asString(16));
145 x = f2m._add(this.a()._value, f2m._square(lambda));
146//console.log(" x (step 1): " + x.asString(16));
147 f2m._overwriteAdd(x, lambda);
148//console.log(" x (step 2): " + x.asString(16));
149 }
150
151 y = f2m._fastMultiply(f2m._add(bX, x), lambda);
152//console.log(" y (step 1): " + y.asString(16));
153 f2m._overwriteAdd(y, x);
154//console.log(" y (step 2): " + y.asString(16));
155 f2m._overwriteAdd(y, bY);
156//console.log(" y (step 3): " + y.asString(16));
157
158 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:new Clipperz.Crypto.ECC.BinaryField.Value(x), y:new Clipperz.Crypto.ECC.BinaryField.Value(y)})
159 }
160//console.log("<<< ECC.BinaryField.Curve.add");
161
162 return result;
163 },
164
165 //-----------------------------------------------------------------------------
166
167 'addTwice': function(aPointA) {
168 return this.add(aPointA, aPointA);
169 },
170
171 //-----------------------------------------------------------------------------
172
173 'overwriteAdd': function(aPointA, aPointB) {
174 if (aPointA.isZero()) {
175 // result = aPointB;
176 aPointA._x._value = aPointB._x._value;
177 aPointA._y._value = aPointB._y._value;
178 } else if (aPointB.isZero()) {
179 // result = aPointA;
180 } else if ((aPointA.x().compare(aPointB.x()) == 0) && ((aPointA.y().compare(aPointB.y()) != 0) || aPointB.x().isZero())) {
181 // result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
182 aPointA._x = Clipperz.Crypto.ECC.BinaryField.Value.O;
183 aPointA._y = Clipperz.Crypto.ECC.BinaryField.Value.O;
184 } else {
185 varf2m;
186 var x, y;
187 var lambda;
188 var aX, aY, bX, bY;
189
190 aX = aPointA.x()._value;
191 aY = aPointA.y()._value;
192 bX = aPointB.x()._value;
193 bY = aPointB.y()._value;
194
195 f2m = this.finiteField();
196
197 if (aPointA.x().compare(aPointB.x()) != 0) {
198//console.log(" a.x != b.x");
199 lambda =f2m._fastMultiply(
200 f2m._add(aY, bY),
201 f2m._inverse(f2m._add(aX, bX))
202 );
203 x = f2m._add(this.a()._value, f2m._square(lambda));
204 f2m._overwriteAdd(x, lambda);
205 f2m._overwriteAdd(x, aX);
206 f2m._overwriteAdd(x, bX);
207 } else {
208//console.log(" a.x == b.x");
209 lambda = f2m._add(bX, f2m._fastMultiply(bY, f2m._inverse(bX)));
210//console.log(" lambda: " + lambda.asString(16));
211 x = f2m._add(this.a()._value, f2m._square(lambda));
212//console.log(" x (step 1): " + x.asString(16));
213 f2m._overwriteAdd(x, lambda);
214//console.log(" x (step 2): " + x.asString(16));
215 }
216
217 y = f2m._fastMultiply(f2m._add(bX, x), lambda);
218//console.log(" y (step 1): " + y.asString(16));
219 f2m._overwriteAdd(y, x);
220//console.log(" y (step 2): " + y.asString(16));
221 f2m._overwriteAdd(y, bY);
222//console.log(" y (step 3): " + y.asString(16));
223
224 // result = new Clipperz.Crypto.ECC.BinaryField.Point({x:new Clipperz.Crypto.ECC.BinaryField.Value(x), y:new Clipperz.Crypto.ECC.BinaryField.Value(y)})
225 aPointA._x._value = x;
226 aPointA._y._value = y;
227
228 }
229//console.log("<<< ECC.BinaryField.Curve.add");
230
231 return result;
232 },
233
234 //-----------------------------------------------------------------------------
235
236 'multiply': function(aValue, aPoint) {
237 var result;
238
239//console.profile();
240 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
241
242 if (aValue.isZero() == false) {
243 var k, Q;
244 var i;
245 var countIndex; countIndex = 0;
246
247 if (aValue.compare(Clipperz.Crypto.ECC.BinaryField.Value.O) > 0) {
248 k = aValue;
249 Q = aPoint;
250 } else {
251MochiKit.Logging.logError("The Clipperz.Crypto.ECC.BinaryFields.Value does not work with negative values!!!!");
252 k = aValue.negate();
253 Q = this.negate(aPoint);
254 }
255
256//console.log("k: " + k.toString(16));
257//console.log("k.bitSize: " + k.bitSize());
258 for (i=k.bitSize()-1; i>=0; i--) {
259 result = this.add(result, result);
260 // this.overwriteAdd(result, result);
261 if (k.isBitSet(i)) {
262 result = this.add(result, Q);
263 // this.overwriteAdd(result, Q);
264 }
265
266 // if (countIndex==100) {console.log("multiply.break"); break;} else countIndex++;
267 }
268 }
269//console.profileEnd();
270
271 return result;
272 },
273
274 //-----------------------------------------------------------------------------
275
276 'deferredMultiply': function(aValue, aPoint) {
277 var deferredResult;
278 var result;
279
280MochiKit.Logging.logDebug(">>> deferredMultiply - value: " + aValue + ", point: " + aPoint);
281//console.profile("ECC.Curve.multiply");
282 deferredResult = new MochiKit.Async.Deferred();
283//deferredResult.addCallback(function(res) {console.profile("ECC.Curve.deferredMultiply"); return res;} );
284//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 1: " + res); return res;});
285
286 result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
287//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 2: " + res); return res;});
288
289 if (aValue.isZero() == false) {
290 var k, Q;
291 var i;
292 var countIndex; countIndex = 0;
293
294 if (aValue.compare(Clipperz.Crypto.ECC.BinaryField.Value.O) > 0) {
295 k = aValue;
296 Q = aPoint;
297 } else {
298MochiKit.Logging.logError("The Clipperz.Crypto.ECC.BinaryFields.Value does not work with negative values!!!!");
299 k = aValue.negate();
300 Q = this.negate(aPoint);
301 }
302
303//console.log("k: " + k.toString(16));
304//console.log("k.bitSize: " + k.bitSize());
305
306//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 3: " + res); return res;});
307 for (i=k.bitSize()-1; i>=0; i--) {
308//MochiKit.Logging.logDebug("====> " + i);
309//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 4 > i = " + i + ": " + res); return res;});
310 deferredResult.addMethod(this, "addTwice");
311 //# result = this.add(result, result);
312 // this.overwriteAdd(result, result);
313 if (k.isBitSet(i)) {
314 deferredResult.addMethod(this, "add", Q);
315 //# result = this.add(result, Q);
316 // this.overwriteAdd(result, Q);
317 }
318 if (i%20 == 0) {deferredResult.addCallback(MochiKit.Async.wait, 0.1);}
319
320 // if (countIndex==100) {console.log("multiply.break"); break;} else countIndex++;
321//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 4 < i = " + i + ": " + res); return res;});
322 }
323//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 4: " + res); return res;});
324 }
325//#console.profileEnd();
326//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 5: " + res); return res;});
327//deferredResult.addBoth(function(res) {console.profileEnd(); return res;});
328//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 6: " + res); return res;});
329 deferredResult.callback(result);
330
331 //# return result;
332 return deferredResult;
333 },
334
335 //-----------------------------------------------------------------------------
336 __syntaxFix__: "syntax fix"
337});
338
339
340//#############################################################################
341
342Clipperz.Crypto.ECC.StandardCurves = {};
343
344MochiKit.Base.update(Clipperz.Crypto.ECC.StandardCurves, {
345/*
346 '_K571': null,
347 'K571': function() {
348 if (Clipperz.Crypto.ECC.StandardCurves._K571 == null) {
349 Clipperz.Crypto.ECC.StandardCurves._K571 = new Clipperz.Crypto.ECC.BinaryField.Curve({
350 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),
351 a: new Clipperz.Crypto.ECC.BinaryField.Value('0', 16),
352 b: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
353 G: new Clipperz.Crypto.ECC.BinaryField.Point({
354 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),
355 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)
356 }),
357 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),
358 h: new Clipperz.Crypto.ECC.BinaryField.Value('4', 16)
359 });
360 }
361
362 return Clipperz.Crypto.ECC.StandardCurves._K571;
363 },
364
365
366
367 '_K283': null,
368 'K283': function() { //f(z) = z^283 + z^12 + z^7 + z^5 + 1
369 if (Clipperz.Crypto.ECC.StandardCurves._K283 == null) {
370 Clipperz.Crypto.ECC.StandardCurves._K283 = new Clipperz.Crypto.ECC.BinaryField.Curve({
371 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
372 a: new Clipperz.Crypto.ECC.BinaryField.Value('0', 16),
373 b: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
374 G: new Clipperz.Crypto.ECC.BinaryField.Point({
375 x: new Clipperz.Crypto.ECC.BinaryField.Value('0503213f 78ca4488 3f1a3b81 62f188e5 53cd265f 23c1567a 16876913 b0c2ac24 58492836', 16),
376 y: new Clipperz.Crypto.ECC.BinaryField.Value('01ccda38 0f1c9e31 8d90f95d 07e5426f e87e45c0 e8184698 e4596236 4e341161 77dd2259', 16)
377 }),
378 r: new Clipperz.Crypto.ECC.BinaryField.Value('01ffffff ffffffff ffffffff ffffffff ffffe9ae 2ed07577 265dff7f 94451e06 1e163c61', 16),
379 h: new Clipperz.Crypto.ECC.BinaryField.Value('4', 16)
380 });
381 }
382
383 return Clipperz.Crypto.ECC.StandardCurves._K283;
384 },
385*/
386 //-----------------------------------------------------------------------------
387
388 '_B571': null,
389 'B571': function() { //f(z) = z^571 + z^10 + z^5 + z^2 + 1
390 if (Clipperz.Crypto.ECC.StandardCurves._B571 == null) {
391 Clipperz.Crypto.ECC.StandardCurves._B571 = new Clipperz.Crypto.ECC.BinaryField.Curve({
392 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425', 16),
393 a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
394 b: new Clipperz.Crypto.ECC.BinaryField.Value('02f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a', 16),
395 G: new Clipperz.Crypto.ECC.BinaryField.Point({
396 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),
397 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)
398 }),
399 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),
400 h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
401
402 // S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
403 // n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16)
404 });
405
406 //-----------------------------------------------------------------------------
407 //
408 //Guide to Elliptic Curve Cryptography
409 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
410 //- Pag: 56, Alorithm 2.45 (with a typo!!!)
411 //
412 //-----------------------------------------------------------------------------
413 //
414 // http://www.milw0rm.com/papers/136
415 //
416 // -------------------------------------------------------------------------
417 // Polynomial Reduction Algorithm Modulo f571
418 // -------------------------------------------------------------------------
419 //
420 // Input: Polynomial p(x) of degree 1140 or less, stored as
421 // an array of 2T machinewords.
422 // Output: p(x) mod f571(x)
423 //
424 // FOR i = T-1, ..., 0 DO
425 // SET X := P[i+T]
426 // P[i] := P[i] ^ (X<<5) ^ (X<<7) ^ (X<<10) ^ (X<<15)
427 // P[i+1] := P[i+1] ^ (X>>17) ^ (X>>22) ^ (X>>25) ^ (X>>27)
428 //
429 // SET X := P[T-1] >> 27
430 // P[0] := P[0] ^ X ^ (X<<2) ^ (X<<5) ^ (X<<10)
431 // P[T-1] := P[T-1] & 0x07ffffff
432 //
433 // RETURN P[T-1],...,P[0]
434 //
435 // -------------------------------------------------------------------------
436 //
437 Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module;
438 Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module = function(aValue) {
439 varresult;
440
441 if (aValue.bitSize() > 1140) {
442 MochiKit.Logging.logWarning("ECC.StandarCurves.B571.finiteField().module: falling back to default implementation");
443 result = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule(aValue);
444 } else {
445 varC, T;
446 var i;
447
448//console.log(">>> binaryField.finiteField.(improved)module");
449 // C = aValue.value().slice(0);
450 C = aValue._value.slice(0);
451 for (i=35; i>=18; i--) {
452 T = C[i];
453 C[i-18] = (((C[i-18] ^ (T<<5) ^ (T<<7) ^ (T<<10) ^ (T<<15)) & 0xffffffff) >>> 0);
454 C[i-17] = ((C[i-17] ^ (T>>>27) ^ (T>>>25) ^ (T>>>22) ^ (T>>>17)) >>> 0);
455 }
456 T = (C[17] >>> 27);
457 C[0] = ((C[0] ^ T ^ ((T<<2) ^ (T<<5) ^ (T<<10)) & 0xffffffff) >>> 0);
458 C[17] = (C[17] & 0x07ffffff);
459
460 for(i=18; i<=35; i++) {
461 C[i] = 0;
462 }
463
464 result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
465//console.log("<<< binaryField.finiteField.(improved)module");
466 }
467
468 return result;
469 };
470 }
471
472 return Clipperz.Crypto.ECC.StandardCurves._B571;
473 },
474
475 //-----------------------------------------------------------------------------
476
477 '_B283': null,
478 'B283': function() { //f(z) = z^283 + z^12 + z^7 + z^5 + 1
479 if (Clipperz.Crypto.ECC.StandardCurves._B283 == null) {
480 Clipperz.Crypto.ECC.StandardCurves._B283 = new Clipperz.Crypto.ECC.BinaryField.Curve({
481 // modulus: new Clipperz.Crypto.ECC.BinaryField.Value('10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
482 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
483 a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
484 b: new Clipperz.Crypto.ECC.BinaryField.Value('027b680a c8b8596d a5a4af8a 19a0303f ca97fd76 45309fa2 a581485a f6263e31 3b79a2f5', 16),
485 G: new Clipperz.Crypto.ECC.BinaryField.Point({
486 x: new Clipperz.Crypto.ECC.BinaryField.Value('05f93925 8db7dd90 e1934f8c 70b0dfec 2eed25b8 557eac9c 80e2e198 f8cdbecd 86b12053', 16),
487 y: new Clipperz.Crypto.ECC.BinaryField.Value('03676854 fe24141c b98fe6d4 b20d02b4 516ff702 350eddb0 826779c8 13f0df45 be8112f4', 16)
488 }),
489 r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffff ffffffff ffffffff ffffffff ffffef90 399660fc 938a9016 5b042a7c efadb307', 16),
490 h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
491
492 // S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
493 // n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16)
494 });
495
496 //-----------------------------------------------------------------------------
497 //
498 //Guide to Elliptic Curve Cryptography
499 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
500 //- Pag: 56, Alorithm 2.43
501 //
502 //-----------------------------------------------------------------------------
503 Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module;
504 Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module = function(aValue) {
505 varresult;
506
507 if (aValue.bitSize() > 564) {
508 MochiKit.Logging.logWarning("ECC.StandarCurves.B283.finiteField().module: falling back to default implementation");
509 result = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule(aValue);
510 } else {
511 varC, T;
512 var i;
513
514//console.log(">>> binaryField.finiteField.(improved)module");
515 C = aValue._value.slice(0);
516 for (i=17; i>=9; i--) {
517 T = C[i];
518 C[i-9] = (((C[i-9] ^ (T<<5) ^ (T<<10) ^ (T<<12) ^ (T<<17)) & 0xffffffff) >>> 0);
519 C[i-8] = ((C[i-8] ^ (T>>>27) ^ (T>>>22) ^ (T>>>20) ^ (T>>>15)) >>> 0);
520 }
521 T = (C[8] >>> 27);
522 C[0] = ((C[0] ^ T ^ ((T<<5) ^ (T<<7) ^ (T<<12)) & 0xffffffff) >>> 0);
523 C[8] = (C[8] & 0x07ffffff);
524
525 for(i=9; i<=17; i++) {
526 C[i] = 0;
527 }
528
529 result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
530//console.log("<<< binaryField.finiteField.(improved)module");
531 }
532
533 return result;
534 };
535 }
536
537 return Clipperz.Crypto.ECC.StandardCurves._B283;
538 },
539
540 //-----------------------------------------------------------------------------
541 __syntaxFix__: "syntax fix"
542});
543
544//#############################################################################
545
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/FiniteField.js b/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/FiniteField.js
deleted file mode 100644
index 4d1ca67..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/FiniteField.js
+++ b/dev/null
@@ -1,521 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24//try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 //throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
26//}
27if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
28if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
29
30Clipperz.Crypto.ECC.BinaryField.FiniteField = function(args) {
31 args = args || {};
32 this._modulus = args.modulus;
33
34 return this;
35}
36
37Clipperz.Crypto.ECC.BinaryField.FiniteField.prototype = MochiKit.Base.update(null, {
38
39 'asString': function() {
40 return "Clipperz.Crypto.ECC.BinaryField.FiniteField (" + this.modulus().asString() + ")";
41 },
42
43 //-----------------------------------------------------------------------------
44
45 'modulus': function() {
46 return this._modulus;
47 },
48
49 //-----------------------------------------------------------------------------
50
51 '_module': function(aValue) {
52 varresult;
53 var modulusComparison;
54//console.log(">>> binaryField.finiteField.(standard)module");
55
56 modulusComparison = Clipperz.Crypto.ECC.BinaryField.Value._compare(aValue, this.modulus()._value);
57
58 if (modulusComparison < 0) {
59 result = aValue;
60 } else if (modulusComparison == 0) {
61 result = [0];
62 } else {
63 var modulusBitSize;
64 var resultBitSize;
65
66 result = aValue;
67
68 modulusBitSize = this.modulus().bitSize();
69 resultBitSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(result);
70 while (resultBitSize >= modulusBitSize) {
71 Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(result, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(this.modulus()._value, resultBitSize - modulusBitSize));
72 resultBitSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(result);
73 }
74 }
75//console.log("<<< binaryField.finiteField.(standard)module");
76
77 return result;
78 },
79
80 'module': function(aValue) {
81 return new Clipperz.Crypto.ECC.BinaryField.Value(this._module(aValue._value.slice(0)));
82 },
83
84 //-----------------------------------------------------------------------------
85
86 '_add': function(a, b) {
87 return Clipperz.Crypto.ECC.BinaryField.Value._xor(a, b);
88 },
89
90 '_overwriteAdd': function(a, b) {
91 Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(a, b);
92 },
93
94 'add': function(a, b) {
95 return new Clipperz.Crypto.ECC.BinaryField.Value(this._add(a._value, b._value));
96 },
97
98 //-----------------------------------------------------------------------------
99
100 'negate': function(aValue) {
101 return aValue.clone();
102 },
103
104 //-----------------------------------------------------------------------------
105
106 '_multiply': function(a, b) {
107 var result;
108 var valueToXor;
109 var i,c;
110
111 result = [0];
112 valueToXor = b;
113 c = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(a);
114 for (i=0; i<c; i++) {
115 if (Clipperz.Crypto.ECC.BinaryField.Value._isBitSet(a, i) === true) {
116 Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(result, valueToXor);
117 }
118 valueToXor = Clipperz.Crypto.ECC.BinaryField.Value._overwriteShiftLeft(valueToXor, 1);
119 }
120 result = this._module(result);
121
122 return result;
123 },
124
125 'multiply': function(a, b) {
126 return new Clipperz.Crypto.ECC.BinaryField.Value(this._multiply(a._value, b._value));
127 },
128
129 //-----------------------------------------------------------------------------
130
131 '_fastMultiply': function(a, b) {
132 var result;
133 var B;
134 var i,c;
135
136 result = [0];
137 B = b.slice(0); //Is this array copy avoidable?
138 c = 32;
139 for (i=0; i<c; i++) {
140 var ii, cc;
141
142 cc = a.length;
143 for (ii=0; ii<cc; ii++) {
144 if (((a[ii] >>> i) & 0x01) == 1) {
145 Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(result, B, ii);
146 }
147 }
148
149 if (i < (c-1)) {
150 B = Clipperz.Crypto.ECC.BinaryField.Value._overwriteShiftLeft(B, 1);
151 }
152 }
153 result = this._module(result);
154
155 return result;
156 },
157
158 'fastMultiply': function(a, b) {
159 return new Clipperz.Crypto.ECC.BinaryField.Value(this._fastMultiply(a._value, b._value));
160 },
161
162 //-----------------------------------------------------------------------------
163 //
164 //Guide to Elliptic Curve Cryptography
165 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
166 //- Pag: 49, Alorithm 2.34
167 //
168 //-----------------------------------------------------------------------------
169
170 '_square': function(aValue) {
171 var result;
172 var value;
173 var c,i;
174 var precomputedValues;
175
176 value = aValue;
177 result = new Array(value.length * 2);
178 precomputedValues = Clipperz.Crypto.ECC.BinaryField.FiniteField.squarePrecomputedBytes;
179
180 c = value.length;
181 for (i=0; i<c; i++) {
182 result[i*2] = precomputedValues[(value[i] & 0x000000ff)];
183 result[i*2] |= ((precomputedValues[(value[i] & 0x0000ff00) >>> 8]) << 16);
184
185 result[i*2 + 1] = precomputedValues[(value[i] & 0x00ff0000) >>> 16];
186 result[i*2 + 1] |= ((precomputedValues[(value[i] & 0xff000000) >>> 24]) << 16);
187 }
188
189 return this._module(result);
190 },
191
192 'square': function(aValue) {
193 return new Clipperz.Crypto.ECC.BinaryField.Value(this._square(aValue._value));
194 },
195
196 //-----------------------------------------------------------------------------
197
198 '_inverse': function(aValue) {
199 varresult;
200 var b, c;
201 var u, v;
202
203 // b = Clipperz.Crypto.ECC.BinaryField.Value.I._value;
204 b = [1];
205 // c = Clipperz.Crypto.ECC.BinaryField.Value.O._value;
206 c = [0];
207 u = this._module(aValue);
208 v = this.modulus()._value.slice(0);
209
210 while (Clipperz.Crypto.ECC.BinaryField.Value._bitSize(u) > 1) {
211 varbitDifferenceSize;
212
213 bitDifferenceSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(u) - Clipperz.Crypto.ECC.BinaryField.Value._bitSize(v);
214 if (bitDifferenceSize < 0) {
215 var swap;
216
217 swap = u;
218 u = v;
219 v = swap;
220
221 swap = c;
222 c = b;
223 b = swap;
224
225 bitDifferenceSize = -bitDifferenceSize;
226 }
227
228 u = this._add(u, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(v, bitDifferenceSize));
229 b = this._add(b, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(c, bitDifferenceSize));
230 // this._overwriteAdd(u, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(v, bitDifferenceSize));
231 // this._overwriteAdd(b, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(c, bitDifferenceSize));
232 }
233
234 result = this._module(b);
235
236 return result;
237 },
238
239 'inverse': function(aValue) {
240 return new Clipperz.Crypto.ECC.BinaryField.Value(this._inverse(aValue._value));
241 },
242
243 //-----------------------------------------------------------------------------
244 __syntaxFix__: "syntax fix"
245});
246
247
248Clipperz.Crypto.ECC.BinaryField.FiniteField.squarePrecomputedBytes = [
249 0x0000, // 0 = 0000 0000 -> 0000 0000 0000 0000
250 0x0001, // 1 = 0000 0001 -> 0000 0000 0000 0001
251 0x0004, // 2 = 0000 0010 -> 0000 0000 0000 0100
252 0x0005, // 3 = 0000 0011 -> 0000 0000 0000 0101
253 0x0010, // 4 = 0000 0100 -> 0000 0000 0001 0000
254 0x0011, // 5 = 0000 0101 -> 0000 0000 0001 0001
255 0x0014, // 6 = 0000 0110 -> 0000 0000 0001 0100
256 0x0015, // 7 = 0000 0111 -> 0000 0000 0001 0101
257 0x0040, // 8 = 0000 1000 -> 0000 0000 0100 0000
258 0x0041, // 9 = 0000 1001 -> 0000 0000 0100 0001
259 0x0044, // 10 = 0000 1010 -> 0000 0000 0100 0100
260 0x0045, // 11 = 0000 1011 -> 0000 0000 0100 0101
261 0x0050, // 12 = 0000 1100 -> 0000 0000 0101 0000
262 0x0051, // 13 = 0000 1101 -> 0000 0000 0101 0001
263 0x0054, // 14 = 0000 1110 -> 0000 0000 0101 0100
264 0x0055, // 15 = 0000 1111 -> 0000 0000 0101 0101
265
266 0x0100, // 16 = 0001 0000 -> 0000 0001 0000 0000
267 0x0101, // 17 = 0001 0001 -> 0000 0001 0000 0001
268 0x0104, // 18 = 0001 0010 -> 0000 0001 0000 0100
269 0x0105, // 19 = 0001 0011 -> 0000 0001 0000 0101
270 0x0110, // 20 = 0001 0100 -> 0000 0001 0001 0000
271 0x0111, // 21 = 0001 0101 -> 0000 0001 0001 0001
272 0x0114, // 22 = 0001 0110 -> 0000 0001 0001 0100
273 0x0115, // 23 = 0001 0111 -> 0000 0001 0001 0101
274 0x0140, // 24 = 0001 1000 -> 0000 0001 0100 0000
275 0x0141, // 25 = 0001 1001 -> 0000 0001 0100 0001
276 0x0144, // 26 = 0001 1010 -> 0000 0001 0100 0100
277 0x0145, // 27 = 0001 1011 -> 0000 0001 0100 0101
278 0x0150, // 28 = 0001 1100 -> 0000 0001 0101 0000
279 0x0151, // 28 = 0001 1101 -> 0000 0001 0101 0001
280 0x0154, // 30 = 0001 1110 -> 0000 0001 0101 0100
281 0x0155, // 31 = 0001 1111 -> 0000 0001 0101 0101
282
283 0x0400, // 32 = 0010 0000 -> 0000 0100 0000 0000
284 0x0401, // 33 = 0010 0001 -> 0000 0100 0000 0001
285 0x0404, // 34 = 0010 0010 -> 0000 0100 0000 0100
286 0x0405, // 35 = 0010 0011 -> 0000 0100 0000 0101
287 0x0410, // 36 = 0010 0100 -> 0000 0100 0001 0000
288 0x0411, // 37 = 0010 0101 -> 0000 0100 0001 0001
289 0x0414, // 38 = 0010 0110 -> 0000 0100 0001 0100
290 0x0415, // 39 = 0010 0111 -> 0000 0100 0001 0101
291 0x0440, // 40 = 0010 1000 -> 0000 0100 0100 0000
292 0x0441, // 41 = 0010 1001 -> 0000 0100 0100 0001
293 0x0444, // 42 = 0010 1010 -> 0000 0100 0100 0100
294 0x0445, // 43 = 0010 1011 -> 0000 0100 0100 0101
295 0x0450, // 44 = 0010 1100 -> 0000 0100 0101 0000
296 0x0451, // 45 = 0010 1101 -> 0000 0100 0101 0001
297 0x0454, // 46 = 0010 1110 -> 0000 0100 0101 0100
298 0x0455, // 47 = 0010 1111 -> 0000 0100 0101 0101
299
300 0x0500, // 48 = 0011 0000 -> 0000 0101 0000 0000
301 0x0501, // 49 = 0011 0001 -> 0000 0101 0000 0001
302 0x0504, // 50 = 0011 0010 -> 0000 0101 0000 0100
303 0x0505, // 51 = 0011 0011 -> 0000 0101 0000 0101
304 0x0510, // 52 = 0011 0100 -> 0000 0101 0001 0000
305 0x0511, // 53 = 0011 0101 -> 0000 0101 0001 0001
306 0x0514, // 54 = 0011 0110 -> 0000 0101 0001 0100
307 0x0515, // 55 = 0011 0111 -> 0000 0101 0001 0101
308 0x0540, // 56 = 0011 1000 -> 0000 0101 0100 0000
309 0x0541, // 57 = 0011 1001 -> 0000 0101 0100 0001
310 0x0544, // 58 = 0011 1010 -> 0000 0101 0100 0100
311 0x0545, // 59 = 0011 1011 -> 0000 0101 0100 0101
312 0x0550, // 60 = 0011 1100 -> 0000 0101 0101 0000
313 0x0551, // 61 = 0011 1101 -> 0000 0101 0101 0001
314 0x0554, // 62 = 0011 1110 -> 0000 0101 0101 0100
315 0x0555, // 63 = 0011 1111 -> 0000 0101 0101 0101
316
317 0x1000, // 64 = 0100 0000 -> 0001 0000 0000 0000
318 0x1001, // 65 = 0100 0001 -> 0001 0000 0000 0001
319 0x1004, // 66 = 0100 0010 -> 0001 0000 0000 0100
320 0x1005, // 67 = 0100 0011 -> 0001 0000 0000 0101
321 0x1010, // 68 = 0100 0100 -> 0001 0000 0001 0000
322 0x1011, // 69 = 0100 0101 -> 0001 0000 0001 0001
323 0x1014, // 70 = 0100 0110 -> 0001 0000 0001 0100
324 0x1015, // 71 = 0100 0111 -> 0001 0000 0001 0101
325 0x1040, // 72 = 0100 1000 -> 0001 0000 0100 0000
326 0x1041, // 73 = 0100 1001 -> 0001 0000 0100 0001
327 0x1044, // 74 = 0100 1010 -> 0001 0000 0100 0100
328 0x1045, // 75 = 0100 1011 -> 0001 0000 0100 0101
329 0x1050, // 76 = 0100 1100 -> 0001 0000 0101 0000
330 0x1051, // 77 = 0100 1101 -> 0001 0000 0101 0001
331 0x1054, // 78 = 0100 1110 -> 0001 0000 0101 0100
332 0x1055, // 79 = 0100 1111 -> 0001 0000 0101 0101
333
334 0x1100, // 80 = 0101 0000 -> 0001 0001 0000 0000
335 0x1101, // 81 = 0101 0001 -> 0001 0001 0000 0001
336 0x1104, // 82 = 0101 0010 -> 0001 0001 0000 0100
337 0x1105, // 83 = 0101 0011 -> 0001 0001 0000 0101
338 0x1110, // 84 = 0101 0100 -> 0001 0001 0001 0000
339 0x1111, // 85 = 0101 0101 -> 0001 0001 0001 0001
340 0x1114, // 86 = 0101 0110 -> 0001 0001 0001 0100
341 0x1115, // 87 = 0101 0111 -> 0001 0001 0001 0101
342 0x1140, // 88 = 0101 1000 -> 0001 0001 0100 0000
343 0x1141, // 89 = 0101 1001 -> 0001 0001 0100 0001
344 0x1144, // 90 = 0101 1010 -> 0001 0001 0100 0100
345 0x1145, // 91 = 0101 1011 -> 0001 0001 0100 0101
346 0x1150, // 92 = 0101 1100 -> 0001 0001 0101 0000
347 0x1151, // 93 = 0101 1101 -> 0001 0001 0101 0001
348 0x1154, // 94 = 0101 1110 -> 0001 0001 0101 0100
349 0x1155, // 95 = 0101 1111 -> 0001 0001 0101 0101
350
351 0x1400, // 96 = 0110 0000 -> 0001 0100 0000 0000
352 0x1401, // 97 = 0110 0001 -> 0001 0100 0000 0001
353 0x1404, // 98 = 0110 0010 -> 0001 0100 0000 0100
354 0x1405, // 99 = 0110 0011 -> 0001 0100 0000 0101
355 0x1410, //100 = 0110 0100 -> 0001 0100 0001 0000
356 0x1411, //101 = 0110 0101 -> 0001 0100 0001 0001
357 0x1414, //102 = 0110 0110 -> 0001 0100 0001 0100
358 0x1415, //103 = 0110 0111 -> 0001 0100 0001 0101
359 0x1440, //104 = 0110 1000 -> 0001 0100 0100 0000
360 0x1441, //105 = 0110 1001 -> 0001 0100 0100 0001
361 0x1444, //106 = 0110 1010 -> 0001 0100 0100 0100
362 0x1445, //107 = 0110 1011 -> 0001 0100 0100 0101
363 0x1450, //108 = 0110 1100 -> 0001 0100 0101 0000
364 0x1451, //109 = 0110 1101 -> 0001 0100 0101 0001
365 0x1454, //110 = 0110 1110 -> 0001 0100 0101 0100
366 0x1455, //111 = 0110 1111 -> 0001 0100 0101 0101
367
368 0x1500, //112 = 0111 0000 -> 0001 0101 0000 0000
369 0x1501, //113 = 0111 0001 -> 0001 0101 0000 0001
370 0x1504, //114 = 0111 0010 -> 0001 0101 0000 0100
371 0x1505, //115 = 0111 0011 -> 0001 0101 0000 0101
372 0x1510, //116 = 0111 0100 -> 0001 0101 0001 0000
373 0x1511, //117 = 0111 0101 -> 0001 0101 0001 0001
374 0x1514, //118 = 0111 0110 -> 0001 0101 0001 0100
375 0x1515, //119 = 0111 0111 -> 0001 0101 0001 0101
376 0x1540, //120 = 0111 1000 -> 0001 0101 0100 0000
377 0x1541, //121 = 0111 1001 -> 0001 0101 0100 0001
378 0x1544, //122 = 0111 1010 -> 0001 0101 0100 0100
379 0x1545, //123 = 0111 1011 -> 0001 0101 0100 0101
380 0x1550, //124 = 0111 1100 -> 0001 0101 0101 0000
381 0x1551, //125 = 0111 1101 -> 0001 0101 0101 0001
382 0x1554, //126 = 0111 1110 -> 0001 0101 0101 0100
383 0x1555, //127 = 0111 1111 -> 0001 0101 0101 0101
384
385 0x4000, //128 = 1000 0000 -> 0100 0000 0000 0000
386 0x4001, //129 = 1000 0001 -> 0100 0000 0000 0001
387 0x4004, //130 = 1000 0010 -> 0100 0000 0000 0100
388 0x4005, //131 = 1000 0011 -> 0100 0000 0000 0101
389 0x4010, //132 = 1000 0100 -> 0100 0000 0001 0000
390 0x4011, //133 = 1000 0101 -> 0100 0000 0001 0001
391 0x4014, //134 = 1000 0110 -> 0100 0000 0001 0100
392 0x4015, //135 = 1000 0111 -> 0100 0000 0001 0101
393 0x4040, //136 = 1000 1000 -> 0100 0000 0100 0000
394 0x4041, //137 = 1000 1001 -> 0100 0000 0100 0001
395 0x4044, //138 = 1000 1010 -> 0100 0000 0100 0100
396 0x4045, //139 = 1000 1011 -> 0100 0000 0100 0101
397 0x4050, //140 = 1000 1100 -> 0100 0000 0101 0000
398 0x4051, //141 = 1000 1101 -> 0100 0000 0101 0001
399 0x4054, //142 = 1000 1110 -> 0100 0000 0101 0100
400 0x4055, //143 = 1000 1111 -> 0100 0000 0101 0101
401
402 0x4100, //144 = 1001 0000 -> 0100 0001 0000 0000
403 0x4101, //145 = 1001 0001 -> 0100 0001 0000 0001
404 0x4104, //146 = 1001 0010 -> 0100 0001 0000 0100
405 0x4105, //147 = 1001 0011 -> 0100 0001 0000 0101
406 0x4110, //148 = 1001 0100 -> 0100 0001 0001 0000
407 0x4111, //149 = 1001 0101 -> 0100 0001 0001 0001
408 0x4114, //150 = 1001 0110 -> 0100 0001 0001 0100
409 0x4115, //151 = 1001 0111 -> 0100 0001 0001 0101
410 0x4140, //152 = 1001 1000 -> 0100 0001 0100 0000
411 0x4141, //153 = 1001 1001 -> 0100 0001 0100 0001
412 0x4144, //154 = 1001 1010 -> 0100 0001 0100 0100
413 0x4145, //155 = 1001 1011 -> 0100 0001 0100 0101
414 0x4150, //156 = 1001 1100 -> 0100 0001 0101 0000
415 0x4151, //157 = 1001 1101 -> 0100 0001 0101 0001
416 0x4154, //158 = 1001 1110 -> 0100 0001 0101 0100
417 0x4155, //159 = 1001 1111 -> 0100 0001 0101 0101
418
419 0x4400, //160 = 1010 0000 -> 0100 0100 0000 0000
420 0x4401, //161 = 1010 0001 -> 0100 0100 0000 0001
421 0x4404, //162 = 1010 0010 -> 0100 0100 0000 0100
422 0x4405, //163 = 1010 0011 -> 0100 0100 0000 0101
423 0x4410, //164 = 1010 0100 -> 0100 0100 0001 0000
424 0x4411, //165 = 1010 0101 -> 0100 0100 0001 0001
425 0x4414, //166 = 1010 0110 -> 0100 0100 0001 0100
426 0x4415, //167 = 1010 0111 -> 0100 0100 0001 0101
427 0x4440, //168 = 1010 1000 -> 0100 0100 0100 0000
428 0x4441, //169 = 1010 1001 -> 0100 0100 0100 0001
429 0x4444, //170 = 1010 1010 -> 0100 0100 0100 0100
430 0x4445, //171 = 1010 1011 -> 0100 0100 0100 0101
431 0x4450, //172 = 1010 1100 -> 0100 0100 0101 0000
432 0x4451, //173 = 1010 1101 -> 0100 0100 0101 0001
433 0x4454, //174 = 1010 1110 -> 0100 0100 0101 0100
434 0x4455, //175 = 1010 1111 -> 0100 0100 0101 0101
435
436 0x4500, //176 = 1011 0000 -> 0100 0101 0000 0000
437 0x4501, //177 = 1011 0001 -> 0100 0101 0000 0001
438 0x4504, //178 = 1011 0010 -> 0100 0101 0000 0100
439 0x4505, //179 = 1011 0011 -> 0100 0101 0000 0101
440 0x4510, //180 = 1011 0100 -> 0100 0101 0001 0000
441 0x4511, //181 = 1011 0101 -> 0100 0101 0001 0001
442 0x4514, //182 = 1011 0110 -> 0100 0101 0001 0100
443 0x4515, //183 = 1011 0111 -> 0100 0101 0001 0101
444 0x4540, //184 = 1011 1000 -> 0100 0101 0100 0000
445 0x4541, //185 = 1011 1001 -> 0100 0101 0100 0001
446 0x4544, //186 = 1011 1010 -> 0100 0101 0100 0100
447 0x4545, //187 = 1011 1011 -> 0100 0101 0100 0101
448 0x4550, //188 = 1011 1100 -> 0100 0101 0101 0000
449 0x4551, //189 = 1011 1101 -> 0100 0101 0101 0001
450 0x4554, //190 = 1011 1110 -> 0100 0101 0101 0100
451 0x4555, //191 = 1011 1111 -> 0100 0101 0101 0101
452
453 0x5000, //192 = 1100 0000 -> 0101 0000 0000 0000
454 0x5001, //193 = 1100 0001 -> 0101 0000 0000 0001
455 0x5004, //194 = 1100 0010 -> 0101 0000 0000 0100
456 0x5005, //195 = 1100 0011 -> 0101 0000 0000 0101
457 0x5010, //196 = 1100 0100 -> 0101 0000 0001 0000
458 0x5011, //197 = 1100 0101 -> 0101 0000 0001 0001
459 0x5014, //198 = 1100 0110 -> 0101 0000 0001 0100
460 0x5015, //199 = 1100 0111 -> 0101 0000 0001 0101
461 0x5040, //200 = 1100 1000 -> 0101 0000 0100 0000
462 0x5041, //201 = 1100 1001 -> 0101 0000 0100 0001
463 0x5044, //202 = 1100 1010 -> 0101 0000 0100 0100
464 0x5045, //203 = 1100 1011 -> 0101 0000 0100 0101
465 0x5050, //204 = 1100 1100 -> 0101 0000 0101 0000
466 0x5051, //205 = 1100 1101 -> 0101 0000 0101 0001
467 0x5054, //206 = 1100 1110 -> 0101 0000 0101 0100
468 0x5055, //207 = 1100 1111 -> 0101 0000 0101 0101
469
470 0x5100, //208 = 1101 0000 -> 0101 0001 0000 0000
471 0x5101, //209 = 1101 0001 -> 0101 0001 0000 0001
472 0x5104, //210 = 1101 0010 -> 0101 0001 0000 0100
473 0x5105, //211 = 1101 0011 -> 0101 0001 0000 0101
474 0x5110, //212 = 1101 0100 -> 0101 0001 0001 0000
475 0x5111, //213 = 1101 0101 -> 0101 0001 0001 0001
476 0x5114, //214 = 1101 0110 -> 0101 0001 0001 0100
477 0x5115, //215 = 1101 0111 -> 0101 0001 0001 0101
478 0x5140, //216 = 1101 1000 -> 0101 0001 0100 0000
479 0x5141, //217 = 1101 1001 -> 0101 0001 0100 0001
480 0x5144, //218 = 1101 1010 -> 0101 0001 0100 0100
481 0x5145, //219 = 1101 1011 -> 0101 0001 0100 0101
482 0x5150, //220 = 1101 1100 -> 0101 0001 0101 0000
483 0x5151, //221 = 1101 1101 -> 0101 0001 0101 0001
484 0x5154, //222 = 1101 1110 -> 0101 0001 0101 0100
485 0x5155, //223 = 1101 1111 -> 0101 0001 0101 0101
486
487 0x5400, //224 = 1110 0000 -> 0101 0100 0000 0000
488 0x5401, //225 = 1110 0001 -> 0101 0100 0000 0001
489 0x5404, //226 = 1110 0010 -> 0101 0100 0000 0100
490 0x5405, //227 = 1110 0011 -> 0101 0100 0000 0101
491 0x5410, //228 = 1110 0100 -> 0101 0100 0001 0000
492 0x5411, //229 = 1110 0101 -> 0101 0100 0001 0001
493 0x5414, //230 = 1110 0110 -> 0101 0100 0001 0100
494 0x5415, //231 = 1110 0111 -> 0101 0100 0001 0101
495 0x5440, //232 = 1110 1000 -> 0101 0100 0100 0000
496 0x5441, //233 = 1110 1001 -> 0101 0100 0100 0001
497 0x5444, //234 = 1110 1010 -> 0101 0100 0100 0100
498 0x5445, //235 = 1110 1011 -> 0101 0100 0100 0101
499 0x5450, //236 = 1110 1100 -> 0101 0100 0101 0000
500 0x5451, //237 = 1110 1101 -> 0101 0100 0101 0001
501 0x5454, //238 = 1110 1110 -> 0101 0100 0101 0100
502 0x5455, //239 = 1110 1111 -> 0101 0100 0101 0101
503
504 0x5500, //240 = 1111 0000 -> 0101 0101 0000 0000
505 0x5501, //241 = 1111 0001 -> 0101 0101 0000 0001
506 0x5504, //242 = 1111 0010 -> 0101 0101 0000 0100
507 0x5505, //243 = 1111 0011 -> 0101 0101 0000 0101
508 0x5510, //244 = 1111 0100 -> 0101 0101 0001 0000
509 0x5511, //245 = 1111 0101 -> 0101 0101 0001 0001
510 0x5514, //246 = 1111 0110 -> 0101 0101 0001 0100
511 0x5515, //247 = 1111 0111 -> 0101 0101 0001 0101
512 0x5540, //248 = 1111 1000 -> 0101 0101 0100 0000
513 0x5541, //249 = 1111 1001 -> 0101 0101 0100 0001
514 0x5544, //250 = 1111 1010 -> 0101 0101 0100 0100
515 0x5545, //251 = 1111 1011 -> 0101 0101 0100 0101
516 0x5550, //252 = 1111 1100 -> 0101 0101 0101 0000
517 0x5551, //253 = 1111 1101 -> 0101 0101 0101 0001
518 0x5554, //254 = 1111 1110 -> 0101 0101 0101 0100
519 0x5555 //255 = 1111 1111 -> 0101 0101 0101 0101
520
521]
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Point.js b/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Point.js
deleted file mode 100644
index fef3220..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Point.js
+++ b/dev/null
@@ -1,62 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24//try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 //throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
26//}
27if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
28if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
29
30Clipperz.Crypto.ECC.BinaryField.Point = function(args) {
31 args = args || {};
32 this._x = args.x;
33 this._y = args.y;
34
35 return this;
36}
37
38Clipperz.Crypto.ECC.BinaryField.Point.prototype = MochiKit.Base.update(null, {
39
40 'asString': function() {
41 return "Clipperz.Crypto.ECC.BinaryField.Point (" + this.x() + ", " + this.y() + ")";
42 },
43
44 //-----------------------------------------------------------------------------
45
46 'x': function() {
47 return this._x;
48 },
49
50 'y': function() {
51 return this._y;
52 },
53
54 //-----------------------------------------------------------------------------
55
56 'isZero': function() {
57 return (this.x().isZero() && this.y().isZero())
58 },
59
60 //-----------------------------------------------------------------------------
61 __syntaxFix__: "syntax fix"
62});
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Value.js b/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Value.js
deleted file mode 100644
index b046039..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/ECC/BinaryField/Value.js
+++ b/dev/null
@@ -1,381 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24//try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 //throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
26//}
27if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
28if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
29if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
30if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
31
32Clipperz.Crypto.ECC.BinaryField.Value = function(aValue, aBase, aBitSize) {
33 if (aValue.constructor == String) {
34 varvalue;
35 varstringLength;
36 var numberOfWords;
37 vari,c;
38
39 if (aBase != 16) {
40 throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase;
41 }
42
43 value = aValue.replace(/ /g, '');
44 stringLength = value.length;
45 numberOfWords = Math.ceil(stringLength / 8);
46 this._value = new Array(numberOfWords);
47
48 c = numberOfWords;
49 for (i=0; i<c; i++) {
50 varword;
51
52 if (i < (c-1)) {
53 word = parseInt(value.substr(stringLength-((i+1)*8), 8), 16);
54 } else {
55 word = parseInt(value.substr(0, stringLength-(i*8)), 16);
56 }
57
58 this._value[i] = word;
59 }
60 } else if (aValue.constructor == Array) {
61 var itemsToCopy;
62
63 itemsToCopy = aValue.length;
64 while (aValue[itemsToCopy - 1] == 0) {
65 itemsToCopy --;
66 }
67
68 this._value = aValue.slice(0, itemsToCopy);
69 } else if (aValue.constructor == Number) {
70 this._value = [aValue];
71 } else {
72 // throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedConstructorValueType;
73 }
74
75 this._bitSize == aBitSize || null;
76
77 return this;
78}
79
80Clipperz.Crypto.ECC.BinaryField.Value.prototype = MochiKit.Base.update(null, {
81
82 'value': function() {
83 return this._value;
84 },
85
86 //-----------------------------------------------------------------------------
87
88 'wordSize': function() {
89 return this._value.length
90 },
91
92 //-----------------------------------------------------------------------------
93
94 'clone': function() {
95 return new Clipperz.Crypto.ECC.BinaryField.Value(this._value.slice(0), null, this._bitSize);
96 },
97
98 //-----------------------------------------------------------------------------
99
100 'isZero': function() {
101 return (this.compare(Clipperz.Crypto.ECC.BinaryField.Value.O) == 0);
102 },
103
104 //-----------------------------------------------------------------------------
105
106 'asString': function(aBase) {
107 varresult;
108 var i,c;
109
110 if (aBase != 16) {
111 throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase;
112 }
113
114 result = "";
115 c = this.wordSize();
116 for (i=0; i<c; i++) {
117 varwordAsString;
118
119 // wordAsString = ("00000000" + this.value()[i].toString(16));
120 wordAsString = ("00000000" + this._value[i].toString(16));
121 wordAsString = wordAsString.substring(wordAsString.length - 8);
122 result = wordAsString + result;
123 }
124
125 result = result.replace(/^(00)*/, "");
126
127 if (result == "") {
128 result = "0";
129 }
130
131 return result;
132 },
133
134 //-----------------------------------------------------------------------------
135
136 'shiftLeft': function(aNumberOfBitsToShift) {
137 //this method seems like it is never called. :-(
138 return new Clipperz.Crypto.ECC.BinaryField.Value(Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(this._value, aNumberOfBitsToShift));
139 },
140
141 //-----------------------------------------------------------------------------
142
143 'bitSize': function() {
144 if (this._bitSize == null) {
145 this._bitSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(this._value);
146 }
147
148 return this._bitSize;
149 },
150
151 //-----------------------------------------------------------------------------
152
153 'isBitSet': function(aBitPosition) {
154 return Clipperz.Crypto.ECC.BinaryField.Value._isBitSet(this._value, aBitPosition);
155 },
156
157 //-----------------------------------------------------------------------------
158
159 'xor': function(aValue) {
160 return new Clipperz.Crypto.ECC.BinaryField.Value(Clipperz.Crypto.ECC.BinaryField.Value._xor(this._value, aValue._value));
161 },
162
163 //-----------------------------------------------------------------------------
164
165 'compare': function(aValue) {
166 return Clipperz.Crypto.ECC.BinaryField.Value._compare(this._value, aValue._value);
167 },
168
169 //-----------------------------------------------------------------------------
170 __syntaxFix__: "syntax fix"
171});
172
173Clipperz.Crypto.ECC.BinaryField.Value.O = new Clipperz.Crypto.ECC.BinaryField.Value('0', 16);
174Clipperz.Crypto.ECC.BinaryField.Value.I = new Clipperz.Crypto.ECC.BinaryField.Value('1', 16);
175
176Clipperz.Crypto.ECC.BinaryField.Value._xor = function(a, b, aFirstItemOffset) {
177 var result;
178 var resultSize;
179 var i,c;
180 var firstItemOffset;
181
182 firstItemOffset = aFirstItemOffset || 0;
183 resultSize = Math.max((a.length - firstItemOffset), b.length) + firstItemOffset;
184
185 result = new Array(resultSize);
186
187 c = firstItemOffset;
188 for (i=0; i<c; i++) {
189 result[i] = a[i];
190 }
191
192 c = resultSize;
193 for (i=firstItemOffset; i<c; i++) {
194 result[i] = (((a[i] || 0) ^ (b[i - firstItemOffset] || 0)) >>> 0);
195 }
196
197 return result;
198};
199
200Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor = function(a, b, aFirstItemOffset) {
201 var i,c;
202 var firstItemOffset;
203
204 firstItemOffset = aFirstItemOffset || 0;
205
206 c = Math.max((a.length - firstItemOffset), b.length) + firstItemOffset;
207 for (i=firstItemOffset; i<c; i++) {
208 a[i] = (((a[i] || 0) ^ (b[i - firstItemOffset] || 0)) >>> 0);
209 }
210};
211
212Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft = function(aWordArray, aNumberOfBitsToShift) {
213 var numberOfWordsToShift;
214 varnumberOfBitsToShift;
215 var result;
216 varoverflowValue;
217 var nextOverflowValue;
218 vari,c;
219
220 numberOfWordsToShift = Math.floor(aNumberOfBitsToShift / 32);
221 numberOfBitsToShift = aNumberOfBitsToShift % 32;
222
223 result = new Array(aWordArray.length + numberOfWordsToShift);
224
225 c = numberOfWordsToShift;
226 for (i=0; i<c; i++) {
227 result[i] = 0;
228 }
229
230 overflowValue = 0;
231 nextOverflowValue = 0;
232
233 c = aWordArray.length;
234 for (i=0; i<c; i++) {
235 varvalue;
236 varresultWord;
237
238 // value = this.value()[i];
239 value = aWordArray[i];
240
241 if (numberOfBitsToShift > 0) {
242 nextOverflowValue = (value >>> (32 - numberOfBitsToShift));
243 value = value & (0xffffffff >>> numberOfBitsToShift);
244 resultWord = (((value << numberOfBitsToShift) | overflowValue) >>> 0);
245 } else {
246 resultWord = value;
247 }
248
249 result[i+numberOfWordsToShift] = resultWord;
250 overflowValue = nextOverflowValue;
251 }
252
253 if (overflowValue != 0) {
254 result[aWordArray.length + numberOfWordsToShift] = overflowValue;
255 }
256
257 return result;
258};
259
260Clipperz.Crypto.ECC.BinaryField.Value._overwriteShiftLeft = function(aWordArray, aNumberOfBitsToShift) {
261 var numberOfWordsToShift;
262 varnumberOfBitsToShift;
263 var result;
264 varoverflowValue;
265 vari,c;
266
267 numberOfWordsToShift = Math.floor(aNumberOfBitsToShift / 32);
268 numberOfBitsToShift = aNumberOfBitsToShift % 32;
269
270 result = new Array(aWordArray.length + numberOfWordsToShift);
271
272 c = numberOfWordsToShift;
273 for (i=0; i<c; i++) {
274 result[i] = 0;
275 }
276
277 overflowValue = 0;
278 nextOverflowValue = 0;
279
280 c = aWordArray.length;
281 for (i=0; i<c; i++) {
282 varvalue;
283 varresultWord;
284
285 // value = this.value()[i];
286 value = aWordArray[i];
287
288 if (numberOfBitsToShift > 0) {
289 var nextOverflowValue;
290
291 nextOverflowValue = (value >>> (32 - numberOfBitsToShift));
292 value = value & (0xffffffff >>> numberOfBitsToShift);
293 resultWord = (((value << numberOfBitsToShift) | overflowValue) >>> 0);
294 } else {
295 resultWord = value;
296 }
297
298 result[i+numberOfWordsToShift] = resultWord;
299 overflowValue = nextOverflowValue;
300 }
301
302 if (overflowValue != 0) {
303 result[aWordArray.length + numberOfWordsToShift] = overflowValue;
304 }
305
306 return result;
307};
308
309Clipperz.Crypto.ECC.BinaryField.Value._bitSize = function(aWordArray) {
310 varresult;
311 varnotNullElements;
312 var mostValuableWord;
313 var matchingBitsInMostImportantWord;
314 var mask;
315 var i,c;
316
317 notNullElements = aWordArray.length;
318
319 if ((aWordArray.length == 1) && (aWordArray[0] == 0)) {
320 result = 0;
321 } else {
322 notNullElements --;
323 while((notNullElements > 0) && (aWordArray[notNullElements] == 0)) {
324 notNullElements --;
325 }
326
327 result = notNullElements * 32;
328 mostValuableWord = aWordArray[notNullElements];
329
330 matchingBits = 32;
331 mask = 0x80000000;
332
333 while ((matchingBits > 0) && ((mostValuableWord & mask) == 0)) {
334 matchingBits --;
335 mask >>>= 1;
336 }
337
338 result += matchingBits;
339 }
340
341 return result;
342};
343
344Clipperz.Crypto.ECC.BinaryField.Value._isBitSet = function(aWordArray, aBitPosition) {
345 var result;
346 varbyteIndex;
347 var bitIndexInSelectedByte;
348
349 byteIndex = Math.floor(aBitPosition / 32);
350 bitIndexInSelectedByte = aBitPosition % 32;
351
352 if (byteIndex <= aWordArray.length) {
353 result = ((aWordArray[byteIndex] & (1 << bitIndexInSelectedByte)) != 0);
354 } else {
355 result = false;
356 }
357
358 return result;
359};
360
361Clipperz.Crypto.ECC.BinaryField.Value._compare = function(a,b) {
362 varresult;
363 var i,c;
364
365 result = MochiKit.Base.compare(a.length, b.length);
366
367 c = a.length;
368 for (i=0; (i<c) && (result==0); i++) {
369//console.log("compare[" + c + " - " + i + " - 1] " + this.value()[c-i-1] + ", " + aValue.value()[c-i-1]);
370 // result = MochiKit.Base.compare(this.value()[c-i-1], aValue.value()[c-i-1]);
371 result = MochiKit.Base.compare(a[c-i-1], b[c-i-1]);
372 }
373
374 return result;
375};
376
377
378Clipperz.Crypto.ECC.BinaryField.Value['exception']= {
379 'UnsupportedBase': new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase"),
380 'UnsupportedConstructorValueType':new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedConstructorValueType")
381};
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/ECC/StandardCurves.js b/frontend/gamma/js/ClipperzCryptoLibrary/ECC/StandardCurves.js
deleted file mode 100644
index ed971ae..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/ECC/StandardCurves.js
+++ b/dev/null
@@ -1,234 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24//try { if (typeof(Clipperz.Crypto.ECC.BinaryField.Curve) == 'undefined') { throw ""; }} catch (e) {
25 //throw "Clipperz.Crypto.ECC depends on Clipperz.Crypto.ECC.BinaryField.Curve!";
26//}
27//try { if (typeof(Clipperz.Crypto.ECC.Koblitz.Curve) == 'undefined') { throw ""; }} catch (e) {
28 //throw "Clipperz.Crypto.ECC depends on Clipperz.Crypto.ECC.Koblitz.Curve!";
29//}
30
31Clipperz.Crypto.ECC.StandardCurves = {};
32
33MochiKit.Base.update(Clipperz.Crypto.ECC.StandardCurves, {
34
35 //==============================================================================
36
37 '_K571': null,
38 'K571': function() { //f(z) = z^571 + z^10 + z^5 + z^2 + 1
39 if ((Clipperz.Crypto.ECC.StandardCurves._K571 == null) && (typeof(Clipperz.Crypto.ECC.Koblitz.Curve) != 'undefined')) {
40 Clipperz.Crypto.ECC.StandardCurves._K571 = new Clipperz.Crypto.ECC.Koblitz.Curve({
41 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),
42 a: new Clipperz.Crypto.ECC.Koblitz.Value('0', 16),
43 b: new Clipperz.Crypto.ECC.Koblitz.Value('1', 16),
44 G: new Clipperz.Crypto.ECC.Koblitz.Point({
45 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),
46 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)
47 }),
48 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),
49 h: new Clipperz.Crypto.ECC.Koblitz.Value('4', 16),
50 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)
51 });
52 }
53
54 return Clipperz.Crypto.ECC.StandardCurves._K571;
55 },
56
57 //-----------------------------------------------------------------------------
58
59 '_K283': null,
60 'K283': function() { //f(z) = z^283 + z^12 + z^7 + z^5 + 1
61 if ((Clipperz.Crypto.ECC.StandardCurves._K283 == null) && (typeof(Clipperz.Crypto.ECC.Koblitz.Curve) != 'undefined')) {
62 Clipperz.Crypto.ECC.StandardCurves._K283 = new Clipperz.Crypto.ECC.Koblitz.Curve({
63 modulus: new Clipperz.Crypto.ECC.Koblitz.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
64 a: new Clipperz.Crypto.ECC.Koblitz.Value('0', 16),
65 b: new Clipperz.Crypto.ECC.Koblitz.Value('1', 16),
66 G: new Clipperz.Crypto.ECC.Koblitz.Point({
67 x: new Clipperz.Crypto.ECC.Koblitz.Value('0503213f 78ca4488 3f1a3b81 62f188e5 53cd265f 23c1567a 16876913 b0c2ac24 58492836', 16),
68 y: new Clipperz.Crypto.ECC.Koblitz.Value('01ccda38 0f1c9e31 8d90f95d 07e5426f e87e45c0 e8184698 e4596236 4e341161 77dd2259', 16)
69 }),
70 r: new Clipperz.Crypto.ECC.Koblitz.Value('01ffffff ffffffff ffffffff ffffffff ffffe9ae 2ed07577 265dff7f 94451e06 1e163c61', 16),
71 h: new Clipperz.Crypto.ECC.Koblitz.Value('4', 16),
72 primeFactor: new Clipperz.Crypto.ECC.Koblitz.Value('01ffffff ffffffff ffffffff ffffffff ffffe9ae 2ed07577 265dff7f 94451e06 1e163c61', 16)
73 });
74 }
75
76 return Clipperz.Crypto.ECC.StandardCurves._K283;
77 },
78
79 //==============================================================================
80
81 '_B571': null,
82 'B571': function() { //f(z) = z^571 + z^10 + z^5 + z^2 + 1
83 if ((Clipperz.Crypto.ECC.StandardCurves._B571 == null) && (typeof(Clipperz.Crypto.ECC.BinaryField.Curve) != 'undefined')) {
84 Clipperz.Crypto.ECC.StandardCurves._B571 = new Clipperz.Crypto.ECC.BinaryField.Curve({
85 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),
86 a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
87 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),
88 G: new Clipperz.Crypto.ECC.BinaryField.Point({
89 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),
90 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)
91 }),
92 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),
93 h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
94
95 // S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
96 // n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16)
97 });
98
99 //-----------------------------------------------------------------------------
100 //
101 //Guide to Elliptic Curve Cryptography
102 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
103 //- Pag: 56, Alorithm 2.45 (with a typo!!!)
104 //
105 //-----------------------------------------------------------------------------
106 //
107 // http://www.milw0rm.com/papers/136
108 //
109 // -------------------------------------------------------------------------
110 // Polynomial Reduction Algorithm Modulo f571
111 // -------------------------------------------------------------------------
112 //
113 // Input: Polynomial p(x) of degree 1140 or less, stored as
114 // an array of 2T machinewords.
115 // Output: p(x) mod f571(x)
116 //
117 // FOR i = T-1, ..., 0 DO
118 // SET X := P[i+T]
119 // P[i] := P[i] ^ (X<<5) ^ (X<<7) ^ (X<<10) ^ (X<<15)
120 // P[i+1] := P[i+1] ^ (X>>17) ^ (X>>22) ^ (X>>25) ^ (X>>27)
121 //
122 // SET X := P[T-1] >> 27
123 // P[0] := P[0] ^ X ^ (X<<2) ^ (X<<5) ^ (X<<10)
124 // P[T-1] := P[T-1] & 0x07ffffff
125 //
126 // RETURN P[T-1],...,P[0]
127 //
128 // -------------------------------------------------------------------------
129 //
130 Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module;
131 Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module = function(aValue) {
132 varresult;
133
134 if (aValue.bitSize() > 1140) {
135 MochiKit.Logging.logWarning("ECC.StandarCurves.B571.finiteField().module: falling back to default implementation");
136 result = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule(aValue);
137 } else {
138 varC, T;
139 var i;
140
141//console.log(">>> binaryField.finiteField.(improved)module");
142 // C = aValue.value().slice(0);
143 C = aValue._value.slice(0);
144 for (i=35; i>=18; i--) {
145 T = C[i];
146 C[i-18] = (((C[i-18] ^ (T<<5) ^ (T<<7) ^ (T<<10) ^ (T<<15)) & 0xffffffff) >>> 0);
147 C[i-17] = ((C[i-17] ^ (T>>>27) ^ (T>>>25) ^ (T>>>22) ^ (T>>>17)) >>> 0);
148 }
149 T = (C[17] >>> 27);
150 C[0] = ((C[0] ^ T ^ ((T<<2) ^ (T<<5) ^ (T<<10)) & 0xffffffff) >>> 0);
151 C[17] = (C[17] & 0x07ffffff);
152
153 for(i=18; i<=35; i++) {
154 C[i] = 0;
155 }
156
157 result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
158//console.log("<<< binaryField.finiteField.(improved)module");
159 }
160
161 return result;
162 };
163 }
164
165 return Clipperz.Crypto.ECC.StandardCurves._B571;
166 },
167
168 //-----------------------------------------------------------------------------
169
170 '_B283': null,
171 'B283': function() { //f(z) = z^283 + z^12 + z^7 + z^5 + 1
172 if ((Clipperz.Crypto.ECC.StandardCurves._B283 == null) && (typeof(Clipperz.Crypto.ECC.BinaryField.Curve) != 'undefined')) {
173 Clipperz.Crypto.ECC.StandardCurves._B283 = new Clipperz.Crypto.ECC.BinaryField.Curve({
174 modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
175 a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
176 b: new Clipperz.Crypto.ECC.BinaryField.Value('027b680a c8b8596d a5a4af8a 19a0303f ca97fd76 45309fa2 a581485a f6263e31 3b79a2f5', 16),
177 G: new Clipperz.Crypto.ECC.BinaryField.Point({
178 x: new Clipperz.Crypto.ECC.BinaryField.Value('05f93925 8db7dd90 e1934f8c 70b0dfec 2eed25b8 557eac9c 80e2e198 f8cdbecd 86b12053', 16),
179 y: new Clipperz.Crypto.ECC.BinaryField.Value('03676854 fe24141c b98fe6d4 b20d02b4 516ff702 350eddb0 826779c8 13f0df45 be8112f4', 16)
180 }),
181 r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffff ffffffff ffffffff ffffffff ffffef90 399660fc 938a9016 5b042a7c efadb307', 16),
182 h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
183 });
184
185 //-----------------------------------------------------------------------------
186 //
187 //Guide to Elliptic Curve Cryptography
188 //Darrel Hankerson, Alfred Menezes, Scott Vanstone
189 //- Pag: 56, Alorithm 2.43
190 //
191 //-----------------------------------------------------------------------------
192 Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module;
193 Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module = function(aValue) {
194 varresult;
195
196 if (aValue.bitSize() > 564) {
197 MochiKit.Logging.logWarning("ECC.StandarCurves.B283.finiteField().module: falling back to default implementation");
198 result = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule(aValue);
199 } else {
200 varC, T;
201 var i;
202
203//console.log(">>> binaryField.finiteField.(improved)module");
204 C = aValue._value.slice(0);
205 for (i=17; i>=9; i--) {
206 T = C[i];
207 C[i-9] = (((C[i-9] ^ (T<<5) ^ (T<<10) ^ (T<<12) ^ (T<<17)) & 0xffffffff) >>> 0);
208 C[i-8] = ((C[i-8] ^ (T>>>27) ^ (T>>>22) ^ (T>>>20) ^ (T>>>15)) >>> 0);
209 }
210 T = (C[8] >>> 27);
211 C[0] = ((C[0] ^ T ^ ((T<<5) ^ (T<<7) ^ (T<<12)) & 0xffffffff) >>> 0);
212 C[8] = (C[8] & 0x07ffffff);
213
214 for(i=9; i<=17; i++) {
215 C[i] = 0;
216 }
217
218 result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
219//console.log("<<< binaryField.finiteField.(improved)module");
220 }
221
222 return result;
223 };
224 }
225
226 return Clipperz.Crypto.ECC.StandardCurves._B283;
227 },
228
229 //==============================================================================
230 __syntaxFix__: "syntax fix"
231});
232
233
234
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/PRNG.js b/frontend/gamma/js/ClipperzCryptoLibrary/PRNG.js
deleted file mode 100644
index 18cc260..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/PRNG.js
+++ b/dev/null
@@ -1,850 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
26}
27
28try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) {
29 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!";
30}
31
32try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) {
33 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!";
34}
35
36if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; }
37
38//#############################################################################
39
40Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) {
41 args = args || {};
42 //MochiKit.Base.bindMethods(this);
43
44 this._stack = new Clipperz.ByteArray();
45 this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256;
46 return this;
47}
48
49Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, {
50
51 'toString': function() {
52 return "Clipperz.Crypto.PRNG.EntropyAccumulator";
53 },
54
55 //-------------------------------------------------------------------------
56
57 'stack': function() {
58 return this._stack;
59 },
60
61 'setStack': function(aValue) {
62 this._stack = aValue;
63 },
64
65 'resetStack': function() {
66 this.stack().reset();
67 },
68
69 'maxStackLengthBeforeHashing': function() {
70 return this._maxStackLengthBeforeHashing;
71 },
72
73 //-------------------------------------------------------------------------
74
75 'addRandomByte': function(aValue) {
76 this.stack().appendByte(aValue);
77
78 if (this.stack().length() > this.maxStackLengthBeforeHashing()) {
79 this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack()));
80 }
81 },
82
83 //-------------------------------------------------------------------------
84 __syntaxFix__: "syntax fix"
85});
86
87//#############################################################################
88
89Clipperz.Crypto.PRNG.RandomnessSource = function(args) {
90 args = args || {};
91 MochiKit.Base.bindMethods(this);
92
93 this._generator = args.generator || null;
94 this._sourceId = args.sourceId || null;
95 this._boostMode = args.boostMode || false;
96
97 this._nextPoolIndex = 0;
98
99 return this;
100}
101
102Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, {
103
104 'generator': function() {
105 return this._generator;
106 },
107
108 'setGenerator': function(aValue) {
109 this._generator = aValue;
110 },
111
112 //-------------------------------------------------------------------------
113
114 'boostMode': function() {
115 return this._boostMode;
116 },
117
118 'setBoostMode': function(aValue) {
119 this._boostMode = aValue;
120 },
121
122 //-------------------------------------------------------------------------
123
124 'sourceId': function() {
125 return this._sourceId;
126 },
127
128 'setSourceId': function(aValue) {
129 this._sourceId = aValue;
130 },
131
132 //-------------------------------------------------------------------------
133
134 'nextPoolIndex': function() {
135 return this._nextPoolIndex;
136 },
137
138 'incrementNextPoolIndex': function() {
139 this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators());
140 },
141
142 //-------------------------------------------------------------------------
143
144 'updateGeneratorWithValue': function(aRandomValue) {
145 if (this.generator() != null) {
146 this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue);
147 this.incrementNextPoolIndex();
148 }
149 },
150
151 //-------------------------------------------------------------------------
152 __syntaxFix__: "syntax fix"
153});
154
155//#############################################################################
156
157Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) {
158 args = args || {};
159 //MochiKit.Base.bindMethods(this);
160
161 this._intervalTime = args.intervalTime || 1000;
162
163 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
164
165 this.collectEntropy();
166 return this;
167}
168
169Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
170
171 'intervalTime': function() {
172 return this._intervalTime;
173 },
174
175 //-------------------------------------------------------------------------
176
177 'collectEntropy': function() {
178 varnow;
179 varentropyByte;
180 var intervalTime;
181 now = new Date();
182 entropyByte = (now.getTime() & 0xff);
183
184 intervalTime = this.intervalTime();
185 if (this.boostMode() == true) {
186 intervalTime = intervalTime / 9;
187 }
188
189 this.updateGeneratorWithValue(entropyByte);
190 setTimeout(this.collectEntropy, intervalTime);
191 },
192
193 //-------------------------------------------------------------------------
194
195 'numberOfRandomBits': function() {
196 return 5;
197 },
198
199 //-------------------------------------------------------------------------
200
201 'pollingFrequency': function() {
202 return 10;
203 },
204
205 //-------------------------------------------------------------------------
206 __syntaxFix__: "syntax fix"
207});
208
209//*****************************************************************************
210
211Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) {
212 args = args || {};
213
214 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
215
216 this._numberOfBitsToCollectAtEachEvent = 4;
217 this._randomBitsCollector = 0;
218 this._numberOfRandomBitsCollected = 0;
219
220 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy');
221
222 return this;
223}
224
225Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
226
227 //-------------------------------------------------------------------------
228
229 'numberOfBitsToCollectAtEachEvent': function() {
230 return this._numberOfBitsToCollectAtEachEvent;
231 },
232
233 //-------------------------------------------------------------------------
234
235 'randomBitsCollector': function() {
236 return this._randomBitsCollector;
237 },
238
239 'setRandomBitsCollector': function(aValue) {
240 this._randomBitsCollector = aValue;
241 },
242
243 'appendRandomBitsToRandomBitsCollector': function(aValue) {
244 var collectedBits;
245 var numberOfRandomBitsCollected;
246
247 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
248 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
249 this.setRandomBitsCollector(collectetBits);
250 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent();
251
252 if (numberOfRandomBitsCollected == 8) {
253 this.updateGeneratorWithValue(collectetBits);
254 numberOfRandomBitsCollected = 0;
255 this.setRandomBitsCollector(0);
256 }
257
258 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
259 },
260
261 //-------------------------------------------------------------------------
262
263 'numberOfRandomBitsCollected': function() {
264 return this._numberOfRandomBitsCollected;
265 },
266
267 'setNumberOfRandomBitsCollected': function(aValue) {
268 this._numberOfRandomBitsCollected = aValue;
269 },
270
271 //-------------------------------------------------------------------------
272
273 'collectEntropy': function(anEvent) {
274 var mouseLocation;
275 var randomBit;
276 var mask;
277
278 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent());
279
280 mouseLocation = anEvent.mouse().client;
281 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask);
282 this.appendRandomBitsToRandomBitsCollector(randomBit)
283 },
284
285 //-------------------------------------------------------------------------
286
287 'numberOfRandomBits': function() {
288 return 1;
289 },
290
291 //-------------------------------------------------------------------------
292
293 'pollingFrequency': function() {
294 return 10;
295 },
296
297 //-------------------------------------------------------------------------
298 __syntaxFix__: "syntax fix"
299});
300
301//*****************************************************************************
302
303Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) {
304 args = args || {};
305 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
306
307 this._randomBitsCollector = 0;
308 this._numberOfRandomBitsCollected = 0;
309
310 MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy');
311
312 return this;
313}
314
315Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
316
317 //-------------------------------------------------------------------------
318
319 'randomBitsCollector': function() {
320 return this._randomBitsCollector;
321 },
322
323 'setRandomBitsCollector': function(aValue) {
324 this._randomBitsCollector = aValue;
325 },
326
327 'appendRandomBitToRandomBitsCollector': function(aValue) {
328 var collectedBits;
329 var numberOfRandomBitsCollected;
330
331 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
332 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
333 this.setRandomBitsCollector(collectetBits);
334 numberOfRandomBitsCollected ++;
335
336 if (numberOfRandomBitsCollected == 8) {
337 this.updateGeneratorWithValue(collectetBits);
338 numberOfRandomBitsCollected = 0;
339 this.setRandomBitsCollector(0);
340 }
341
342 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
343 },
344
345 //-------------------------------------------------------------------------
346
347 'numberOfRandomBitsCollected': function() {
348 return this._numberOfRandomBitsCollected;
349 },
350
351 'setNumberOfRandomBitsCollected': function(aValue) {
352 this._numberOfRandomBitsCollected = aValue;
353 },
354
355 //-------------------------------------------------------------------------
356
357 'collectEntropy': function(anEvent) {
358/*
359 var mouseLocation;
360 var randomBit;
361
362 mouseLocation = anEvent.mouse().client;
363
364 randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1);
365 this.appendRandomBitToRandomBitsCollector(randomBit);
366*/
367 },
368
369 //-------------------------------------------------------------------------
370
371 'numberOfRandomBits': function() {
372 return 1;
373 },
374
375 //-------------------------------------------------------------------------
376
377 'pollingFrequency': function() {
378 return 10;
379 },
380
381 //-------------------------------------------------------------------------
382 __syntaxFix__: "syntax fix"
383});
384
385//#############################################################################
386
387Clipperz.Crypto.PRNG.Fortuna = function(args) {
388 vari,c;
389
390 args = args || {};
391
392 this._key = args.seed || null;
393 if (this._key == null) {
394 this._counter = 0;
395 this._key = new Clipperz.ByteArray();
396 } else {
397 this._counter = 1;
398 }
399
400 this._aesKey = null;
401
402 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64;
403 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32;
404
405 this._accumulators = [];
406 c = this.numberOfEntropyAccumulators();
407 for (i=0; i<c; i++) {
408 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator());
409 }
410
411 this._randomnessSources = [];
412 this._reseedCounter = 0;
413
414 return this;
415}
416
417Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, {
418
419 'toString': function() {
420 return "Clipperz.Crypto.PRNG.Fortuna";
421 },
422
423 //-------------------------------------------------------------------------
424
425 'key': function() {
426 return this._key;
427 },
428
429 'setKey': function(aValue) {
430 this._key = aValue;
431 this._aesKey = null;
432 },
433
434 'aesKey': function() {
435 if (this._aesKey == null) {
436 this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()});
437 }
438
439 return this._aesKey;
440 },
441
442 'accumulators': function() {
443 return this._accumulators;
444 },
445
446 'firstPoolReseedLevel': function() {
447 return this._firstPoolReseedLevel;
448 },
449
450 //-------------------------------------------------------------------------
451
452 'reseedCounter': function() {
453 return this._reseedCounter;
454 },
455
456 'incrementReseedCounter': function() {
457 this._reseedCounter = this._reseedCounter +1;
458 },
459
460 //-------------------------------------------------------------------------
461
462 'reseed': function() {
463 varnewKeySeed;
464 var reseedCounter;
465 varreseedCounterMask;
466 var i, c;
467
468 newKeySeed = this.key();
469 this.incrementReseedCounter();
470 reseedCounter = this.reseedCounter();
471
472 c = this.numberOfEntropyAccumulators();
473 reseedCounterMask = 0xffffffff >>> (32 - c);
474 for (i=0; i<c; i++) {
475 if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) {
476 newKeySeed.appendBlock(this.accumulators()[i].stack());
477 this.accumulators()[i].resetStack();
478 }
479 }
480
481 if (reseedCounter == 1) {
482 c = this.randomnessSources().length;
483 for (i=0; i<c; i++) {
484 this.randomnessSources()[i].setBoostMode(false);
485 }
486 }
487
488 this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed));
489 if (reseedCounter == 1) {
490//MochiKit.Logging.logDebug("### PRNG.readyToGenerateRandomBytes");
491Clipperz.log("### PRNG.readyToGenerateRandomBytes");
492 MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes');
493 }
494 MochiKit.Signal.signal(this, 'reseeded');
495 },
496
497 //-------------------------------------------------------------------------
498
499 'isReadyToGenerateRandomValues': function() {
500 return this.reseedCounter() != 0;
501 },
502
503 //-------------------------------------------------------------------------
504
505 'entropyLevel': function() {
506 return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel());
507 },
508
509 //-------------------------------------------------------------------------
510
511 'counter': function() {
512 return this._counter;
513 },
514
515 'incrementCounter': function() {
516 this._counter += 1;
517 },
518
519 'counterBlock': function() {
520 var result;
521
522 result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0);
523
524 return result;
525 },
526
527 //-------------------------------------------------------------------------
528
529 'getRandomBlock': function() {
530 var result;
531
532 result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues()));
533 this.incrementCounter();
534
535 return result;
536 },
537
538 //-------------------------------------------------------------------------
539
540 'getRandomBytes': function(aSize) {
541 var result;
542
543 if (this.isReadyToGenerateRandomValues()) {
544 var i,c;
545 var newKey;
546
547 result = new Clipperz.ByteArray();
548
549 c = Math.ceil(aSize / (128 / 8));
550 for (i=0; i<c; i++) {
551 result.appendBlock(this.getRandomBlock());
552 }
553
554 if (result.length() != aSize) {
555 result = result.split(0, aSize);
556 }
557
558 newKey = this.getRandomBlock().appendBlock(this.getRandomBlock());
559 this.setKey(newKey);
560 } else {
561MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
562 throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy;
563 }
564
565 return result;
566 },
567
568 //-------------------------------------------------------------------------
569
570 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) {
571 varselectedAccumulator;
572
573 selectedAccumulator = this.accumulators()[aPoolId];
574 selectedAccumulator.addRandomByte(aRandomValue);
575
576 if (aPoolId == 0) {
577 MochiKit.Signal.signal(this, 'addedRandomByte')
578 if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) {
579 this.reseed();
580 }
581 }
582 },
583
584 //-------------------------------------------------------------------------
585
586 'numberOfEntropyAccumulators': function() {
587 return this._numberOfEntropyAccumulators;
588 },
589
590 //-------------------------------------------------------------------------
591
592 'randomnessSources': function() {
593 return this._randomnessSources;
594 },
595
596 'addRandomnessSource': function(aRandomnessSource) {
597 aRandomnessSource.setGenerator(this);
598 aRandomnessSource.setSourceId(this.randomnessSources().length);
599 this.randomnessSources().push(aRandomnessSource);
600
601 if (this.isReadyToGenerateRandomValues() == false) {
602 aRandomnessSource.setBoostMode(true);
603 }
604 },
605
606 //-------------------------------------------------------------------------
607
608 'deferredEntropyCollection': function(aValue) {
609 var result;
610
611//MochiKit.Logging.logDebug(">>> PRNG.deferredEntropyCollection");
612
613 if (this.isReadyToGenerateRandomValues()) {
614//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 1");
615 result = aValue;
616 } else {
617//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 2");
618 var deferredResult;
619
620 // Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true);
621
622 deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection");
623 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.1 - PRNG.deferredEntropyCollection - 1: " + res); return res;});
624 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
625 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.2 - PRNG.deferredEntropyCollection - 2: " + res); return res;});
626 MochiKit.Signal.connect(this,
627 'readyToGenerateRandomBytes',
628 deferredResult,
629 'callback');
630
631 result = deferredResult;
632 }
633//MochiKit.Logging.logDebug("<<< PRNG.deferredEntropyCollection - result: " + result);
634
635 return result;
636 },
637
638 //-------------------------------------------------------------------------
639
640 'fastEntropyAccumulationForTestingPurpose': function() {
641 while (! this.isReadyToGenerateRandomValues()) {
642 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256));
643 }
644 },
645
646 //-------------------------------------------------------------------------
647
648 'dump': function(appendToDoc) {
649 var tbl;
650 var i,c;
651
652 tbl = document.createElement("table");
653 tbl.border = 0;
654 with (tbl.style) {
655 border = "1px solid lightgrey";
656 fontFamily = 'Helvetica, Arial, sans-serif';
657 fontSize = '8pt';
658 //borderCollapse = "collapse";
659 }
660 var hdr = tbl.createTHead();
661 var hdrtr = hdr.insertRow(0);
662 // document.createElement("tr");
663 {
664 var ntd;
665
666 ntd = hdrtr.insertCell(0);
667 ntd.style.borderBottom = "1px solid lightgrey";
668 ntd.style.borderRight = "1px solid lightgrey";
669 ntd.appendChild(document.createTextNode("#"));
670
671 ntd = hdrtr.insertCell(1);
672 ntd.style.borderBottom = "1px solid lightgrey";
673 ntd.style.borderRight = "1px solid lightgrey";
674 ntd.appendChild(document.createTextNode("s"));
675
676 ntd = hdrtr.insertCell(2);
677 ntd.colSpan = this.firstPoolReseedLevel();
678 ntd.style.borderBottom = "1px solid lightgrey";
679 ntd.style.borderRight = "1px solid lightgrey";
680 ntd.appendChild(document.createTextNode("base values"));
681
682 ntd = hdrtr.insertCell(3);
683 ntd.colSpan = 20;
684 ntd.style.borderBottom = "1px solid lightgrey";
685 ntd.appendChild(document.createTextNode("extra values"));
686
687 }
688
689 c = this.accumulators().length;
690 for (i=0; i<c ; i++) {
691 varcurrentAccumulator;
692 var bdytr;
693 var bdytd;
694 var ii, cc;
695
696 currentAccumulator = this.accumulators()[i]
697
698 bdytr = tbl.insertRow(true);
699
700 bdytd = bdytr.insertCell(0);
701 bdytd.style.borderRight = "1px solid lightgrey";
702 bdytd.style.color = "lightgrey";
703 bdytd.appendChild(document.createTextNode("" + i));
704
705 bdytd = bdytr.insertCell(1);
706 bdytd.style.borderRight = "1px solid lightgrey";
707 bdytd.style.color = "gray";
708 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length()));
709
710
711 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel());
712 for (ii=0; ii<cc; ii++) {
713 var cellText;
714
715 bdytd = bdytr.insertCell(ii + 2);
716
717 if (ii < currentAccumulator.stack().length()) {
718 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii));
719 } else {
720 cellText = "_";
721 }
722
723 if (ii == (this.firstPoolReseedLevel() - 1)) {
724 bdytd.style.borderRight = "1px solid lightgrey";
725 }
726
727 bdytd.appendChild(document.createTextNode(cellText));
728 }
729
730 }
731
732
733 if (appendToDoc) {
734 var ne = document.createElement("div");
735 ne.id = "entropyGeneratorStatus";
736 with (ne.style) {
737 fontFamily = "Courier New, monospace";
738 fontSize = "12px";
739 lineHeight = "16px";
740 borderTop = "1px solid black";
741 padding = "10px";
742 }
743 if (document.getElementById(ne.id)) {
744 MochiKit.DOM.swapDOM(ne.id, ne);
745 } else {
746 document.body.appendChild(ne);
747 }
748 ne.appendChild(tbl);
749 }
750
751 return tbl;
752 },
753
754 //-----------------------------------------------------------------------------
755 __syntaxFix__: "syntax fix"
756});
757
758//#############################################################################
759
760Clipperz.Crypto.PRNG.Random = function(args) {
761 args = args || {};
762 //MochiKit.Base.bindMethods(this);
763
764 return this;
765}
766
767Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
768
769 'toString': function() {
770 return "Clipperz.Crypto.PRNG.Random";
771 },
772
773 //-------------------------------------------------------------------------
774
775 'getRandomBytes': function(aSize) {
776//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes");
777 varresult;
778 var i,c;
779
780 result = new Clipperz.ByteArray()
781 c = aSize || 1;
782 for (i=0; i<c; i++) {
783 result.appendByte((Math.random()*255) & 0xff);
784 }
785
786//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes");
787 return result;
788 },
789
790 //-------------------------------------------------------------------------
791 __syntaxFix__: "syntax fix"
792});
793
794//#############################################################################
795
796_clipperz_crypt_prng_defaultPRNG = null;
797
798Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
799 if (_clipperz_crypt_prng_defaultPRNG == null) {
800 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna();
801
802 //.............................................................
803 //
804 // TimeRandomnessSource
805 //
806 //.............................................................
807 {
808 var newRandomnessSource;
809
810 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111});
811 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
812 }
813
814 //.............................................................
815 //
816 // MouseRandomnessSource
817 //
818 //.............................................................
819 {
820 varnewRandomnessSource;
821
822 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
823 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
824 }
825
826 //.............................................................
827 //
828 // KeyboardRandomnessSource
829 //
830 //.............................................................
831 {
832 varnewRandomnessSource;
833
834 newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource();
835 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
836 }
837
838 }
839
840 return _clipperz_crypt_prng_defaultPRNG;
841};
842
843//#############################################################################
844
845Clipperz.Crypto.PRNG.exception = {
846 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
847};
848
849
850MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator);
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/RSA.js b/frontend/gamma/js/ClipperzCryptoLibrary/RSA.js
deleted file mode 100644
index 5a480f1..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/RSA.js
+++ b/dev/null
@@ -1,146 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.RSA depends on Clipperz.Crypto.BigInt!";
26}
27
28if (typeof(Clipperz.Crypto.RSA) == 'undefined') { Clipperz.Crypto.RSA = {}; }
29
30Clipperz.Crypto.RSA.VERSION = "0.1";
31Clipperz.Crypto.RSA.NAME = "Clipperz.RSA";
32
33//#############################################################################
34
35MochiKit.Base.update(Clipperz.Crypto.RSA, {
36
37 //-------------------------------------------------------------------------
38
39 'publicKeyWithValues': function (e, d, n) {
40 varresult;
41
42 result = {};
43
44 if (e.isBigInt) {
45 result.e = e;
46 } else {
47 result.e = new Clipperz.Crypto.BigInt(e, 16);
48 }
49
50 if (d.isBigInt) {
51 result.d = d;
52 } else {
53 result.d = new Clipperz.Crypto.BigInt(d, 16);
54 }
55
56 if (n.isBigInt) {
57 result.n = n;
58 } else {
59 result.n = new Clipperz.Crypto.BigInt(n, 16);
60 }
61
62 return result;
63 },
64
65 'privateKeyWithValues': function(e, d, n) {
66 return Clipperz.Crypto.RSA.publicKeyWithValues(e, d, n);
67 },
68
69 //-----------------------------------------------------------------------------
70
71 'encryptUsingPublicKey': function (aKey, aMessage) {
72 varmessageValue;
73 varresult;
74
75 messageValue = new Clipperz.Crypto.BigInt(aMessage, 16);
76 result = messageValue.powerModule(aKey.e, aKey.n);
77
78 return result.asString(16);
79 },
80
81 //.............................................................................
82
83 'decryptUsingPublicKey': function (aKey, aMessage) {
84 return Clipperz.Crypto.RSA.encryptUsingPublicKey(aKey, aMessage);
85 },
86
87 //-----------------------------------------------------------------------------
88
89 'encryptUsingPrivateKey': function (aKey, aMessage) {
90 varmessageValue;
91 varresult;
92
93 messageValue = new Clipperz.Crypto.BigInt(aMessage, 16);
94 result = messageValue.powerModule(aKey.d, aKey.n);
95
96 return result.asString(16);
97 },
98
99 //.............................................................................
100
101 'decryptUsingPrivateKey': function (aKey, aMessage) {
102 return Clipperz.Crypto.RSA.encryptUsingPrivateKey(aKey, aMessage);
103 },
104
105 //-----------------------------------------------------------------------------
106
107 'generatePublicKey': function(aNumberOfBits) {
108 varresult;
109 vare;
110 vard;
111 varn;
112
113 e = new Clipperz.Crypto.BigInt("10001", 16);
114
115 {
116 var p, q;
117 varphi;
118
119 do {
120 p = Clipperz.Crypto.BigInt.randomPrime(aNumberOfBits);
121 } while (p.module(e).equals(1));
122
123 do {
124 q = Clipperz.Crypto.BigInt.randomPrime(aNumberOfBits);
125 } while ((q.equals(p)) || (q.module(e).equals(1)));
126
127 n = p.multiply(q);
128 phi = (p.subtract(1).multiply(q.subtract(1)));
129 d = e.powerModule(-1, phi);
130 }
131
132 result = Clipperz.Crypto.RSA.publicKeyWithValues(e, d, n);
133
134 return result;
135 },
136
137 //-------------------------------------------------------------------------
138
139 __syntaxFix__: "syntax fix"
140
141 //-------------------------------------------------------------------------
142
143});
144
145//#############################################################################
146
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/SHA.js b/frontend/gamma/js/ClipperzCryptoLibrary/SHA.js
deleted file mode 100644
index f8bfe6e..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/SHA.js
+++ b/dev/null
@@ -1,296 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
26}
27
28if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
29if (typeof(Clipperz.Crypto.SHA) == 'undefined') { Clipperz.Crypto.SHA = {}; }
30
31Clipperz.Crypto.SHA.VERSION = "0.3";
32Clipperz.Crypto.SHA.NAME = "Clipperz.Crypto.SHA";
33
34MochiKit.Base.update(Clipperz.Crypto.SHA, {
35
36 '__repr__': function () {
37 return "[" + this.NAME + " " + this.VERSION + "]";
38 },
39
40 'toString': function () {
41 return this.__repr__();
42 },
43
44 //-----------------------------------------------------------------------------
45
46 'rotateRight': function(aValue, aNumberOfBits) {
47//Clipperz.Profile.start("Clipperz.Crypto.SHA.rotateRight");
48 var result;
49
50 result = (aValue >>> aNumberOfBits) | (aValue << (32 - aNumberOfBits));
51
52//Clipperz.Profile.stop("Clipperz.Crypto.SHA.rotateRight");
53 return result;
54 },
55
56 'shiftRight': function(aValue, aNumberOfBits) {
57//Clipperz.Profile.start("Clipperz.Crypto.SHA.shiftRight");
58 var result;
59
60 result = aValue >>> aNumberOfBits;
61
62//Clipperz.Profile.stop("Clipperz.Crypto.SHA.shiftRight");
63 return result;
64 },
65
66 //-----------------------------------------------------------------------------
67
68 'safeAdd': function() {
69//Clipperz.Profile.start("Clipperz.Crypto.SHA.safeAdd");
70 varresult;
71 vari, c;
72
73 result = arguments[0];
74 c = arguments.length;
75 for (i=1; i<c; i++) {
76 varlowerBytesSum;
77
78 lowerBytesSum = (result & 0xffff) + (arguments[i] & 0xffff);
79 result = (((result >> 16) + (arguments[i] >> 16) + (lowerBytesSum >> 16)) << 16) | (lowerBytesSum & 0xffff);
80 }
81
82//Clipperz.Profile.stop("Clipperz.Crypto.SHA.safeAdd");
83 return result;
84 },
85
86 //-----------------------------------------------------------------------------
87
88 'sha256_array': function(aValue) {
89//Clipperz.Profile.start("Clipperz.Crypto.SHA.sha256_array");
90 varresult;
91 varmessage;
92 var h0, h1, h2, h3, h4, h5, h6, h7;
93 vark;
94 varmessageLength;
95 varmessageLengthInBits;
96 var_i, _c;
97 var charBits;
98 var rotateRight;
99 var shiftRight;
100 var safeAdd;
101 varbytesPerBlock;
102 var currentMessageIndex;
103
104 bytesPerBlock = 512/8;
105 rotateRight = Clipperz.Crypto.SHA.rotateRight;
106 shiftRight = Clipperz.Crypto.SHA.shiftRight;
107 safeAdd = Clipperz.Crypto.SHA.safeAdd;
108
109 charBits = 8;
110
111 h0 = 0x6a09e667;
112 h1 = 0xbb67ae85;
113 h2 = 0x3c6ef372;
114 h3 = 0xa54ff53a;
115 h4 = 0x510e527f;
116 h5 = 0x9b05688c;
117 h6 = 0x1f83d9ab;
118 h7 = 0x5be0cd19;
119
120 k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
121 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
122 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
123 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
124 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
125 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
126 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
127 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
128
129 message = aValue;
130 messageLength = message.length;
131
132 //Pre-processing:
133 message.push(0x80); //append a single "1" bit to message
134
135 _c = (512 - (((messageLength + 1) * charBits) % 512) - 64) / charBits;
136 if (_c < 0) {
137 _c = _c + (512 / charBits);
138 }
139
140 for (_i=0; _i<_c; _i++) {
141 message.push(0x00); //append "0" bits until message length ≡ 448 ≡ -64 (mod 512)
142 }
143
144 messageLengthInBits = messageLength * charBits;
145 message.push(0x00); //the 4 most high byte are alway 0 as message length is represented with a 32bit value;
146 message.push(0x00);
147 message.push(0x00);
148 message.push(0x00);
149 message.push((messageLengthInBits >> 24)& 0xff);
150 message.push((messageLengthInBits >> 16)& 0xff);
151 message.push((messageLengthInBits >> 8) & 0xff);
152 message.push( messageLengthInBits & 0xff);
153
154 currentMessageIndex = 0;
155 while(currentMessageIndex < message.length) {
156 varw;
157 vara, b, c, d, e, f, g, h;
158
159 w = Array(64);
160
161 _c = 16;
162 for (_i=0; _i<_c; _i++) {
163 var _j;
164
165 _j = currentMessageIndex + _i*4;
166 w[_i] = (message[_j] << 24) | (message[_j + 1] << 16) | (message[_j + 2] << 8) | (message[_j + 3] << 0);
167 }
168
169 _c = 64;
170 for (_i=16; _i<_c; _i++) {
171 vars0, s1;
172
173 s0 = (rotateRight(w[_i-15], 7)) ^ (rotateRight(w[_i-15], 18)) ^ (shiftRight(w[_i-15], 3));
174 s1 = (rotateRight(w[_i-2], 17)) ^ (rotateRight(w[_i-2], 19)) ^ (shiftRight(w[_i-2], 10));
175 w[_i] = safeAdd(w[_i-16], s0, w[_i-7], s1);
176 }
177
178 a=h0; b=h1; c=h2; d=h3; e=h4; f=h5; g=h6; h=h7;
179
180 _c = 64;
181 for (_i=0; _i<_c; _i++) {
182 var s0, s1, ch, maj, t1, t2;
183
184 s0 = (rotateRight(a, 2)) ^ (rotateRight(a, 13)) ^ (rotateRight(a, 22));
185 maj = (a & b) ^ (a & c) ^ (b & c);
186 t2 = safeAdd(s0, maj);
187 s1 = (rotateRight(e, 6)) ^ (rotateRight(e, 11)) ^ (rotateRight(e, 25));
188 ch = (e & f) ^ ((~e) & g);
189 t1 = safeAdd(h, s1, ch, k[_i], w[_i]);
190
191 h = g;
192 g = f;
193 f = e;
194 e = safeAdd(d, t1);
195 d = c;
196 c = b;
197 b = a;
198 a = safeAdd(t1, t2);
199 }
200
201 h0 = safeAdd(h0, a);
202 h1 = safeAdd(h1, b);
203 h2 = safeAdd(h2, c);
204 h3 = safeAdd(h3, d);
205 h4 = safeAdd(h4, e);
206 h5 = safeAdd(h5, f);
207 h6 = safeAdd(h6, g);
208 h7 = safeAdd(h7, h);
209
210 currentMessageIndex += bytesPerBlock;
211 }
212
213 result = new Array(256/8);
214 result[0] = (h0 >> 24)& 0xff;
215 result[1] = (h0 >> 16)& 0xff;
216 result[2] = (h0 >> 8)& 0xff;
217 result[3] = h0 & 0xff;
218
219 result[4] = (h1 >> 24)& 0xff;
220 result[5] = (h1 >> 16)& 0xff;
221 result[6] = (h1 >> 8)& 0xff;
222 result[7] = h1 & 0xff;
223
224 result[8] = (h2 >> 24)& 0xff;
225 result[9] = (h2 >> 16)& 0xff;
226 result[10] = (h2 >> 8)& 0xff;
227 result[11] = h2 & 0xff;
228
229 result[12] = (h3 >> 24)& 0xff;
230 result[13] = (h3 >> 16)& 0xff;
231 result[14] = (h3 >> 8)& 0xff;
232 result[15] = h3 & 0xff;
233
234 result[16] = (h4 >> 24)& 0xff;
235 result[17] = (h4 >> 16)& 0xff;
236 result[18] = (h4 >> 8)& 0xff;
237 result[19] = h4 & 0xff;
238
239 result[20] = (h5 >> 24)& 0xff;
240 result[21] = (h5 >> 16)& 0xff;
241 result[22] = (h5 >> 8)& 0xff;
242 result[23] = h5 & 0xff;
243
244 result[24] = (h6 >> 24)& 0xff;
245 result[25] = (h6 >> 16)& 0xff;
246 result[26] = (h6 >> 8)& 0xff;
247 result[27] = h6 & 0xff;
248
249 result[28] = (h7 >> 24)& 0xff;
250 result[29] = (h7 >> 16)& 0xff;
251 result[30] = (h7 >> 8)& 0xff;
252 result[31] = h7 & 0xff;
253
254//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256_array");
255 return result;
256 },
257
258 //-----------------------------------------------------------------------------
259
260 'sha256': function(aValue) {
261//Clipperz.Profile.start("Clipperz.Crypto.SHA.sha256");
262 var result;
263 var resultArray;
264 varvalueArray;
265
266 valueArray = aValue.arrayValues();
267 resultArray = Clipperz.Crypto.SHA.sha256_array(valueArray);
268
269 result = new Clipperz.ByteArray(resultArray);
270
271//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256");
272 return result;
273 },
274
275 //-----------------------------------------------------------------------------
276
277 'sha_d256': function(aValue) {
278//Clipperz.Profile.start("Clipperz.Crypto.SHA.sha_d256");
279 var result;
280 var resultArray;
281 varvalueArray;
282
283 valueArray = aValue.arrayValues();
284 resultArray = Clipperz.Crypto.SHA.sha256_array(valueArray);
285 resultArray = Clipperz.Crypto.SHA.sha256_array(resultArray);
286
287 result = new Clipperz.ByteArray(resultArray);
288
289//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256");
290 return result;
291 },
292
293 //-----------------------------------------------------------------------------
294 __syntaxFix__: "syntax fix"
295
296});
diff --git a/frontend/gamma/js/ClipperzCryptoLibrary/SRP.js b/frontend/gamma/js/ClipperzCryptoLibrary/SRP.js
deleted file mode 100644
index 8cc80ba..0000000
--- a/frontend/gamma/js/ClipperzCryptoLibrary/SRP.js
+++ b/dev/null
@@ -1,326 +0,0 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
26}
27
28try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) {
29 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!";
30}
31
32try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) {
33 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!";
34}
35
36if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; }
37
38Clipperz.Crypto.SRP.VERSION = "0.1";
39Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP";
40
41//#############################################################################
42
43MochiKit.Base.update(Clipperz.Crypto.SRP, {
44
45 '_n': null,
46 '_g': null,
47 //-------------------------------------------------------------------------
48
49 'n': function() {
50 if (Clipperz.Crypto.SRP._n == null) {
51 Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16);
52 }
53
54 return Clipperz.Crypto.SRP._n;
55 },
56
57 //-------------------------------------------------------------------------
58
59 'g': function() {
60 if (Clipperz.Crypto.SRP._g == null) {
61 Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation)
62 }
63
64 return Clipperz.Crypto.SRP._g;
65 },
66
67 //-----------------------------------------------------------------------------
68
69 'exception': {
70 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue")
71 },
72
73 //-------------------------------------------------------------------------
74 __syntaxFix__: "syntax fix"
75
76});
77
78//#############################################################################
79//
80 // S R P C o n n e c t i o n version 1.0
81//
82//=============================================================================
83Clipperz.Crypto.SRP.Connection = function (args) {
84 args = args || {};
85
86 this._C = args.C;
87 this._P = args.P;
88 this.hash = args.hash;
89
90 this._a = null;
91 this._A = null;
92
93 this._s = null;
94 this._B = null;
95
96 this._x = null;
97
98 this._u = null;
99 this._K = null;
100 this._M1 = null;
101 this._M2 = null;
102
103 this._sessionKey = null;
104
105 return this;
106}
107
108Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
109
110 'toString': function () {
111 return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription();
112 },
113
114 //-------------------------------------------------------------------------
115
116 'C': function () {
117 return this._C;
118 },
119
120 //-------------------------------------------------------------------------
121
122 'P': function () {
123 return this._P;
124 },
125
126 //-------------------------------------------------------------------------
127
128 'a': function () {
129 if (this._a == null) {
130 this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16);
131 // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10);
132//MochiKit.Logging.logDebug("SRP a: " + this._a);
133 }
134
135 return this._a;
136 },
137
138 //-------------------------------------------------------------------------
139
140 'A': function () {
141 if (this._A == null) {
142 //Warning: this value should be strictly greater than zero: how should we perform this check?
143 this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n());
144
145 if (this._A.equals(0)) {
146MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0.");
147 throw Clipperz.Crypto.SRP.exception.InvalidValue;
148 }
149//MochiKit.Logging.logDebug("SRP A: " + this._A);
150 }
151
152 return this._A;
153 },
154
155 //-------------------------------------------------------------------------
156
157 's': function () {
158 return this._s;
159//MochiKit.Logging.logDebug("SRP s: " + this._S);
160 },
161
162 'set_s': function(aValue) {
163 this._s = aValue;
164 },
165
166 //-------------------------------------------------------------------------
167
168 'B': function () {
169 return this._B;
170 },
171
172 'set_B': function(aValue) {
173 //Warning: this value should be strictly greater than zero: how should we perform this check?
174 if (! aValue.equals(0)) {
175 this._B = aValue;
176//MochiKit.Logging.logDebug("SRP B: " + this._B);
177 } else {
178MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0.");
179 throw Clipperz.Crypto.SRP.exception.InvalidValue;
180 }
181 },
182
183 //-------------------------------------------------------------------------
184
185 'x': function () {
186 if (this._x == null) {
187 this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16);
188//MochiKit.Logging.logDebug("SRP x: " + this._x);
189 }
190
191 return this._x;
192 },
193
194 //-------------------------------------------------------------------------
195
196 'u': function () {
197 if (this._u == null) {
198 this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.B().asString()), 16);
199//MochiKit.Logging.logDebug("SRP u: " + this._u);
200 }
201
202 return this._u;
203 },
204
205 //-------------------------------------------------------------------------
206
207 'S': function () {
208 if (this._S == null) {
209 var bigint;
210 varsrp;
211
212 bigint = Clipperz.Crypto.BigInt;
213 srp = Clipperz.Crypto.SRP;
214
215 this._S =bigint.powerModule(
216 bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())),
217 bigint.add(this.a(), bigint.multiply(this.u(), this.x())),
218 srp.n()
219 )
220//MochiKit.Logging.logDebug("SRP S: " + this._S);
221 }
222
223 return this._S;
224 },
225
226 //-------------------------------------------------------------------------
227
228 'K': function () {
229 if (this._K == null) {
230 this._K = this.stringHash(this.S().asString());
231//MochiKit.Logging.logDebug("SRP K: " + this._K);
232 }
233
234 return this._K;
235 },
236
237 //-------------------------------------------------------------------------
238
239 'M1': function () {
240 if (this._M1 == null) {
241 this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K());
242//MochiKit.Logging.logDebug("SRP M1: " + this._M1);
243 }
244
245 return this._M1;
246 },
247
248 //-------------------------------------------------------------------------
249
250 'M2': function () {
251 if (this._M2 == null) {
252 this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K());
253//MochiKit.Logging.logDebug("SRP M2: " + this._M2);
254 }
255
256 return this._M2;
257 },
258
259 //=========================================================================
260
261 'serverSideCredentialsWithSalt': function(aSalt) {
262 var result;
263 var s, x, v;
264
265 s = aSalt;
266 x = this.stringHash(s + this.P());
267 v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n());
268
269 result = {};
270 result['C'] = this.C();
271 result['s'] = s;
272 result['v'] = v.asString(16);
273
274 return result;
275 },
276
277 'serverSideCredentials': function() {
278 var result;
279 var s;
280
281 s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
282
283 result = this.serverSideCredentialsWithSalt(s);
284
285 return result;
286 },
287
288 //=========================================================================
289/*
290 'computeServerSide_S': function(b) {
291 var result;
292 var v;
293 var bigint;
294 varsrp;
295
296 bigint = Clipperz.Crypto.BigInt;
297 srp = Clipperz.Crypto.SRP;
298
299 v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16);
300 // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n());
301 result = bigint.powerModule(
302 bigint.multiply(
303 this.A(),
304 bigint.powerModule(v, this.u(), srp.n())
305 ), new Clipperz.Crypto.BigInt(b, 10), srp.n()
306 );
307
308 return result;
309 },
310*/
311 //=========================================================================
312
313 'stringHash': function(aValue) {
314 varresult;
315
316 result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2);
317
318 return result;
319 },
320
321 //=========================================================================
322 __syntaxFix__: "syntax fix"
323
324});
325
326//#############################################################################