Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/o0101/longbore
:straight_ruler: longbore - A PRNG with infinite state that passes Dieharder and PractRand
https://github.com/o0101/longbore
csprng npm-package prng random-generation random-number-generators rng simple
Last synced: 15 days ago
JSON representation
:straight_ruler: longbore - A PRNG with infinite state that passes Dieharder and PractRand
- Host: GitHub
- URL: https://github.com/o0101/longbore
- Owner: o0101
- License: mit
- Created: 2017-06-05T12:51:09.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2020-01-22T06:56:30.000Z (almost 5 years ago)
- Last Synced: 2024-10-11T11:53:45.144Z (about 1 month ago)
- Topics: csprng, npm-package, prng, random-generation, random-number-generators, rng, simple
- Language: JavaScript
- Homepage:
- Size: 29.3 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Longbore
Memorizable, simple random number generator with up to infinite internal state that pass Dieharder and PractRand. Set the state as big as you want.
**Please consider this primitive insecure as it does not pass SMHasher**.
## Latest News
Longbore 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.
```js
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
```js
const longbore = require('dosyrng');
const rng = longbore.d451();console.log( rng.round() );
```The RNGs are wrapped as [iterators](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Iterators_and_Generators), so you can easily do:
```js
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` and host it somewhere and load it as a script
```html
const longbore = dosyrng.d451();
```# 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](http://pracrand.sourceforge.net/) which is a [top-notch bias finder for RNGs](https://stackoverflow.com/a/27160492/7652736). 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:
```js
{
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:
```js
const rng = dosyrng.custom( 123, 2 );
```# Iteration
The RNGs created by Longbore respect the normal JavaScript iteration protocol. But they also can be run by simple calling the `round()` function on the RNG object as well.
```js
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.
```js
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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) 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
- [longbore on npm](https://www.npmjs.com/package/dosyrng)