Ordeal::Model::ChaCha20 - Class for generating pseudo-random data


   use Ordeal::Model::ChaCha20;

   my $rs = Ordeal::Model::ChaCha20->new(seed => 'abcdefg123456');


This class is an adaptation from Math::Prime::Util::ChaCha for shipping a pure-Perl cryptogrphic pseudo-random number generator to use for proper shuffling of decks. It is used by Ordeal::Model::Shuffle as the default source for random data.

The implementation of the core algorithm is taken from Math::Prime::Util::ChaCha, adapted for proper "living" in an object. This allows having multiple independent random number generators at the same time. Additionally, the interface has been adapted for managing extraction of strings of bit in order to minimize the number of random data extracted and maximize the period (which is probably overkill for the goals of Ordeal::Model, but whatever).

The main method is "int_rand", which generates an integer between a minimum and a maximum value, both included.

If you want to save the state of the generator for later restoring, e.g. because you want to pass it around as a Cookie, look for "freeze" and "restore". It is also possible to "reset" the generator to its initial state.

Upon construction you can pass a "seed" to influence the initial status of the generator.



   my $other = $rs->clone;

create a clone of the random source, aligned at the very same state. The two sources will act independently after the cloning.


   my $hex = $rs->freeze;

generate an hex-encoded string representing the full state of the generator, for later restoring via "restore".


   my $n = $rs->int_rand($min, $max);

generate a random integer value between $min and $max, both included.

The algorithm uses the ChaCha20 algorithm behind the scenes to generate a stream of random bits. These bits are taken to generate a random integer value in an interval that contains 0 .. ($max - $min + 1), then applies a rejection method to eliminate bias.

As an example, if you use it for rolling a die ($min = 1 and $max = 6), it will take three random bits, generate a number between 0 and 7 and reject values 6 and 7. The other ones will be mapped onto the allowed range 1..6 with a simple addition of 1.



bring the generator back to the beginning state.



restore the state of the generator from a previously frozen representation.


   my $seed = $rs->seed;

accessor for the seed. This is used during construction and also when "reset" is called. It is suggested to set this value in the constructor and leave it at that. A seed will anyway be auto-generated when not available.


The code leverages some experimental Perl features like signatures and postderef; for this reason, at least perl 5.20 will be needed.

Report bugs through GitHub (patches welcome) at


Flavio Poletti <>


Copyright (C) 2018 by Flavio Poletti <>

This module is free software. You can redistribute it and/or modify it under the terms of the Artistic License 2.0.

This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.