1.0.3 • Published 7 years ago

dosyrng v1.0.3

Weekly downloads
1
License
MIT
Repository
github
Last release
7 years ago

dosyrng

Memorizable, simple 8-bit random number generators that pass Dieharder and PractRand.

https://nodei.co/npm/dosyrng.png?downloads=true&downloadRank=true&stars=true contributions welcome

Latest News

dosyrng passes Dieharder and PractRand. Oooh yeah!

Testing on 1 Gb initially produced 1 FAILED ( rgb_lagged_sums 31 ), and I concluded this was because the test was looping the 1 Gb input so many times and finding correlations that otherwise were not present. When I truncated the input to a large prime less than 1 Gb this test passed, adding support for my theory as to why it failed. Oooh yeah!

Simplicity by Design

The round function is only a few lines long.

  function round() {
    let j = 44;
    let sum = 1;
    for( let i = 0; i < 45; i++ ) {
      s[j] ^= (s[i] >> 1) ^ (sum << 1);
      s[i] += s[j] + 1;
      j = ( j + 1 ) % 45;
      sum += s[i];
    }
    return sum & 255;
  }

That's it.

DOSY defines a family of truly superb, super-simple, variable-state PRNGs ( pseudorandom number generators ) / CSPRNGs ( cryptogrpahically secure pseudorandom number generators ), that are both extraordinarily simple, and pass PractRand.

Install & Using

If you're using node you can just npm install dosyrng and

const dosyrng = require('dosyrng');
const rng = dosyrng.d451();

console.log( rng.round() );

The RNGs are wrapped as iterators, so you can easily do:

let count = 0;
rng.length = 100;  // note the special length property puts a limit on a single iteration
for( const rvar of rng ) {
  console.log( rvar );
}

To run it in the browser, just download the index.js file, save it as dosyrng.js, host it somewhere and load it as a script

  <script src=/dosyrng.js></script>
  <script>
    const rng = dosyrng.d451();
  </script>

Use Cases

Dosy is not super fast ( it iterates its entire state once for each output byte ), and it was designed to mostly generate short keystreams to encrypt short messages, under 4K in length.

Test Results

Dosy was tested using PractRand which is a top-notch bias finder for RNGs. Despite being so simple to implement, both D451 and D453 passed PractRand ( at 16 MB, 32 MB and 64 MB, no other sequence lengths were generated ). So far the following values are tested:

{
  d31: "fails", // 24 bit 
  d41: "passes", // 32 bit 
  d51: "passes", // 40 bit 
  d81: "passes", // 64 bit
  d451: "passes", // 360 bit
  d452: "passes",
  d453: "passes",
  d454: "passes",
  d455: "passes"
}

Naming

The DOSY structure defines a family of generators specified by their state length ( in bytes ) and a bit shift ( in bits ). Each algorithm is named like

D451 - 45 bytes of state, 1 bit of shift

or, more generally like, DXXY.

Where XX ( or XXX or XXXX and so on, is the state length ) and Y is the bit shift.

Customization

You can set your own parameters:

  const rng = dosyrng.custom( 123, 2 );

Iteration

The RNGs created by dosyrng respect the normal JavaScript iteration protocol. But they also can be run by simple calling the round() function on the RNG object as well.

rng[Symbol.iterator]().next().value; // OK
rng.round(); // OK

And these RNGs also have an extension to the iterator protocol. If you set their .length property you can control the length of the iteration to be whatever you like. Without setting length as a number, the iteration is infinite.

rng.length = 10;
for( const rvar of rng ) console.log( rvar ); // 10 values

Key Scheduling

You can access the interal state of the generator ( after the first value has been generated ). You can do whatever you like to this state. The state is a Typed Array so standard Typed Array APIs apply.

You can implement your own key scheduling algorithm to include a key to seed the generator, like I did. I used a "sponge" construction, with the first 5 bytes set to absorb the key, by successive rounds, and the last 40 bytes set to the "spare capacity". This key scheduling algorithm worked well, and it's not the only way you can seed this family of generators.

Links