summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/Clipperz/Crypto/PRNG.js
Unidiff
Diffstat (limited to 'frontend/gamma/js/Clipperz/Crypto/PRNG.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/PRNG.js855
1 files changed, 855 insertions, 0 deletions
diff --git a/frontend/gamma/js/Clipperz/Crypto/PRNG.js b/frontend/gamma/js/Clipperz/Crypto/PRNG.js
new file mode 100644
index 0000000..266b909
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/PRNG.js
@@ -0,0 +1,855 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
31}
32
33try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) {
34 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!";
35}
36
37try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) {
38 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!";
39}
40
41if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; }
42
43//#############################################################################
44
45Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) {
46 args = args || {};
47 //MochiKit.Base.bindMethods(this);
48
49 this._stack = new Clipperz.ByteArray();
50 this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256;
51 return this;
52}
53
54Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, {
55
56 'toString': function() {
57 return "Clipperz.Crypto.PRNG.EntropyAccumulator";
58 },
59
60 //-------------------------------------------------------------------------
61
62 'stack': function() {
63 return this._stack;
64 },
65
66 'setStack': function(aValue) {
67 this._stack = aValue;
68 },
69
70 'resetStack': function() {
71 this.stack().reset();
72 },
73
74 'maxStackLengthBeforeHashing': function() {
75 return this._maxStackLengthBeforeHashing;
76 },
77
78 //-------------------------------------------------------------------------
79
80 'addRandomByte': function(aValue) {
81 this.stack().appendByte(aValue);
82
83 if (this.stack().length() > this.maxStackLengthBeforeHashing()) {
84 this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack()));
85 }
86 },
87
88 //-------------------------------------------------------------------------
89 __syntaxFix__: "syntax fix"
90});
91
92//#############################################################################
93
94Clipperz.Crypto.PRNG.RandomnessSource = function(args) {
95 args = args || {};
96 MochiKit.Base.bindMethods(this);
97
98 this._generator = args.generator || null;
99 this._sourceId = args.sourceId || null;
100 this._boostMode = args.boostMode || false;
101
102 this._nextPoolIndex = 0;
103
104 return this;
105}
106
107Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, {
108
109 'generator': function() {
110 return this._generator;
111 },
112
113 'setGenerator': function(aValue) {
114 this._generator = aValue;
115 },
116
117 //-------------------------------------------------------------------------
118
119 'boostMode': function() {
120 return this._boostMode;
121 },
122
123 'setBoostMode': function(aValue) {
124 this._boostMode = aValue;
125 },
126
127 //-------------------------------------------------------------------------
128
129 'sourceId': function() {
130 return this._sourceId;
131 },
132
133 'setSourceId': function(aValue) {
134 this._sourceId = aValue;
135 },
136
137 //-------------------------------------------------------------------------
138
139 'nextPoolIndex': function() {
140 return this._nextPoolIndex;
141 },
142
143 'incrementNextPoolIndex': function() {
144 this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators());
145 },
146
147 //-------------------------------------------------------------------------
148
149 'updateGeneratorWithValue': function(aRandomValue) {
150 if (this.generator() != null) {
151 this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue);
152 this.incrementNextPoolIndex();
153 }
154 },
155
156 //-------------------------------------------------------------------------
157 __syntaxFix__: "syntax fix"
158});
159
160//#############################################################################
161
162Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) {
163 args = args || {};
164 //MochiKit.Base.bindMethods(this);
165
166 this._intervalTime = args.intervalTime || 1000;
167
168 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
169
170 this.collectEntropy();
171 return this;
172}
173
174Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
175
176 'intervalTime': function() {
177 return this._intervalTime;
178 },
179
180 //-------------------------------------------------------------------------
181
182 'collectEntropy': function() {
183 varnow;
184 varentropyByte;
185 var intervalTime;
186 now = new Date();
187 entropyByte = (now.getTime() & 0xff);
188
189 intervalTime = this.intervalTime();
190 if (this.boostMode() == true) {
191 intervalTime = intervalTime / 9;
192 }
193
194 this.updateGeneratorWithValue(entropyByte);
195 setTimeout(this.collectEntropy, intervalTime);
196 },
197
198 //-------------------------------------------------------------------------
199
200 'numberOfRandomBits': function() {
201 return 5;
202 },
203
204 //-------------------------------------------------------------------------
205
206 'pollingFrequency': function() {
207 return 10;
208 },
209
210 //-------------------------------------------------------------------------
211 __syntaxFix__: "syntax fix"
212});
213
214//*****************************************************************************
215
216Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) {
217 args = args || {};
218
219 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
220
221 this._numberOfBitsToCollectAtEachEvent = 4;
222 this._randomBitsCollector = 0;
223 this._numberOfRandomBitsCollected = 0;
224
225 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy');
226
227 return this;
228}
229
230Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
231
232 //-------------------------------------------------------------------------
233
234 'numberOfBitsToCollectAtEachEvent': function() {
235 return this._numberOfBitsToCollectAtEachEvent;
236 },
237
238 //-------------------------------------------------------------------------
239
240 'randomBitsCollector': function() {
241 return this._randomBitsCollector;
242 },
243
244 'setRandomBitsCollector': function(aValue) {
245 this._randomBitsCollector = aValue;
246 },
247
248 'appendRandomBitsToRandomBitsCollector': function(aValue) {
249 var collectedBits;
250 var numberOfRandomBitsCollected;
251
252 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
253 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
254 this.setRandomBitsCollector(collectetBits);
255 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent();
256
257 if (numberOfRandomBitsCollected == 8) {
258 this.updateGeneratorWithValue(collectetBits);
259 numberOfRandomBitsCollected = 0;
260 this.setRandomBitsCollector(0);
261 }
262
263 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
264 },
265
266 //-------------------------------------------------------------------------
267
268 'numberOfRandomBitsCollected': function() {
269 return this._numberOfRandomBitsCollected;
270 },
271
272 'setNumberOfRandomBitsCollected': function(aValue) {
273 this._numberOfRandomBitsCollected = aValue;
274 },
275
276 //-------------------------------------------------------------------------
277
278 'collectEntropy': function(anEvent) {
279 var mouseLocation;
280 var randomBit;
281 var mask;
282
283 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent());
284
285 mouseLocation = anEvent.mouse().client;
286 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask);
287 this.appendRandomBitsToRandomBitsCollector(randomBit)
288 },
289
290 //-------------------------------------------------------------------------
291
292 'numberOfRandomBits': function() {
293 return 1;
294 },
295
296 //-------------------------------------------------------------------------
297
298 'pollingFrequency': function() {
299 return 10;
300 },
301
302 //-------------------------------------------------------------------------
303 __syntaxFix__: "syntax fix"
304});
305
306//*****************************************************************************
307
308Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) {
309 args = args || {};
310 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
311
312 this._randomBitsCollector = 0;
313 this._numberOfRandomBitsCollected = 0;
314
315 MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy');
316
317 return this;
318}
319
320Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
321
322 //-------------------------------------------------------------------------
323
324 'randomBitsCollector': function() {
325 return this._randomBitsCollector;
326 },
327
328 'setRandomBitsCollector': function(aValue) {
329 this._randomBitsCollector = aValue;
330 },
331
332 'appendRandomBitToRandomBitsCollector': function(aValue) {
333 var collectedBits;
334 var numberOfRandomBitsCollected;
335
336 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
337 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
338 this.setRandomBitsCollector(collectetBits);
339 numberOfRandomBitsCollected ++;
340
341 if (numberOfRandomBitsCollected == 8) {
342 this.updateGeneratorWithValue(collectetBits);
343 numberOfRandomBitsCollected = 0;
344 this.setRandomBitsCollector(0);
345 }
346
347 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
348 },
349
350 //-------------------------------------------------------------------------
351
352 'numberOfRandomBitsCollected': function() {
353 return this._numberOfRandomBitsCollected;
354 },
355
356 'setNumberOfRandomBitsCollected': function(aValue) {
357 this._numberOfRandomBitsCollected = aValue;
358 },
359
360 //-------------------------------------------------------------------------
361
362 'collectEntropy': function(anEvent) {
363/*
364 var mouseLocation;
365 var randomBit;
366
367 mouseLocation = anEvent.mouse().client;
368
369 randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1);
370 this.appendRandomBitToRandomBitsCollector(randomBit);
371*/
372 },
373
374 //-------------------------------------------------------------------------
375
376 'numberOfRandomBits': function() {
377 return 1;
378 },
379
380 //-------------------------------------------------------------------------
381
382 'pollingFrequency': function() {
383 return 10;
384 },
385
386 //-------------------------------------------------------------------------
387 __syntaxFix__: "syntax fix"
388});
389
390//#############################################################################
391
392Clipperz.Crypto.PRNG.Fortuna = function(args) {
393 vari,c;
394
395 args = args || {};
396
397 this._key = args.seed || null;
398 if (this._key == null) {
399 this._counter = 0;
400 this._key = new Clipperz.ByteArray();
401 } else {
402 this._counter = 1;
403 }
404
405 this._aesKey = null;
406
407 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64;
408 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32;
409
410 this._accumulators = [];
411 c = this.numberOfEntropyAccumulators();
412 for (i=0; i<c; i++) {
413 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator());
414 }
415
416 this._randomnessSources = [];
417 this._reseedCounter = 0;
418
419 return this;
420}
421
422Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, {
423
424 'toString': function() {
425 return "Clipperz.Crypto.PRNG.Fortuna";
426 },
427
428 //-------------------------------------------------------------------------
429
430 'key': function() {
431 return this._key;
432 },
433
434 'setKey': function(aValue) {
435 this._key = aValue;
436 this._aesKey = null;
437 },
438
439 'aesKey': function() {
440 if (this._aesKey == null) {
441 this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()});
442 }
443
444 return this._aesKey;
445 },
446
447 'accumulators': function() {
448 return this._accumulators;
449 },
450
451 'firstPoolReseedLevel': function() {
452 return this._firstPoolReseedLevel;
453 },
454
455 //-------------------------------------------------------------------------
456
457 'reseedCounter': function() {
458 return this._reseedCounter;
459 },
460
461 'incrementReseedCounter': function() {
462 this._reseedCounter = this._reseedCounter +1;
463 },
464
465 //-------------------------------------------------------------------------
466
467 'reseed': function() {
468 varnewKeySeed;
469 var reseedCounter;
470 varreseedCounterMask;
471 var i, c;
472
473 newKeySeed = this.key();
474 this.incrementReseedCounter();
475 reseedCounter = this.reseedCounter();
476
477 c = this.numberOfEntropyAccumulators();
478 reseedCounterMask = 0xffffffff >>> (32 - c);
479 for (i=0; i<c; i++) {
480 if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) {
481 newKeySeed.appendBlock(this.accumulators()[i].stack());
482 this.accumulators()[i].resetStack();
483 }
484 }
485
486 if (reseedCounter == 1) {
487 c = this.randomnessSources().length;
488 for (i=0; i<c; i++) {
489 this.randomnessSources()[i].setBoostMode(false);
490 }
491 }
492
493 this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed));
494 if (reseedCounter == 1) {
495//MochiKit.Logging.logDebug("### PRNG.readyToGenerateRandomBytes");
496Clipperz.log("### PRNG.readyToGenerateRandomBytes");
497 MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes');
498 }
499 MochiKit.Signal.signal(this, 'reseeded');
500 },
501
502 //-------------------------------------------------------------------------
503
504 'isReadyToGenerateRandomValues': function() {
505 return this.reseedCounter() != 0;
506 },
507
508 //-------------------------------------------------------------------------
509
510 'entropyLevel': function() {
511 return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel());
512 },
513
514 //-------------------------------------------------------------------------
515
516 'counter': function() {
517 return this._counter;
518 },
519
520 'incrementCounter': function() {
521 this._counter += 1;
522 },
523
524 'counterBlock': function() {
525 var result;
526
527 result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0);
528
529 return result;
530 },
531
532 //-------------------------------------------------------------------------
533
534 'getRandomBlock': function() {
535 var result;
536
537 result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues()));
538 this.incrementCounter();
539
540 return result;
541 },
542
543 //-------------------------------------------------------------------------
544
545 'getRandomBytes': function(aSize) {
546 var result;
547
548 if (this.isReadyToGenerateRandomValues()) {
549 var i,c;
550 var newKey;
551
552 result = new Clipperz.ByteArray();
553
554 c = Math.ceil(aSize / (128 / 8));
555 for (i=0; i<c; i++) {
556 result.appendBlock(this.getRandomBlock());
557 }
558
559 if (result.length() != aSize) {
560 result = result.split(0, aSize);
561 }
562
563 newKey = this.getRandomBlock().appendBlock(this.getRandomBlock());
564 this.setKey(newKey);
565 } else {
566MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
567 throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy;
568 }
569
570 return result;
571 },
572
573 //-------------------------------------------------------------------------
574
575 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) {
576 varselectedAccumulator;
577
578 selectedAccumulator = this.accumulators()[aPoolId];
579 selectedAccumulator.addRandomByte(aRandomValue);
580
581 if (aPoolId == 0) {
582 MochiKit.Signal.signal(this, 'addedRandomByte')
583 if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) {
584 this.reseed();
585 }
586 }
587 },
588
589 //-------------------------------------------------------------------------
590
591 'numberOfEntropyAccumulators': function() {
592 return this._numberOfEntropyAccumulators;
593 },
594
595 //-------------------------------------------------------------------------
596
597 'randomnessSources': function() {
598 return this._randomnessSources;
599 },
600
601 'addRandomnessSource': function(aRandomnessSource) {
602 aRandomnessSource.setGenerator(this);
603 aRandomnessSource.setSourceId(this.randomnessSources().length);
604 this.randomnessSources().push(aRandomnessSource);
605
606 if (this.isReadyToGenerateRandomValues() == false) {
607 aRandomnessSource.setBoostMode(true);
608 }
609 },
610
611 //-------------------------------------------------------------------------
612
613 'deferredEntropyCollection': function(aValue) {
614 var result;
615
616//MochiKit.Logging.logDebug(">>> PRNG.deferredEntropyCollection");
617
618 if (this.isReadyToGenerateRandomValues()) {
619//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 1");
620 result = aValue;
621 } else {
622//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 2");
623 var deferredResult;
624
625 // Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true);
626
627 deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection");
628 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.1 - PRNG.deferredEntropyCollection - 1: " + res); return res;});
629 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
630 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.2 - PRNG.deferredEntropyCollection - 2: " + res); return res;});
631 MochiKit.Signal.connect(this,
632 'readyToGenerateRandomBytes',
633 deferredResult,
634 'callback');
635
636 result = deferredResult;
637 }
638//MochiKit.Logging.logDebug("<<< PRNG.deferredEntropyCollection - result: " + result);
639
640 return result;
641 },
642
643 //-------------------------------------------------------------------------
644
645 'fastEntropyAccumulationForTestingPurpose': function() {
646 while (! this.isReadyToGenerateRandomValues()) {
647 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256));
648 }
649 },
650
651 //-------------------------------------------------------------------------
652
653 'dump': function(appendToDoc) {
654 var tbl;
655 var i,c;
656
657 tbl = document.createElement("table");
658 tbl.border = 0;
659 with (tbl.style) {
660 border = "1px solid lightgrey";
661 fontFamily = 'Helvetica, Arial, sans-serif';
662 fontSize = '8pt';
663 //borderCollapse = "collapse";
664 }
665 var hdr = tbl.createTHead();
666 var hdrtr = hdr.insertRow(0);
667 // document.createElement("tr");
668 {
669 var ntd;
670
671 ntd = hdrtr.insertCell(0);
672 ntd.style.borderBottom = "1px solid lightgrey";
673 ntd.style.borderRight = "1px solid lightgrey";
674 ntd.appendChild(document.createTextNode("#"));
675
676 ntd = hdrtr.insertCell(1);
677 ntd.style.borderBottom = "1px solid lightgrey";
678 ntd.style.borderRight = "1px solid lightgrey";
679 ntd.appendChild(document.createTextNode("s"));
680
681 ntd = hdrtr.insertCell(2);
682 ntd.colSpan = this.firstPoolReseedLevel();
683 ntd.style.borderBottom = "1px solid lightgrey";
684 ntd.style.borderRight = "1px solid lightgrey";
685 ntd.appendChild(document.createTextNode("base values"));
686
687 ntd = hdrtr.insertCell(3);
688 ntd.colSpan = 20;
689 ntd.style.borderBottom = "1px solid lightgrey";
690 ntd.appendChild(document.createTextNode("extra values"));
691
692 }
693
694 c = this.accumulators().length;
695 for (i=0; i<c ; i++) {
696 varcurrentAccumulator;
697 var bdytr;
698 var bdytd;
699 var ii, cc;
700
701 currentAccumulator = this.accumulators()[i]
702
703 bdytr = tbl.insertRow(true);
704
705 bdytd = bdytr.insertCell(0);
706 bdytd.style.borderRight = "1px solid lightgrey";
707 bdytd.style.color = "lightgrey";
708 bdytd.appendChild(document.createTextNode("" + i));
709
710 bdytd = bdytr.insertCell(1);
711 bdytd.style.borderRight = "1px solid lightgrey";
712 bdytd.style.color = "gray";
713 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length()));
714
715
716 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel());
717 for (ii=0; ii<cc; ii++) {
718 var cellText;
719
720 bdytd = bdytr.insertCell(ii + 2);
721
722 if (ii < currentAccumulator.stack().length()) {
723 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii));
724 } else {
725 cellText = "_";
726 }
727
728 if (ii == (this.firstPoolReseedLevel() - 1)) {
729 bdytd.style.borderRight = "1px solid lightgrey";
730 }
731
732 bdytd.appendChild(document.createTextNode(cellText));
733 }
734
735 }
736
737
738 if (appendToDoc) {
739 var ne = document.createElement("div");
740 ne.id = "entropyGeneratorStatus";
741 with (ne.style) {
742 fontFamily = "Courier New, monospace";
743 fontSize = "12px";
744 lineHeight = "16px";
745 borderTop = "1px solid black";
746 padding = "10px";
747 }
748 if (document.getElementById(ne.id)) {
749 MochiKit.DOM.swapDOM(ne.id, ne);
750 } else {
751 document.body.appendChild(ne);
752 }
753 ne.appendChild(tbl);
754 }
755
756 return tbl;
757 },
758
759 //-----------------------------------------------------------------------------
760 __syntaxFix__: "syntax fix"
761});
762
763//#############################################################################
764
765Clipperz.Crypto.PRNG.Random = function(args) {
766 args = args || {};
767 //MochiKit.Base.bindMethods(this);
768
769 return this;
770}
771
772Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
773
774 'toString': function() {
775 return "Clipperz.Crypto.PRNG.Random";
776 },
777
778 //-------------------------------------------------------------------------
779
780 'getRandomBytes': function(aSize) {
781//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes");
782 varresult;
783 var i,c;
784
785 result = new Clipperz.ByteArray()
786 c = aSize || 1;
787 for (i=0; i<c; i++) {
788 result.appendByte((Math.random()*255) & 0xff);
789 }
790
791//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes");
792 return result;
793 },
794
795 //-------------------------------------------------------------------------
796 __syntaxFix__: "syntax fix"
797});
798
799//#############################################################################
800
801_clipperz_crypt_prng_defaultPRNG = null;
802
803Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
804 if (_clipperz_crypt_prng_defaultPRNG == null) {
805 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna();
806
807 //.............................................................
808 //
809 // TimeRandomnessSource
810 //
811 //.............................................................
812 {
813 var newRandomnessSource;
814
815 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111});
816 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
817 }
818
819 //.............................................................
820 //
821 // MouseRandomnessSource
822 //
823 //.............................................................
824 {
825 varnewRandomnessSource;
826
827 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
828 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
829 }
830
831 //.............................................................
832 //
833 // KeyboardRandomnessSource
834 //
835 //.............................................................
836 {
837 varnewRandomnessSource;
838
839 newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource();
840 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
841 }
842
843 }
844
845 return _clipperz_crypt_prng_defaultPRNG;
846};
847
848//#############################################################################
849
850Clipperz.Crypto.PRNG.exception = {
851 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
852};
853
854
855MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator);