summaryrefslogtreecommitdiff
path: root/frontend/beta/js/Clipperz/Crypto/AES.js
Unidiff
Diffstat (limited to 'frontend/beta/js/Clipperz/Crypto/AES.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/Clipperz/Crypto/AES.js836
1 files changed, 836 insertions, 0 deletions
diff --git a/frontend/beta/js/Clipperz/Crypto/AES.js b/frontend/beta/js/Clipperz/Crypto/AES.js
new file mode 100644
index 0000000..a60df5c
--- a/dev/null
+++ b/frontend/beta/js/Clipperz/Crypto/AES.js
@@ -0,0 +1,836 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.AES depends on Clipperz.ByteArray!";
31}
32
33 //Dependency commented to avoid a circular reference
34//try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) {
35 //throw "Clipperz.Crypto.AES depends on Clipperz.Crypto.PRNG!";
36//}
37
38if (typeof(Clipperz.Crypto.AES) == 'undefined') { Clipperz.Crypto.AES = {}; }
39
40//#############################################################################
41
42Clipperz.Crypto.AES.DeferredExecutionContext = function(args) {
43 args = args || {};
44
45 this._key = args.key;
46 this._message = args.message;
47 this._result = args.message.clone();
48 this._nonce = args.nonce;
49 this._messageLength = this._message.length();
50
51 this._messageArray = this._message.arrayValues();
52 this._resultArray = this._result.arrayValues();
53 this._nonceArray = this._nonce.arrayValues();
54
55 this._executionStep = 0;
56
57 return this;
58}
59
60Clipperz.Crypto.AES.DeferredExecutionContext.prototype = MochiKit.Base.update(null, {
61
62 'key': function() {
63 return this._key;
64 },
65
66 'message': function() {
67 return this._message;
68 },
69
70 'messageLength': function() {
71 return this._messageLength;
72 },
73
74 'result': function() {
75 return new Clipperz.ByteArray(this.resultArray());
76 },
77
78 'nonce': function() {
79 return this._nonce;
80 },
81
82 'messageArray': function() {
83 return this._messageArray;
84 },
85
86 'resultArray': function() {
87 return this._resultArray;
88 },
89
90 'nonceArray': function() {
91 return this._nonceArray;
92 },
93
94 'elaborationChunkSize': function() {
95 return Clipperz.Crypto.AES.DeferredExecution.chunkSize;
96 },
97
98 'executionStep': function() {
99 return this._executionStep;
100 },
101
102 'setExecutionStep': function(aValue) {
103 this._executionStep = aValue;
104 },
105
106 'pause': function(aValue) {
107 return MochiKit.Async.wait(Clipperz.Crypto.AES.DeferredExecution.pauseTime, aValue);
108 },
109
110 //-----------------------------------------------------------------------------
111 __syntaxFix__: "syntax fix"
112
113});
114
115//#############################################################################
116
117Clipperz.Crypto.AES.Key = function(args) {
118 args = args || {};
119
120 this._key = args.key;
121 this._keySize = args.keySize || this.key().length();
122
123 if (this.keySize() == 128/8) {
124 this._b = 176;
125 this._numberOfRounds = 10;
126 } else if (this.keySize() == 256/8) {
127 this._b = 240;
128 this._numberOfRounds = 14;
129 } else {
130 MochiKit.Logging.logError("AES unsupported key size: " + (this.keySize() * 8) + " bits");
131 throw Clipperz.Crypto.AES.exception.UnsupportedKeySize;
132 }
133
134 this._stretchedKey = null;
135
136 return this;
137}
138
139Clipperz.Crypto.AES.Key.prototype = MochiKit.Base.update(null, {
140
141 'asString': function() {
142 return "Clipperz.Crypto.AES.Key (" + this.key().toHexString() + ")";
143 },
144
145 //-----------------------------------------------------------------------------
146
147 'key': function() {
148 return this._key;
149 },
150
151 'keySize': function() {
152 return this._keySize;
153 },
154
155 'b': function() {
156 return this._b;
157 },
158
159 'numberOfRounds': function() {
160 return this._numberOfRounds;
161 },
162 //=========================================================================
163
164 'keyScheduleCore': function(aWord, aRoundConstantsIndex) {
165 varresult;
166 var sbox;
167
168 sbox = Clipperz.Crypto.AES.sbox();
169
170 result = [sbox[aWord[1]] ^ Clipperz.Crypto.AES.roundConstants()[aRoundConstantsIndex],
171 sbox[aWord[2]],
172 sbox[aWord[3]],
173 sbox[aWord[0]]];
174
175 return result;
176 },
177
178 //-----------------------------------------------------------------------------
179
180 'xorWithPreviousStretchValues': function(aKey, aWord, aPreviousWordIndex) {
181 varresult;
182 var i,c;
183
184 result = [];
185 c = 4;
186 for (i=0; i<c; i++) {
187 result[i] = aWord[i] ^ aKey.byteAtIndex(aPreviousWordIndex + i);
188 }
189
190 return result;
191 },
192
193 //-----------------------------------------------------------------------------
194
195 'sboxShakeup': function(aWord) {
196 var result;
197 var sbox;
198 var i,c;
199
200 result = [];
201 sbox = Clipperz.Crypto.AES.sbox();
202 c =4;
203 for (i=0; i<c; i++) {
204 result[i] = sbox[aWord[i]];
205 }
206
207 return result;
208 },
209
210 //-----------------------------------------------------------------------------
211
212 'stretchKey': function(aKey) {
213 varcurrentWord;
214 varkeyLength;
215 varpreviousStretchIndex;
216 var i,c;
217
218 keyLength = aKey.length();
219 previousStretchIndex = keyLength - this.keySize();
220
221 currentWord = [aKey.byteAtIndex(keyLength - 4),
222 aKey.byteAtIndex(keyLength - 3),
223 aKey.byteAtIndex(keyLength - 2),
224 aKey.byteAtIndex(keyLength - 1)];
225 currentWord = this.keyScheduleCore(currentWord, keyLength / this.keySize());
226
227 if (this.keySize() == 256/8) {
228 c = 8;
229 } else if (this.keySize() == 128/8){
230 c = 4;
231 }
232
233 for (i=0; i<c; i++) {
234 if (i == 4) {
235 //fifth streatch word
236 currentWord = this.sboxShakeup(currentWord);
237 }
238
239 currentWord = this.xorWithPreviousStretchValues(aKey, currentWord, previousStretchIndex + (i*4));
240 aKey.appendBytes(currentWord);
241 }
242
243 return aKey;
244 },
245
246 //-----------------------------------------------------------------------------
247
248 'stretchedKey': function() {
249 if (this._stretchedKey == null) {
250 var stretchedKey;
251
252 stretchedKey = this.key().clone();
253
254 while (stretchedKey.length() < this.keySize()) {
255 stretchedKey.appendByte(0);
256 }
257
258 while (stretchedKey.length() < this.b()) {
259 stretchedKey = this.stretchKey(stretchedKey);
260 }
261
262 this._stretchedKey = stretchedKey.split(0, this.b());
263 }
264
265 return this._stretchedKey;
266 },
267
268 //=========================================================================
269 __syntaxFix__: "syntax fix"
270});
271
272//#############################################################################
273
274Clipperz.Crypto.AES.State = function(args) {
275 args = args || {};
276
277 this._data = args.block;
278 this._key = args.key;
279
280 return this;
281}
282
283Clipperz.Crypto.AES.State.prototype = MochiKit.Base.update(null, {
284
285 'key': function() {
286 return this._key;
287 },
288
289 //-----------------------------------------------------------------------------
290
291 'data': function() {
292 return this._data;
293 },
294
295 'setData': function(aValue) {
296 this._data = aValue;
297 },
298
299 //=========================================================================
300
301 'addRoundKey': function(aRoundNumber) {
302 //each byte of the state is combined with the round key; each round key is derived from the cipher key using a key schedule.
303 vardata;
304 varstretchedKey;
305 varfirstStretchedKeyIndex;
306 var i,c;
307
308 data = this.data();
309 stretchedKey = this.key().stretchedKey();
310 firstStretchedKeyIndex = aRoundNumber * (128/8);
311 c = 128/8;
312 for (i=0; i<c; i++) {
313 data[i] = data[i] ^ stretchedKey.byteAtIndex(firstStretchedKeyIndex + i);
314 }
315 },
316
317 //-----------------------------------------------------------------------------
318
319 'subBytes': function() {
320 // a non-linear substitution step where each byte is replaced with another according to a lookup table.
321 var i,c;
322 vardata;
323 var sbox;
324
325 data = this.data();
326 sbox = Clipperz.Crypto.AES.sbox();
327
328 c = 16;
329 for (i=0; i<c; i++) {
330 data[i] = sbox[data[i]];
331 }
332 },
333
334 //-----------------------------------------------------------------------------
335
336 'shiftRows': function() {
337 //a transposition step where each row of the state is shifted cyclically a certain number of steps.
338 varnewValue;
339 vardata;
340 varshiftMapping;
341 vari,c;
342
343 newValue = new Array(16);
344 data = this.data();
345 shiftMapping = Clipperz.Crypto.AES.shiftRowMapping();
346 // [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
347 c = 16;
348 for (i=0; i<c; i++) {
349 newValue[i] = data[shiftMapping[i]];
350 }
351 for (i=0; i<c; i++) {
352 data[i] = newValue[i];
353 }
354 },
355
356 //-----------------------------------------------------------------------------
357/*
358 'mixColumnsWithValues': function(someValues) {
359 varresult;
360 vara;
361 var i,c;
362
363 c = 4;
364 result = [];
365 a = [];
366 for (i=0; i<c; i++) {
367 a[i] = [];
368 a[i][1] = someValues[i]
369 if ((a[i][1] & 0x80) == 0x80) {
370 a[i][2] = (a[i][1] << 1) ^ 0x11b;
371 } else {
372 a[i][2] = a[i][1] << 1;
373 }
374
375 a[i][3] = a[i][2] ^ a[i][1];
376 }
377
378 for (i=0; i<c; i++) {
379 varx;
380
381 x = Clipperz.Crypto.AES.mixColumnsMatrix()[i];
382 result[i] = a[0][x[0]] ^ a[1][x[1]] ^ a[2][x[2]] ^ a[3][x[3]];
383 }
384
385 return result;
386 },
387
388 'mixColumns': function() {
389 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
390 var data;
391 var i, c;
392
393 data = this.data();
394 c = 4;
395 for(i=0; i<c; i++) {
396 varblockIndex;
397 var mixedValues;
398
399 blockIndex = i * 4;
400 mixedValues = this.mixColumnsWithValues([data[blockIndex + 0],
401 data[blockIndex + 1],
402 data[blockIndex + 2],
403 data[blockIndex + 3]]);
404 data[blockIndex + 0] = mixedValues[0];
405 data[blockIndex + 1] = mixedValues[1];
406 data[blockIndex + 2] = mixedValues[2];
407 data[blockIndex + 3] = mixedValues[3];
408 }
409 },
410*/
411
412 'mixColumns': function() {
413 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
414 var data;
415 var i, c;
416 var a_1;
417 var a_2;
418
419 a_1 = new Array(4);
420 a_2 = new Array(4);
421
422 data = this.data();
423 c = 4;
424 for(i=0; i<c; i++) {
425 varblockIndex;
426 var ii, cc;
427
428 blockIndex = i * 4;
429
430 cc = 4;
431 for (ii=0; ii<cc; ii++) {
432 var value;
433
434 value = data[blockIndex + ii];
435 a_1[ii] = value;
436 a_2[ii] = (value & 0x80) ? ((value << 1) ^ 0x011b) : (value << 1);
437 }
438
439 data[blockIndex + 0] = a_2[0] ^ a_1[1] ^ a_2[1] ^ a_1[2] ^ a_1[3];
440 data[blockIndex + 1] = a_1[0] ^ a_2[1] ^ a_1[2] ^ a_2[2] ^ a_1[3];
441 data[blockIndex + 2] = a_1[0] ^ a_1[1] ^ a_2[2] ^ a_1[3] ^ a_2[3];
442 data[blockIndex + 3] = a_1[0] ^ a_2[0] ^ a_1[1] ^ a_1[2] ^ a_2[3];
443 }
444 },
445
446 //=========================================================================
447
448 'spinRound': function(aRoundNumber) {
449 this.addRoundKey(aRoundNumber);
450 this.subBytes();
451 this.shiftRows();
452 this.mixColumns();
453 },
454
455 'spinLastRound': function() {
456 this.addRoundKey(this.key().numberOfRounds() - 1);
457 this.subBytes();
458 this.shiftRows();
459 this.addRoundKey(this.key().numberOfRounds());
460 },
461
462 //=========================================================================
463
464 'encrypt': function() {
465 vari,c;
466
467 c = this.key().numberOfRounds() - 1;
468 for (i=0; i<c; i++) {
469 this.spinRound(i);
470 }
471
472 this.spinLastRound();
473 },
474
475 //=========================================================================
476 __syntaxFix__: "syntax fix"
477});
478
479//#############################################################################
480
481Clipperz.Crypto.AES.VERSION = "0.1";
482Clipperz.Crypto.AES.NAME = "Clipperz.Crypto.AES";
483
484MochiKit.Base.update(Clipperz.Crypto.AES, {
485
486 //http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-AES.html
487 //http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
488 //http://en.wikipedia.org/wiki/Rijndael_key_schedule
489 //http://en.wikipedia.org/wiki/Rijndael_S-box
490
491 '__repr__': function () {
492 return "[" + this.NAME + " " + this.VERSION + "]";
493 },
494
495 'toString': function () {
496 return this.__repr__();
497 },
498
499 //=============================================================================
500
501 '_sbox': null,
502 'sbox': function() {
503 if (Clipperz.Crypto.AES._sbox == null) {
504 Clipperz.Crypto.AES._sbox = [
5050x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
5060xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
5070xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
5080x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
5090x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
5100x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
5110xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
5120x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
5130xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
5140x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
5150xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
5160xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
5170xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
5180x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
5190xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
5200x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
521 ];
522 }
523
524 return Clipperz.Crypto.AES._sbox;
525 },
526
527 //-----------------------------------------------------------------------------
528 //
529 // 0 4 8 12 0 4 812
530 // 1 5 9 13 => 5 9 131
531 // 2 6 10 14 10 14 26
532 // 3 7 11 15 15 3 711
533 //
534 '_shiftRowMapping': null,
535 'shiftRowMapping': function() {
536 if (Clipperz.Crypto.AES._shiftRowMapping == null) {
537 Clipperz.Crypto.AES._shiftRowMapping = [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
538 }
539
540 return Clipperz.Crypto.AES._shiftRowMapping;
541 },
542
543 //-----------------------------------------------------------------------------
544
545 '_mixColumnsMatrix': null,
546 'mixColumnsMatrix': function() {
547 if (Clipperz.Crypto.AES._mixColumnsMatrix == null) {
548 Clipperz.Crypto.AES._mixColumnsMatrix = [[2, 3, 1 ,1],
549 [1, 2, 3, 1],
550 [1, 1, 2, 3],
551 [3, 1, 1, 2] ];
552 }
553
554 return Clipperz.Crypto.AES._mixColumnsMatrix;
555 },
556
557 '_roundConstants': null,
558 'roundConstants': function() {
559 if (Clipperz.Crypto.AES._roundConstants == null) {
560 Clipperz.Crypto.AES._roundConstants = [ , 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154];
561 // Clipperz.Crypto.AES._roundConstants = [ , 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a];
562 }
563
564 return Clipperz.Crypto.AES._roundConstants;
565 },
566
567 //=============================================================================
568
569 'incrementNonce': function(aNonce) {
570//Clipperz.Profile.start("Clipperz.Crypto.AES.incrementNonce");
571 var i;
572 var done;
573
574 done = false;
575 i = aNonce.length - 1;
576
577 while ((i>=0) && (done == false)) {
578 var currentByteValue;
579
580 currentByteValue = aNonce[i];
581
582 if (currentByteValue == 0xff) {
583 aNonce[i] = 0;
584 if (i>= 0) {
585 i --;
586 } else {
587 done = true;
588 }
589 } else {
590 aNonce[i] = currentByteValue + 1;
591 done = true;
592 }
593 }
594//Clipperz.Profile.stop("Clipperz.Crypto.AES.incrementNonce");
595 },
596
597 //-----------------------------------------------------------------------------
598
599 'encryptBlock': function(aKey, aBlock) {
600 varresult;
601 varstate;
602
603 state = new Clipperz.Crypto.AES.State({block:aBlock, key:aKey});
604//is(state.data(), 'before');
605 state.encrypt();
606 result = state.data();
607
608 return result;
609 },
610
611 //-----------------------------------------------------------------------------
612
613 'encryptBlocks': function(aKey, aMessage, aNonce) {
614 varresult;
615 var nonce;
616 var self;
617 varmessageIndex;
618 varmessageLength;
619 var blockSize;
620
621 self = Clipperz.Crypto.AES;
622 blockSize = 128/8;
623 messageLength = aMessage.length;
624 nonce = aNonce;
625
626 result = aMessage;
627 messageIndex = 0;
628 while (messageIndex < messageLength) {
629 var encryptedBlock;
630 var i,c;
631
632 self.incrementNonce(nonce);
633 encryptedBlock = self.encryptBlock(aKey, nonce);
634
635 if ((messageLength - messageIndex) > blockSize) {
636 c = blockSize;
637 } else {
638 c = messageLength - messageIndex;
639 }
640
641 for (i=0; i<c; i++) {
642 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
643 }
644
645 messageIndex += blockSize;
646 }
647
648 return result;
649 },
650
651 //-----------------------------------------------------------------------------
652
653 'encrypt': function(aKey, someData, aNonce) {
654 var result;
655 var nonce;
656 varencryptedData;
657 var key;
658
659 key = new Clipperz.Crypto.AES.Key({key:aKey});
660 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
661
662 encryptedData = Clipperz.Crypto.AES.encryptBlocks(key, someData.arrayValues(), nonce.arrayValues());
663
664 result = nonce.appendBytes(encryptedData);
665
666 return result;
667 },
668
669 //-----------------------------------------------------------------------------
670
671 'decrypt': function(aKey, someData) {
672 var result;
673 var nonce;
674 var encryptedData;
675 var decryptedData;
676 vardataIterator;
677 var key;
678
679 key = new Clipperz.Crypto.AES.Key({key:aKey});
680
681 encryptedData = someData.arrayValues();
682 nonce = encryptedData.slice(0, (128/8));
683 encryptedData = encryptedData.slice(128/8);
684 decryptedData = Clipperz.Crypto.AES.encryptBlocks(key, encryptedData, nonce);
685
686 result = new Clipperz.ByteArray(decryptedData);
687
688 return result;
689 },
690
691 //=============================================================================
692
693 'deferredEncryptExecutionChunk': function(anExecutionContext) {
694 varresult;
695 var nonce;
696 var self;
697 varmessageIndex;
698 varmessageLength;
699 var blockSize;
700 var executionLimit;
701
702 self = Clipperz.Crypto.AES;
703 blockSize = 128/8;
704 messageLength = anExecutionContext.messageArray().length;
705 nonce = anExecutionContext.nonceArray();
706 result = anExecutionContext.resultArray();
707
708 messageIndex = anExecutionContext.executionStep();
709 executionLimit = messageIndex + anExecutionContext.elaborationChunkSize();
710 executionLimit = Math.min(executionLimit, messageLength);
711
712 while (messageIndex < executionLimit) {
713 var encryptedBlock;
714 var i,c;
715
716 self.incrementNonce(nonce);
717 encryptedBlock = self.encryptBlock(anExecutionContext.key(), nonce);
718
719 if ((executionLimit - messageIndex) > blockSize) {
720 c = blockSize;
721 } else {
722 c = executionLimit - messageIndex;
723 }
724
725 for (i=0; i<c; i++) {
726 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
727 }
728
729 messageIndex += blockSize;
730 }
731 anExecutionContext.setExecutionStep(messageIndex);
732
733 return anExecutionContext;
734 },
735
736 //-----------------------------------------------------------------------------
737
738 'deferredEncryptBlocks': function(anExecutionContext) {
739 vardeferredResult;
740 varmessageSize;
741 var i,c;
742 var now;
743
744 messageSize = anExecutionContext.messageLength();
745
746 deferredResult = new MochiKit.Async.Deferred();
747//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncryptBlocks - START: " + res); return res;});
748 // deferredResult.addCallback(MochiKit.Base.method(anExecutionContext, 'pause'));
749
750 c = Math.ceil(messageSize / anExecutionContext.elaborationChunkSize());
751 for (i=0; i<c; i++) {
752//deferredResult.addBoth(function(res) {now = new Date(); return res;});
753//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncryptBlocks - : (" + i + ") - " + res); return res;});
754 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptExecutionChunk);
755//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("[" + (new Date() - now) + "]Clipperz.Crypto.AES.deferredEncryptBlocks"); return res;});
756//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncryptBlocks - : (" + i + ") -- " + res); return res;});
757 deferredResult.addCallback(MochiKit.Base.method(anExecutionContext, 'pause'));
758//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncryptBlocks - : (" + i + ") --- " + res); return res;});
759 }
760//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncryptBlocks - END: " + res); return res;});
761
762 deferredResult.callback(anExecutionContext);
763
764 return deferredResult;
765 },
766
767 //-----------------------------------------------------------------------------
768
769 'deferredEncrypt': function(aKey, someData, aNonce) {
770 var deferredResult;
771 varexecutionContext;
772 var result;
773 var nonce;
774 var key;
775
776 key = new Clipperz.Crypto.AES.Key({key:aKey});
777 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
778
779 executionContext = new Clipperz.Crypto.AES.DeferredExecutionContext({key:key, message:someData, nonce:nonce});
780
781 deferredResult = new MochiKit.Async.Deferred();
782//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncrypt - 1: " + res); return res;});
783 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptBlocks);
784//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncrypt - 2: " + res); return res;});
785 deferredResult.addCallback(function(anExecutionContext) {
786 var result;
787
788 result = anExecutionContext.nonce().clone();
789 result.appendBytes(anExecutionContext.resultArray());
790
791 return result;
792 });
793//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("Clipperz.Crypto.AES.deferredEncrypt - 3: " + res); return res;});
794 deferredResult.callback(executionContext)
795
796 return deferredResult;
797 },
798
799 //-----------------------------------------------------------------------------
800
801 'deferredDecrypt': function(aKey, someData) {
802 var deferredResult
803 var nonce;
804 var message;
805 var key;
806
807 key = new Clipperz.Crypto.AES.Key({key:aKey});
808 nonce = someData.split(0, (128/8));
809 message = someData.split(128/8);
810 executionContext = new Clipperz.Crypto.AES.DeferredExecutionContext({key:key, message:message, nonce:nonce});
811
812 deferredResult = new MochiKit.Async.Deferred();
813 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptBlocks);
814 deferredResult.addCallback(function(anExecutionContext) {
815 return anExecutionContext.result();
816 });
817 deferredResult.callback(executionContext);
818
819 return deferredResult;
820 },
821
822 //-----------------------------------------------------------------------------
823 __syntaxFix__: "syntax fix"
824
825});
826
827//#############################################################################
828
829Clipperz.Crypto.AES.DeferredExecution = {
830 'chunkSize': 4096, // 1024 4096 8192 1638432768;
831 'pauseTime': 0.2
832}
833
834Clipperz.Crypto.AES.exception = {
835 'UnsupportedKeySize': new MochiKit.Base.NamedError("Clipperz.Crypto.AES.exception.UnsupportedKeySize")
836};