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