Skip to content

Instantly share code, notes, and snippets.

@maciejczyzewski
Last active February 7, 2021 16:46
Show Gist options
  • Save maciejczyzewski/5b704c9b8f0f13b660d7 to your computer and use it in GitHub Desktop.
Save maciejczyzewski/5b704c9b8f0f13b660d7 to your computer and use it in GitHub Desktop.
Reference Implementation in JavaScript
/* NCG written in 2015 by Maciej A. Czyzewski
To the extent possible under law, the author has dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
// Simulating a 16-bit & 32-bit value
function U16(i) { return i & 0xFFFF; } function U32(i) { return i & 0xFFFFFFFF; }
// S - seed, I - increment, t - mask, i - temporary
var S, I, t, i;
// The length of the initial states
var SIZE = 16;
// The number of rounds in algorithm
var ROUNDS = 1;
// Abbreviation for getting values from the tape
function M(i) { return (((i % SIZE) + SIZE) % SIZE); }
// Bits rotation formula
function R(x, y) { return (((x) << (y)) | ((x) >> (16 - (y)))) }
// Variebles in the algorithm
var a, b, c = 0, d = 0, e;
// Initial state vector (pi digits)
var G, Q = new Array(1, 4, 1, 5, 9, 2, 6, 5,
3, 5, 8, 9, 7, 9, 3, 2);
function push(seed) {
// Preparation
I = U32(seed * 0x3C6EF35F);
for (S = U32(seed), i = 0; i < SIZE; i++) {
// Reinforcement
G[M(i)] = U16(G[M(i)] ^ (((I * (S + 1)) ^ S) >> 16));
G[M(i)] = U16(G[M(i)] ^ (((I * (S - 1)) ^ S) >> 00));
// Finalization
I = U32(I ^ ((G[M(I - 1)] + G[M(i)]) << 16)
^ ((G[M(I + 1)] - G[M(i)]) << 00));
}
}
function pull() {
// Variebles
a = G[M(I + 0)]; b = G[M(I + 1)];
// Initialization
t = U32((a + I) * (b - S));
// Chaos
e = U16((G[M(t - b)] << ((a >>> 0) % 9)) ^ (G[M(t + a)] >> ((b >>> 0) % 9)));
// Rounds
for (i = 0; i < ROUNDS * 2; i += 2) {
// Absorption
c = U16(c ^ G[M(I + i - 2)]); d = U16(d ^ G[M(I + i + 2)]);
// Mixing & Modification
c = U16(c ^ (d = U16(d ^ R(e, (c >>> 0) % 17))));
G[M(I + i - 2)] = U16(G[M(I + i - 2)] - (d = U16(d + (t & c))));
d = U16(d + (c = U16(c + R(t, (d >>> 0) % 17))));
G[M(I + i + 2)] = U16(G[M(I + i + 2)] + (c = U16(c + (e & d))));
}
// Transformation
G[M(I + 0)] = U16(R(c, (t >>> 0) % 17) ^ R(d, (t >>> 0) % 17) ^ (t & a) ^ (e & b));
G[M(I + 1)] = U16((b >> 1) ^ (-(b & 1) & 0xB400)); // LFSR
// Finalization
t = U32(t + (c ^ (b << 8) ^ (d << 16) ^ (a & 0xFF) ^ ((a >> 8) << 24)));
// Cleaning
c = d = 0xFFFF;
// Increment
I = U32(I + 2);
return t;
}
function reset() {
// Copying defaults
G = Q;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment