compared with
Current by Denis Portnov
on Apr 24, 2012 11:52.

Key
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (32)

View Page History
h2.Overview
This RFC contains a proposal for implementing cryptographicaly strong pseudo-random number generator (RNG) in ZF2.
Several components withing current ZF2 reqire strong random number and there is also a possibility for future user-space modules to use this component. So component will be single point of generating strong pseudo-random numbers.
<ac:macro ac:name="note"><ac:parameter ac:name="title">Updated</ac:parameter><ac:rich-text-body>
<p>This RFC has been recently updated to the new component structure</p></ac:rich-text-body></ac:macro>

Component is partly implemented in [this feature branch|https://github.com/denixport/zf2/tree/feature/math-rand/library/Zend/Math/Rand] on GitHub.
<p>This RFC contains a proposal for implementing cryptographicaly strong pseudo-random number generator (RNG) in ZF2. Several components withing current ZF2 reqire strong random number and there is also a possibility for future user-space modules to use this component. So component will be single point of generating strong pseudo-random numbers.</p>

h2.Component Structure
h3. Zend\Math\Rand\Rand
Implements following methods:
* {{getBytes($length)}} -- random binary string of {{$length}} bytes
* {{getBoolean()}} -- boolean
* {{getInt($min, $max)}} -- int within {{$min}} & {{$max}}
* {{getFloat($min, $max)}} -- float within {{$min}} & {{$max}}
* {{getString($length, $charlist)}} -- generates random ASCII string
<p>Working prototype is ready. Please see <a href="https://github.com/denixport/zf2/tree/feature/rand/library/Zend/Math/Rand">this feature branch</a> on GitHub.</p>

If no adapter is provided to constructor, component will try to determine best available adapter for current system.
<h2>Overview</h2>
<p>RNG uses scheme described in <a href="http://tools.ietf.org/html/rfc4086">RFC 4086</a>. Generator collects inital entropy data from varous sources, adds this data to entropy pool and periodically mixes the pool with some complex mixing function. This way even with weak and predictable sources of entropy, generated random value is cryptographicaly strong. <br />
Component is partly based on TrueCrypt RNG.</p>

h3. Zend\Math\Rand\Adapter
Interface to various RNGs, methods {{seed}} and {{warmUp}} are features of canonical RNG
<h2>Component Structure</h2>
{code:php} <h3>Zend\Math\Rand\Generator</h3>
namespace Zend\Math\Rand;
<p>Generator is constructed with array of sources of randomness (<code>SourceInterface</code>) and mixing function (<code>MixerInterface</code>). This is the way to create custom generators with custom set of sources and mixing function. <br />
Methods to get random values are:</p>
<ul>
<li><code>generate($length)</code> &ndash; random binary string of <code>$length</code> bytes</li>
<li><code>getBoolean()</code> &ndash; boolean</li>
<li><code>getInt($min = 0, $max = PHP_INT_MAX)</code> &ndash; int within <code>$min</code> &amp; <code>$max</code></li>
<li><code>getFloat()</code> &ndash; floating point number between 0 and 1 with machine's precision</li>
<li><code>getString($length, $charlist)</code> &ndash; generates random ASCII string</li>
</ul>



<h3>Factory (Zend\Math\Rand\GeneratorFactory)</h3>
<p>Factory is a fast way to create generator based on pre-defined strength. Generator supports three levels of strength: low, medium, high. For each level different sources and mixing function is used. <br />
Factory methods are:</p>
<ul>
<li><code>create($options)</code> &ndash; create instance based on provided options</li>
<li><code>createGenerator($strength = Strength::MEDIUM)</code> &ndash; create generator of required strength</li>
</ul>


<h3>Source (Zend\Math\Rand\SourceInterface)</h3>
<p>Different sources of entropy in PHP: openssl, /dev/urandom/, mt_rand() etc. </p>

<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
namespace Zend\Math\Rand\Source;

interface Adapter SourceInterface
{
public static function isAvailable();
public static function getStrength();
public function seed($seed); generate($length);
public function warmUp($cycles = 100);
public function getBytes($length);
public function getBoolean();
public function getInt($min = null, $max = null);
public function getFloat($min = null, $max = null);
public function getString($length, $charlist = null);
}
{code}
]]></ac:plain-text-body></ac:macro>

Currently implemented adapters are
* Openssl - openssl extension
* Stream - to read from various streams ({{/dev/random}} , {{/dev/hwrandom}} etc)
* Capicom - Windows COM
* Mcrypt - (using {{mcrypt_create_iv()}} that works on Windows platform
* PhpMtRand - PHP Mersenne Twister ({{mt_rand()}})

h2.Questions
<h3>Mixer (Zend\Math\Rand\MixerInterface)</h3>
<p>Mixing function. Default mixing function is hash mixer based on SHA-512, RIPEMD, Whirpool</p>

* _Should RNG express what kind of algorithm ("cryptographically strong" or week) was used?_
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
namespace Zend\Math\Rand\Mixer;

* _Should component use adapters or single class is good enough?_
Adapter interface allows custom adapters, and possibility to use services like Random.org. On the other hand if no extensibility is requied functionallity will fit fine within single class.
interface MixerInterface
{
public static function getStrength();
public function mix($bytes);
}
]]></ac:plain-text-body></ac:macro>

* _Should RNG have it's own namespace Zend\Rand or reside within Zend\Math?_
That mostly depends on component architecture

* _Should there be a distinction between int/bigint (float/bigfloat)?_
So {{getInt()}} will generate numbers within 0 - PHP_INT_MAX, and {{getBigInt}} will generate numbers of arbitrary size as strings
<h2>Questions</h2>
<p>Due to refactoring, some questions are not relevant anymore.</p>

* _What other adapters, if any, component should provide?_
<ul>
<li><em>Should RNG component have it's own namespace Zend\Random or live in Zend\Math, or Zend\Crypt?</em></li>
</ul>


<ul>
<li><span style="text-decoration: line-through;">Should RNG express what kind of algorithm (&quot;cryptographically strong&quot; or week) was used?</span></li>
</ul>


<ul>
<li><span style="text-decoration: line-through;">Should component use adapters or single class is good enough?</span></li>
</ul>


<ul>
<li><span style="text-decoration: line-through;">Should there be a distinction between int/bigint (float/bigfloat)?</span></li>
</ul>


<ul>
<li><span style="text-decoration: line-through;">What other adapters, if any, component should provide?</span></li>
</ul>


<h2>References</h2>
<ul>
<li><a href="http://tools.ietf.org/html/rfc4086">RFC 4086</a></li>
<li><a href="http://www.truecrypt.org/docs/?s=random-number-generator">TrueCrypt RNG</a></li>
</ul>