# HG changeset patch # User Claus Gittinger # Date 1412264178 -7200 # Node ID bfae9f81787a649c30b278f972c71ab27f42e61b # Parent 5afe23725daf683b257bb811e8b5605e9f3a18e3 class: Random changed: #randomSeed sv's idea: feed hash instead of xoring the individual entropy sources diff -r 5afe23725daf -r bfae9f81787a Random.st --- 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 $' ! !