class: Random
changed: #randomSeed
sv's idea: feed hash instead of xoring the individual entropy sources
--- a/Random.st Thu Oct 02 17:19:47 2014 +0200
+++ b/Random.st Thu Oct 02 17:36:18 2014 +0200
@@ -268,50 +268,41 @@
The entropy returned should be reasonable enough for a good seed of a good rnd
generator. However, keep in mind, that it only has a limited number of entropy bits
(in the order of 32).
- But it shoud be much better than what is commonly used in older
+ But it should be much better than what is commonly used in older
programs (current time) or even a constant."
- |newSeed hash|
+ |hash|
+
+ hash := MD5Stream new.
RandomSalt isNil ifTrue:[
RandomSalt := 1.
] ifFalse:[
RandomSalt := RandomSalt + 1.
].
- newSeed := RandomSalt + (Time microsecondClockValue bitXor:OperatingSystem getProcessId).
- newSeed := newSeed bitXor:(ObjectMemory addressOf:(Object new)).
- newSeed := newSeed bitXor:(ObjectMemory oldSpaceUsed).
+ hash nextPut:RandomSalt.
+ hash nextPutAll:Time microsecondClockValue asLargeInteger digitBytes.
+ hash nextPutAll:OperatingSystem getProcessId asLargeInteger digitBytes.
+ hash nextPutAll:(ObjectMemory addressOf:(Object new)) asLargeInteger digitBytes.
+ hash nextPutAll:(ObjectMemory oldSpaceUsed) asLargeInteger digitBytes.
+ hash nextPutAll:(ObjectMemory newSpaceUsed) asLargeInteger digitBytes.
[
- newSeed := newSeed bitXor:(OperatingSystem getCPUCycleCount).
+ hash nextPutAll:(OperatingSystem getCPUCycleCount) asLargeInteger digitBytes.
] on:PrimitiveFailure do:[].
- "/ any other easy sources of entropy?
-
- "/ how likely is that? - paranoia
- newSeed = 0 ifTrue:[ newSeed := Time microsecondClockValue ].
-
- "/ The above gives us a 5-8 byte number, but some high bits are constant.
- "/ (the constant high bits from the above do not provide any entropy)
- "/ so the effective entropy is more in the order of 32 bits.
- "/ if called shortly in a row, the returned values are only affected by
- "/ the amount of memory allocated in between (and if there are any newspace reclamations),
- "/ the real time in between and the number of cpu cycles between,
- "/ plus the salt counter.
- "/ Hashing should make this less likely to be predicted.
+ "/ any other cheap sources of entropy?
"/ I think there is no problem in that MD5 is not a secure hash algo here - the idea is to shuffle the bits around a bit
"/ (because the numbers above usually have many high bits in common)
"/ and then condense the bits into a smaller number.
"/ Any comment from a crypto guy here - I am willing to change this to some other hash, if that makes a problem
- hash := MD5Stream hashValueOf:(newSeed asLargeInteger digitBytes).
- "/ still the same number of entropy bits, bit no longer limited to an unknown number of low bits,
- "/ bit arbitrarily spread among the hash bytes.
- "/ Seeding rnd generators should Xor the returned 8 bytes to their max. seed size
- ^ LargeInteger digitBytes:hash.
+ "/ Seeding rnd generators should take some bits from the returned number (i.e. their max. seed size)
+ ^ LargeInteger digitBytes:hash hashValue.
"
10 timesRepeat:[Transcript showCR:self randomSeed].
+ 10 timesRepeat:[Transcript showCR:(self randomSeed bitAnd:16rFFFF)].
self randomSeed bitAnd:16rFFFFFFFF
"
! !
@@ -766,10 +757,10 @@
!Random class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.55 2014-10-02 14:50:55 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.56 2014-10-02 15:36:18 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.55 2014-10-02 14:50:55 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.56 2014-10-02 15:36:18 cg Exp $'
! !