summaryrefslogtreecommitdiff
path: root/frontend/delta/js/Clipperz/Crypto/PRNG.js
Unidiff
Diffstat (limited to 'frontend/delta/js/Clipperz/Crypto/PRNG.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/Clipperz/Crypto/PRNG.js841
1 files changed, 841 insertions, 0 deletions
diff --git a/frontend/delta/js/Clipperz/Crypto/PRNG.js b/frontend/delta/js/Clipperz/Crypto/PRNG.js
new file mode 100644
index 0000000..c539f06
--- a/dev/null
+++ b/frontend/delta/js/Clipperz/Crypto/PRNG.js
@@ -0,0 +1,841 @@
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) {
490Clipperz.log("### PRNG.readyToGenerateRandomBytes");
491 MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes');
492 }
493 MochiKit.Signal.signal(this, 'reseeded');
494 },
495
496 //-------------------------------------------------------------------------
497
498 'isReadyToGenerateRandomValues': function() {
499 return this.reseedCounter() != 0;
500 },
501
502 //-------------------------------------------------------------------------
503
504 'entropyLevel': function() {
505 return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel());
506 },
507
508 //-------------------------------------------------------------------------
509
510 'counter': function() {
511 return this._counter;
512 },
513
514 'incrementCounter': function() {
515 this._counter += 1;
516 },
517
518 'counterBlock': function() {
519 var result;
520
521 result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0);
522
523 return result;
524 },
525
526 //-------------------------------------------------------------------------
527
528 'getRandomBlock': function() {
529 var result;
530
531 result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues()));
532 this.incrementCounter();
533
534 return result;
535 },
536
537 //-------------------------------------------------------------------------
538
539 'getRandomBytes': function(aSize) {
540 var result;
541
542 if (this.isReadyToGenerateRandomValues()) {
543 var i,c;
544 var newKey;
545
546 result = new Clipperz.ByteArray();
547
548 c = Math.ceil(aSize / (128 / 8));
549 for (i=0; i<c; i++) {
550 result.appendBlock(this.getRandomBlock());
551 }
552
553 if (result.length() != aSize) {
554 result = result.split(0, aSize);
555 }
556
557 newKey = this.getRandomBlock().appendBlock(this.getRandomBlock());
558 this.setKey(newKey);
559 } else {
560Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
561 throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy;
562 }
563
564 return result;
565 },
566
567 //-------------------------------------------------------------------------
568
569 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) {
570 varselectedAccumulator;
571
572 selectedAccumulator = this.accumulators()[aPoolId];
573 selectedAccumulator.addRandomByte(aRandomValue);
574
575 if (aPoolId == 0) {
576 MochiKit.Signal.signal(this, 'addedRandomByte')
577 if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) {
578 this.reseed();
579 }
580 }
581 },
582
583 //-------------------------------------------------------------------------
584
585 'numberOfEntropyAccumulators': function() {
586 return this._numberOfEntropyAccumulators;
587 },
588
589 //-------------------------------------------------------------------------
590
591 'randomnessSources': function() {
592 return this._randomnessSources;
593 },
594
595 'addRandomnessSource': function(aRandomnessSource) {
596 aRandomnessSource.setGenerator(this);
597 aRandomnessSource.setSourceId(this.randomnessSources().length);
598 this.randomnessSources().push(aRandomnessSource);
599
600 if (this.isReadyToGenerateRandomValues() == false) {
601 aRandomnessSource.setBoostMode(true);
602 }
603 },
604
605 //-------------------------------------------------------------------------
606
607 'deferredEntropyCollection': function(aValue) {
608 var result;
609
610
611 if (this.isReadyToGenerateRandomValues()) {
612 result = aValue;
613 } else {
614 var deferredResult;
615
616 deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection");
617 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
618 MochiKit.Signal.connect(this,
619 'readyToGenerateRandomBytes',
620 deferredResult,
621 'callback');
622
623 result = deferredResult;
624 }
625
626 return result;
627 },
628
629 //-------------------------------------------------------------------------
630
631 'fastEntropyAccumulationForTestingPurpose': function() {
632 while (! this.isReadyToGenerateRandomValues()) {
633 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256));
634 }
635 },
636
637 //-------------------------------------------------------------------------
638
639 'dump': function(appendToDoc) {
640 var tbl;
641 var i,c;
642
643 tbl = document.createElement("table");
644 tbl.border = 0;
645 with (tbl.style) {
646 border = "1px solid lightgrey";
647 fontFamily = 'Helvetica, Arial, sans-serif';
648 fontSize = '8pt';
649 //borderCollapse = "collapse";
650 }
651 var hdr = tbl.createTHead();
652 var hdrtr = hdr.insertRow(0);
653 // document.createElement("tr");
654 {
655 var ntd;
656
657 ntd = hdrtr.insertCell(0);
658 ntd.style.borderBottom = "1px solid lightgrey";
659 ntd.style.borderRight = "1px solid lightgrey";
660 ntd.appendChild(document.createTextNode("#"));
661
662 ntd = hdrtr.insertCell(1);
663 ntd.style.borderBottom = "1px solid lightgrey";
664 ntd.style.borderRight = "1px solid lightgrey";
665 ntd.appendChild(document.createTextNode("s"));
666
667 ntd = hdrtr.insertCell(2);
668 ntd.colSpan = this.firstPoolReseedLevel();
669 ntd.style.borderBottom = "1px solid lightgrey";
670 ntd.style.borderRight = "1px solid lightgrey";
671 ntd.appendChild(document.createTextNode("base values"));
672
673 ntd = hdrtr.insertCell(3);
674 ntd.colSpan = 20;
675 ntd.style.borderBottom = "1px solid lightgrey";
676 ntd.appendChild(document.createTextNode("extra values"));
677
678 }
679
680 c = this.accumulators().length;
681 for (i=0; i<c ; i++) {
682 varcurrentAccumulator;
683 var bdytr;
684 var bdytd;
685 var ii, cc;
686
687 currentAccumulator = this.accumulators()[i]
688
689 bdytr = tbl.insertRow(true);
690
691 bdytd = bdytr.insertCell(0);
692 bdytd.style.borderRight = "1px solid lightgrey";
693 bdytd.style.color = "lightgrey";
694 bdytd.appendChild(document.createTextNode("" + i));
695
696 bdytd = bdytr.insertCell(1);
697 bdytd.style.borderRight = "1px solid lightgrey";
698 bdytd.style.color = "gray";
699 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length()));
700
701
702 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel());
703 for (ii=0; ii<cc; ii++) {
704 var cellText;
705
706 bdytd = bdytr.insertCell(ii + 2);
707
708 if (ii < currentAccumulator.stack().length()) {
709 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii));
710 } else {
711 cellText = "_";
712 }
713
714 if (ii == (this.firstPoolReseedLevel() - 1)) {
715 bdytd.style.borderRight = "1px solid lightgrey";
716 }
717
718 bdytd.appendChild(document.createTextNode(cellText));
719 }
720
721 }
722
723
724 if (appendToDoc) {
725 var ne = document.createElement("div");
726 ne.id = "entropyGeneratorStatus";
727 with (ne.style) {
728 fontFamily = "Courier New, monospace";
729 fontSize = "12px";
730 lineHeight = "16px";
731 borderTop = "1px solid black";
732 padding = "10px";
733 }
734 if (document.getElementById(ne.id)) {
735 MochiKit.DOM.swapDOM(ne.id, ne);
736 } else {
737 document.body.appendChild(ne);
738 }
739 ne.appendChild(tbl);
740 }
741
742 return tbl;
743 },
744
745 //-----------------------------------------------------------------------------
746 __syntaxFix__: "syntax fix"
747});
748
749//#############################################################################
750
751Clipperz.Crypto.PRNG.Random = function(args) {
752 args = args || {};
753 //MochiKit.Base.bindMethods(this);
754
755 return this;
756}
757
758Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
759
760 'toString': function() {
761 return "Clipperz.Crypto.PRNG.Random";
762 },
763
764 //-------------------------------------------------------------------------
765
766 'getRandomBytes': function(aSize) {
767//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes");
768 varresult;
769 var i,c;
770
771 result = new Clipperz.ByteArray()
772 c = aSize || 1;
773 for (i=0; i<c; i++) {
774 result.appendByte((Math.random()*255) & 0xff);
775 }
776
777//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes");
778 return result;
779 },
780
781 //-------------------------------------------------------------------------
782 __syntaxFix__: "syntax fix"
783});
784
785//#############################################################################
786
787_clipperz_crypt_prng_defaultPRNG = null;
788
789Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
790 if (_clipperz_crypt_prng_defaultPRNG == null) {
791 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna();
792
793 //.............................................................
794 //
795 // TimeRandomnessSource
796 //
797 //.............................................................
798 {
799 var newRandomnessSource;
800
801 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111});
802 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
803 }
804
805 //.............................................................
806 //
807 // MouseRandomnessSource
808 //
809 //.............................................................
810 {
811 varnewRandomnessSource;
812
813 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
814 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
815 }
816
817 //.............................................................
818 //
819 // KeyboardRandomnessSource
820 //
821 //.............................................................
822 {
823 varnewRandomnessSource;
824
825 newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource();
826 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
827 }
828
829 }
830
831 return _clipperz_crypt_prng_defaultPRNG;
832};
833
834//#############################################################################
835
836Clipperz.Crypto.PRNG.exception = {
837 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
838};
839
840
841MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator);