pool_of_entropy 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4bfa3a0e0d42e79d2af5b13539692da02db0d33c
4
- data.tar.gz: 97f2e7d2a51605afeb88dbf2c1560e8829b91595
3
+ metadata.gz: 9282759abb1c13fd70a45b27da5f58030107bc23
4
+ data.tar.gz: 88da59e58548d584b72df4640be40be61aef9b37
5
5
  SHA512:
6
- metadata.gz: 2a67971cfcae21b459bd249154c7b3ab74ec94f36c7b08c146928196084840a074a83c01faad59fd4e8eb23be888e02a74945c9b01b77a2264e44d908723d5e9
7
- data.tar.gz: 73db8b9f6f8d8c8db1873a4d3be54eecf41793f0b7a6ab60a3c8225a2526de41d7508c07e7844b1adb60479dd155fa647511a08a9488d3695bb89a9499cfce99
6
+ metadata.gz: b158c97ffc614e6f40c5f769812a5f1441877e96c429e525875639c18f3c1a6f8699341bf81c062981e7eac2a2e986120718029facdb8bfe135e5ad8fc140d7f
7
+ data.tar.gz: c68191705fce736800291804d24d30c46e74be13906cde6cae5e46983ae1afaeaeb6d72aa5b4e4cb72110b06d2d9751b32034c3e2424381378f13d8fdf08518a
data/.yardopts CHANGED
@@ -3,5 +3,7 @@ lib/**/*.rb
3
3
  --no-private
4
4
  -
5
5
  README.md
6
+ RECIPES.md
7
+ RATIONALE.md
6
8
  LICENSE.txt
7
9
  DIEHARDER_TEST.md
data/RATIONALE.md CHANGED
@@ -9,8 +9,8 @@ psuedo random data that has no discernable pattern.
9
9
 
10
10
  Generators used for games also need another trait - they need to be unpredictable to the end users.
11
11
  Often that is not strictly true in the academic sense, for example a well-informed user with enough
12
- time and skill could predict the next output from Ruby's rand() method. However, when this really
13
- needs to be true, you can use a Crytogaphically Secure PRNG (CSPRNG). Ruby's SecureRandom cannot
12
+ time and skill could predict the next output from Ruby's rand() method. However, when your really
13
+ need secure numbers, you can use a Crytogaphically Secure PRNG (CSPRNG). Ruby's SecureRandom cannot
14
14
  be predicted from outside the system. Part of how CSPRNGs achieve unpredicatbility is by collecting
15
15
  entropy from sources within the computer - this might be timing of events from network cards and
16
16
  keyboard presses, or by sampling from deliberately noisy circuits.
@@ -44,8 +44,8 @@ Truly unpredictable sources are also easy enough to find. They make themselves u
44
44
  by collecting entropy from sources on the machines where they run, that no-one can predict.
45
45
 
46
46
  However, there has been a cost to the user's agency. If I was playing a game
47
- using one of these sources, even though it was fair in the sense that the outcomes could
48
- well be the same, it gives me the same feeling as if another player was rolling all the dice.
47
+ using one of these sources, even though it was fair in the sense that the outcomes were chosen
48
+ with equal chances, it gives me the same feeling as if another player was rolling all the dice.
49
49
  In a role-playing game, it feels the same as if the DM was rolling all the dice. Now sometimes
50
50
  and for some (many/most?) people that's OK. But other times, part of the fun is in rolling
51
51
  the dice yourself. I would be happy rolling computer dice, but only if somehow it was
@@ -63,12 +63,32 @@ regular CSPRNGs used to protect your computer on the internet is how this "entro
63
63
  In a secure system, entropy is sourced from multiple places - anywhere that data can be
64
64
  gathered that an imagined attacker will have a hard time guessing the value. In PoolOfEntropy
65
65
  this is subverted - the end user supplies any data they like, and the gem treats it
66
- as "entropy". Technically, if you were an attacker, this would not be called entropy at
67
- all (because you know it) - however, to the machinery of the PRNG, or to me as a fellow
68
- player in a dice game, it counts just fine.
66
+ as entropy. Technically, if you were an attacker, this would not be called entropy at
67
+ all (because you know the exact value) - however, to the machinery of the PRNG, or
68
+ to me as a fellow player in a dice game, it counts just fine.
69
69
 
70
70
  By default PoolOfEntropy objects start off with some machine-collected entropy from SecureRandom
71
71
  to avoid trivial attacks (of always using the dice in the exact same way). You could view this
72
72
  as representing the environment or the die itself (all the scratches and imperfections that
73
73
  you cannot control, and have no influence over). Or, under an honour system of not repeating
74
- yourself you can switch off that default.
74
+ yourself you can switch off that default.
75
+
76
+ ## What PoolOfEntropy Does Not Do: Superstition
77
+
78
+ PoolOfEntropy will happily eat any string data and use it to help generate random numbers. It
79
+ cannot tell, and therefore does not care, what the *meaning* of that data is. It cannot
80
+ tell what you wish for, it is not "lady luck" in code form.
81
+
82
+ Superstition is a natural human feeling. We blow on dice before throwing them to encourage results
83
+ that we want, we avoid saying things lest we "tempt fate", and perform a thousand other
84
+ minor rites in order to get supposed good luck. This is true even when intellectually we
85
+ understand that truly random events are unbiased and there is no predictable cause and effect.
86
+ You cannot be a "lucky person" in the sense that random number generators will somehow
87
+ favour you. But the feeling is persistent, it seems inherent to human nature.
88
+
89
+ You can bring superstition into your interactions with a computer PRNG; you may already do,
90
+ if you play any computer game that uses random numbers. In some ways this gem encourages that,
91
+ by giving you the ability to set things up with data that is meaningful for you. But bear
92
+ in mind, that like a well-rolled die, the computer doesn't understand or care. The difference
93
+ between PoolOfEntropy and most other PRNGs is supposed to be the difference between you
94
+ rolling a die and someone else rolling it for you.
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![Dependency Status](https://gemnasium.com/neilslater/pool_of_entropy.png)](https://gemnasium.com/neilslater/pool_of_entropy)
7
7
 
8
8
  PoolOfEntropy is a pseudo random number generator (PRNG) based on secure hashes,
9
- intended to bring back the feeling of 'personal luck' that some gamers may feel when rolling
9
+ intended to bring back the feeling of 'personal agency' that some gamers may feel when rolling
10
10
  their *own* dice. An instance of the PoolOfEntropy class could be assigned to a player, or
11
11
  to each die in a game, and it can be influenced (similar to throwing a die differently), or
12
12
  personalised by feeding in arbitrary data (e.g. a picture of the player, a favourite saying).
@@ -40,17 +40,40 @@ Or install it yourself as:
40
40
 
41
41
  ## Usage
42
42
 
43
- Create a new generator:
43
+ ### Create a new generator:
44
44
 
45
45
  pool = PoolOfEntropy.new
46
46
 
47
- Get a random number. Not feeding the generator with any customisation
47
+ Or
48
+
49
+ pool = PoolOfEntropy.new :size => 24
50
+
51
+ Or
52
+
53
+ pool = PoolOfEntropy.new :size => 24, :blank => true
54
+
55
+ The :size parameter sets the amount of randomness that the pool
56
+ can store, in multiples of 512 bits (or 64 bytes). The default
57
+ size of 1 is fastest, and has a good distribution of values
58
+ statistically. Larger pool sizes (up to 256) will calculate a
59
+ little slower, but can be used to buffer more entropy from
60
+ the #add_to_pool method.
61
+
62
+ Setting :blank to true starts the pool with the entire pool
63
+ zero, so that repeatedly using the generator in exactly the
64
+ same way will return the same values.
65
+
66
+ ### Get a random number.
67
+
68
+ Not feeding the generator with any customisation
48
69
  means it is completely deterministic based on current internal state. The
49
70
  analogy here might be "trusting to Fate":
50
71
 
51
72
  pool.rand( 20 )
52
73
 
53
- Influence the next random number (but not any others). This is analogous to
74
+ ### Influence the next random number (but not any others).
75
+
76
+ This is analogous to
54
77
  shaking or throwing dice in a certain way. Only the next result from rand()
55
78
  is affected:
56
79
 
@@ -64,7 +87,9 @@ is affected:
64
87
  # we re-join the deterministic sequence of the PRNG:
65
88
  pool.rand
66
89
 
67
- Influence the next three random numbers. Data supplied to modify_next is
90
+ ### Influence the next three random numbers.
91
+
92
+ Data supplied to modify_next is
68
93
  put in a queue, first in, first out:
69
94
 
70
95
  pool.modify_next( 'Shake the die lots.' )
@@ -77,7 +102,9 @@ put in a queue, first in, first out:
77
102
 
78
103
  pool.rand # . . . and back to main sequence
79
104
 
80
- Influence all random numbers from this point forward. This is analogous to
105
+ ### Influence all random numbers from this point forward.
106
+
107
+ This is analogous to
81
108
  having a personal style of throwing dice, or perhaps a different environment
82
109
  to throw them in.
83
110
 
@@ -90,7 +117,7 @@ to throw them in.
90
117
  # The two modifier types "stack", and this is modified twice
91
118
  pool.modify_next( 'And I really mean it!' ).rand( 20 )
92
119
 
93
- Remove modfiers:
120
+ ### Remove modfiers.
94
121
 
95
122
  # Just the "all" modifier
96
123
  pool.modify_all( nil )
@@ -101,7 +128,9 @@ Remove modfiers:
101
128
  # Re-set "next" and "all" modifiers
102
129
  pool.clear_all_modifiers
103
130
 
104
- Alter internal state of pool. This mixes in any entropy in the supplied
131
+ ### Alter internal state of pool.
132
+
133
+ This mixes in any entropy in the supplied
105
134
  data, and changes the deterministic sequence going forward. This is
106
135
  analogous to long-term alterations to dice, the environment, or
107
136
  person throwing the dice.
@@ -111,14 +140,17 @@ person throwing the dice.
111
140
  All the inputs can be any length String, from any source. If the data
112
141
  contains *any* "true randomness" (however you want to define it, and however
113
142
  the String is formatted), then PoolOfEntropy
114
- will process that (using SHA-512) into unbiased results. If you care
143
+ will process that (using SHA-512) into unbiased results.
144
+
145
+ If you care
115
146
  about your own source of randomness being more "important" than
116
- the initial state of the PRNG, or its continued deterministic ticking,
147
+ the initial state of the PRNG or its deterministic progression,
117
148
  then make use of the modifiers and/or add data to the pool frequently.
118
149
 
119
150
  ## More information
120
151
 
121
152
  * [Rationale](RATIONALE.md)
153
+ * [Recipes and Suggestions](RECIPES.md)
122
154
  * [Dieharder test of statistical randomness](DIEHARDER_TEST.md)
123
155
 
124
156
  ## Contributing
data/RECIPES.md ADDED
@@ -0,0 +1,70 @@
1
+ # Uses for PoolOfEntropy
2
+
3
+ ## DO NOT USE FOR: Monte-Carlo Simulations
4
+
5
+ Although PoolOfEntropy can be seeded for repeatable sequences, and produces random numbers of
6
+ suitable quality, it is a lot slower than other equally good options. Use Ruby's built in
7
+ rand() or the Random class instead.
8
+
9
+ ## DO NOT USE FOR: Communications Security
10
+
11
+ Although PoolOfEntropy can produce numbers of suitable quality, and is based
12
+ on a secure hash design, it is not proven secure and is never likely to be. In
13
+ addition, it operates on the application level in a Ruby process, and direct access
14
+ to that process would allow it to be compromised very easily. Use SecureRandom
15
+ instead.
16
+
17
+ ## Dice for Play-by-Mail
18
+
19
+ This was one of the original design goals for the gem. One problem with games
20
+ played where events happen offline is that random numbers may be required when
21
+ a player is not present. By assigning an instance of PoolOfEntropy to each
22
+ player, and letting the player provide data for modifiers or the pool, it
23
+ allows the game to simulate fair dice rolls, and for the players to have influenced
24
+ those rolls in advance. In a philosophical sense you could say the players
25
+ have rolled the dice themselves.
26
+
27
+ To create and use a pool for a player:
28
+
29
+ # Depending on how many dice rolls will be made offline, I recommend
30
+ # a largish pool here. This 4KB pool, if completely filled with
31
+ # quality random data for a player, could generate over 6500 rolls of a d20
32
+ # that you might consider to be "rolled by the player" (in the sense that
33
+ # an infinitely powerful machine that knew the initial state before user
34
+ # data was added would need to see the results from that many rolls before it
35
+ # could figure out what the new state was)
36
+
37
+ freds_entropy = PoolOfEntropy.new :size => 64
38
+
39
+ # Add Fred's data, assuming freds_input is an Array of Strings. Ideally you
40
+ # have at least same number of strings as :size param above. You can split
41
+ # large files into chunks for processing e.g. images or videos
42
+
43
+ freds_input.each do |data|
44
+ freds_entropy.add_to_pool( data )
45
+ end
46
+
47
+ # Save the pool for later use (example to file, but binary blob in database
48
+ # is also fine). Note you should encrypt this if players have access to the
49
+ # data and would know how to use PoolOfEntropy themselves.
50
+
51
+ File.open( 'fred.pool', 'wb' ) { |file| file.write Marshal.dump( freds_entropy ) }
52
+
53
+ # Open the pool up later to use it
54
+
55
+ freds_entropy = File.open( 'fred.pool', 'rb' ) { |file| Marshal.load( file.read ) }
56
+
57
+ # During the game, Fred rolls a die:
58
+
59
+ result = freds_entropy.rand( 20 ) + 1
60
+
61
+ The gem games_dice will accept a PoolOfEntropy object as a generator for a dice object:
62
+
63
+ require 'games_dice'
64
+
65
+ freds_attack = GamesDice.create '1d20 + 6', freds_entropy
66
+
67
+ freds_attack.roll
68
+ # => 21
69
+ freds_attack.explain_result
70
+ # => "1d20: 15. 15 + 6 = 21"
@@ -1,3 +1,3 @@
1
1
  class PoolOfEntropy
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pool_of_entropy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil Slater
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-15 00:00:00.000000000 Z
11
+ date: 2014-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yard
@@ -97,6 +97,7 @@ files:
97
97
  - LICENSE.txt
98
98
  - RATIONALE.md
99
99
  - README.md
100
+ - RECIPES.md
100
101
  - Rakefile
101
102
  - lib/pool_of_entropy.rb
102
103
  - lib/pool_of_entropy/core_prng.rb