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

Changes (33)

View Page History
h2.Overview {note:title=Updated}
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.
This RFC has been recently updated to the new component structure
{note}

Component is partly implemented in [this feature branch|https://github.com/denixport/zf2/tree/feature/math-rand/library/Zend/Math/Rand] on GitHub.
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.

Working prototype is ready. Please see [this feature branch|https://github.com/denixport/zf2/tree/feature/rand/library/Zend/Math/Rand] on GitHub.

h2.Overview
RNG uses scheme described in [RFC 4086|http://tools.ietf.org/html/rfc4086]. 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.
Component is partly based on TrueCrypt RNG.

h2.Component Structure
h3. Zend\Math\Rand\Rand Zend\Math\Rand\Generator
Implements following methods:
Generator is constructed with array of sources of randomness ({{SourceInterface}}) and mixing function ({{MixerInterface}}). This is the way to create custom generators with custom set of sources and mixing function.
Methods to get random values are:
* {{getBytes($length)}} {{generate($length)}} -- random binary string of {{$length}} bytes
* {{getBoolean()}} -- boolean
* {{getInt($min, $max)}} -- int within {{$min}} & {{$max}}
* {{getFloat($min, $max)}} -- float within {{$min}} & {{$max}}
* {{getInt($min = 0, $max = PHP_INT_MAX)}} -- int within {{$min}} & {{$max}}
* {{getFloat()}} -- floating point number between 0 and 1 with machine's precision
* {{getString($length, $charlist)}} -- generates random ASCII string

If no adapter is provided to constructor, component will try to determine best available adapter for current system.

h3. Zend\Math\Rand\Adapter
Interface to various RNGs, methods {{seed}} and {{warmUp}} are features of canonical RNG
h3. Factory (Zend\Math\Rand\GeneratorFactory)
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.
Factory methods are:
* {{create($options)}} -- create instance based on provided options
* {{createGenerator($strength = Strength::MEDIUM)}} -- create generator of required strength

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

{code:php}
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}

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()}})

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

{code:php}
namespace Zend\Math\Rand\Mixer;

interface MixerInterface
{
public static function getStrength();
public function mix($bytes);
}
{code}


h2.Questions
Due to refactoring, some questions are not relevant anymore.

* _Should RNG express what kind of algorithm ("cryptographically strong" or week) was used?_
* _Should RNG component have it's own namespace Zend\Random or live in Zend\Math, or Zend\Crypt?_

* _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.
* -Should RNG express what kind of algorithm ("cryptographically strong" or week) was used?-

* _Should RNG have it's own namespace Zend\Rand or reside within Zend\Math?_
That mostly depends on component architecture
* -Should component use adapters or single class is good enough?-

* _-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

* _-What other adapters, if any, component should provide?_-

h2.References
* [RFC 4086|http://tools.ietf.org/html/rfc4086]
* [TrueCrypt RNG|http://www.truecrypt.org/docs/?s=random-number-generator]