TinyMT32 Pseudorandom Number Generator (PRNG)
Extracted elements (16)
A single fixed parameter set (mat1, mat2, tmat) is mandated for this specification rather than leaving it user-selectable (as in the original v1.1 implementation), so that the pseudorandom sequence is fully determined by the seed alone. This simplifies use and ensures determinism.
The conditional if-branch form of certain operations (replacing '-((int32_t)(y & 1)) & mask' idioms) was adopted to avoid dependence on two's complement representation of negative integers, improving portability at the cost of potentially slower generation speed.
The period_certification() function from the original TinyMT32 source was safely removed because the chosen parameter set guarantees that none of the 2^32 possible seeds leads to an all-zero 127-bit internal state, eliminating the need for this check.
TinyMT32 is a variant of the Mersenne Twister with a far shorter period (2^127 - 1 vs. MT's 2^19937 - 1), but this tradeoff is intentional: the merit is the small 127-bit internal state, which is compatible with embedded devices where MT's 19937-bit state is impractical.
TinyMT32 was chosen over the Park-Miller Linear Congruential PRNG because the latter has well-known limitations. TinyMT32 passes BigCrush (TestU01) and AdaptiveCrush statistical tests, representing a major quality improvement while maintaining a small 127-bit internal state suitable for embedded devices.
The specification allows multiple independent PRNG instances to run in parallel, each with its own tinymt32_t structure instance. The structure must not be shared or modified by the caller between successive generation calls.
When mapping PRNG output to a smaller integer range, use of floating-point arithmetic (single or double precision) should probably be avoided if PRNG determinism is required, as floating-point rounding may differ across platforms. The specification only outputs 32-bit unsigned integers; range mapping is out of scope.
Any implementation of TinyMT32 in line with this specification MUST produce the same output as the reference implementation in Figure 1. Compliance can be verified by checking that with seed value 1, the first 50 outputs match the values listed in Figure 2.
The PRNG MUST first be initialized by calling tinymt32_init(s, seed) before any output is generated. The tinymt32_t structure must be left unchanged by the caller between successive calls to tinymt32_generate_uint32.
The TinyMT32 PRNG MUST use the specific parameter set: mat1 = 0x8f7011ee, mat2 = 0xfc78ff1f, tmat = 0x3793fdff. This ensures the pseudorandom sequence depends only on the seed value and not on parameter selection.
The tinymt32_generate_uint32(s) function is the primary output function, returning a 32-bit unsigned integer in the range [0, 2^32 - 1] inclusive by advancing the internal state and applying the tempering function.
The tinymt32_init(s, seed) initialization function accepts a 32-bit unsigned integer seed (including 0 as a valid value), runs a MIN_LOOP of 8 mixing iterations, and then advances the state PRE_LOOP (8) steps before the PRNG is ready for use.
The TinyMT32 internal state is represented by a tinymt32_t structure containing a 4-element uint32_t status array plus three uint32_t parameter fields (mat1, mat2, tmat), totaling a 127-bit internal state.
The tinymt32_next_state() function advances the 127-bit internal state using XOR, left/right shifts (SH0=1, SH1=10), and conditional XOR with mat1/mat2 parameters when the least-significant bit of y is 1.
The tinymt32_temper() function produces the 32-bit output from internal state by combining status[3], status[0], and status[2] via XOR and an 8-bit right shift, with a conditional XOR of tmat based on the LSB of t1.
TinyMT32 and MT MUST NOT be used for cryptographic applications. The authors do not believe this specification generates specific security risks per se, but the non-cryptographic nature of the PRNG is an absolute constraint.