Random.st
changeset 3414 bfae9f81787a
parent 3403 bf8cccac67c9
child 3431 4ece2027bd33
equal deleted inserted replaced
3413:5afe23725daf 3414:bfae9f81787a
   266      plus some value depending on the memory allocation state,
   266      plus some value depending on the memory allocation state,
   267      plus a random salt, and shuffles those bits around.
   267      plus a random salt, and shuffles those bits around.
   268      The entropy returned should be reasonable enough for a good seed of a good rnd
   268      The entropy returned should be reasonable enough for a good seed of a good rnd
   269      generator. However, keep in mind, that it only has a limited number of entropy bits
   269      generator. However, keep in mind, that it only has a limited number of entropy bits
   270      (in the order of 32). 
   270      (in the order of 32). 
   271      But it shoud be much better than what is commonly used in older
   271      But it should be much better than what is commonly used in older
   272      programs (current time) or even a constant."
   272      programs (current time) or even a constant."
   273 
   273 
   274     |newSeed hash|
   274     |hash|
       
   275 
       
   276     hash := MD5Stream new.
   275 
   277 
   276     RandomSalt isNil ifTrue:[
   278     RandomSalt isNil ifTrue:[
   277         RandomSalt := 1.
   279         RandomSalt := 1.
   278     ] ifFalse:[
   280     ] ifFalse:[
   279         RandomSalt := RandomSalt + 1.
   281         RandomSalt := RandomSalt + 1.
   280     ].
   282     ].
   281     newSeed := RandomSalt + (Time microsecondClockValue bitXor:OperatingSystem getProcessId).
   283     hash nextPut:RandomSalt.
   282     newSeed := newSeed bitXor:(ObjectMemory addressOf:(Object new)).
   284     hash nextPutAll:Time microsecondClockValue asLargeInteger digitBytes. 
   283     newSeed := newSeed bitXor:(ObjectMemory oldSpaceUsed).
   285     hash nextPutAll:OperatingSystem getProcessId asLargeInteger digitBytes. 
       
   286     hash nextPutAll:(ObjectMemory addressOf:(Object new)) asLargeInteger digitBytes. 
       
   287     hash nextPutAll:(ObjectMemory oldSpaceUsed) asLargeInteger digitBytes. 
       
   288     hash nextPutAll:(ObjectMemory newSpaceUsed) asLargeInteger digitBytes. 
   284     [
   289     [
   285         newSeed := newSeed bitXor:(OperatingSystem getCPUCycleCount).
   290         hash nextPutAll:(OperatingSystem getCPUCycleCount) asLargeInteger digitBytes. 
   286     ] on:PrimitiveFailure do:[].
   291     ] on:PrimitiveFailure do:[].
   287 
   292 
   288     "/ any other easy sources of entropy?
   293     "/ any other cheap sources of entropy?
   289 
       
   290     "/ how likely is that? - paranoia
       
   291     newSeed = 0 ifTrue:[ newSeed := Time microsecondClockValue ]. 
       
   292 
       
   293     "/ The above gives us a 5-8 byte number, but some high bits are constant.
       
   294     "/ (the constant high bits from the above do not provide any entropy)
       
   295     "/ so the effective entropy is more in the order of 32 bits.
       
   296     "/ if called shortly in a row, the returned values are only affected by
       
   297     "/ the amount of memory allocated in between (and if there are any newspace reclamations),
       
   298     "/ the real time in between and the number of cpu cycles between,
       
   299     "/ plus the salt counter.
       
   300     "/ Hashing should make this less likely to be predicted.
       
   301 
   294 
   302     "/ 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
   295     "/ 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
   303     "/ (because the numbers above usually have many high bits in common)
   296     "/ (because the numbers above usually have many high bits in common)
   304     "/ and then condense the bits into a smaller number.
   297     "/ and then condense the bits into a smaller number.
   305     "/ Any comment from a crypto guy here - I am willing to change this to some other hash, if that makes a problem
   298     "/ Any comment from a crypto guy here - I am willing to change this to some other hash, if that makes a problem
   306 
   299 
   307     hash := MD5Stream hashValueOf:(newSeed asLargeInteger digitBytes).
   300     "/ Seeding rnd generators should take some bits from the returned number (i.e. their max. seed size)
   308     "/ still the same number of entropy bits, bit no longer limited to an unknown number of low bits,
   301     ^ LargeInteger digitBytes:hash hashValue.
   309     "/ bit arbitrarily spread among the hash bytes.
       
   310     "/ Seeding rnd generators should Xor the returned 8 bytes to their max. seed size
       
   311     ^ LargeInteger digitBytes:hash.
       
   312 
   302 
   313     "
   303     "
   314      10 timesRepeat:[Transcript showCR:self randomSeed].
   304      10 timesRepeat:[Transcript showCR:self randomSeed].
       
   305      10 timesRepeat:[Transcript showCR:(self randomSeed bitAnd:16rFFFF)].
   315      self randomSeed bitAnd:16rFFFFFFFF
   306      self randomSeed bitAnd:16rFFFFFFFF
   316     "
   307     "
   317 ! !
   308 ! !
   318 
   309 
   319 !Random class methodsFor:'testing'!
   310 !Random class methodsFor:'testing'!
   764 ! !
   755 ! !
   765 
   756 
   766 !Random class methodsFor:'documentation'!
   757 !Random class methodsFor:'documentation'!
   767 
   758 
   768 version
   759 version
   769     ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.55 2014-10-02 14:50:55 cg Exp $'
   760     ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.56 2014-10-02 15:36:18 cg Exp $'
   770 !
   761 !
   771 
   762 
   772 version_CVS
   763 version_CVS
   773     ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.55 2014-10-02 14:50:55 cg Exp $'
   764     ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.56 2014-10-02 15:36:18 cg Exp $'
   774 ! !
   765 ! !
   775 
   766