Skip to content

Instantly share code, notes, and snippets.

@senevoldsen
Created September 13, 2019 15:12
Show Gist options
  • Save senevoldsen/3559d6711f000e981539904c834319f0 to your computer and use it in GitHub Desktop.
Save senevoldsen/3559d6711f000e981539904c834319f0 to your computer and use it in GitHub Desktop.
#define SPRITZ_N 256
#define SPRITZ_N_FLOOR_HALF 128
#define SPRITZ_D 16
#define SPRITZ_I_S 0
#define SPRITZ_I_I 1
#define SPRITZ_I_J 2
#define SPRITZ_I_K 3
#define SPRITZ_I_Z 4
#define SPRITZ_I_A 5
#define SPRITZ_I_W 6
#define SPRITZ_ADD_M(X,Y)\
(((X) + (Y)) mod SPRITZ_N)
#define SPRITZ_SHUFFLE_CHECK \
if ((_spritz select SPRITZ_I_A) == SPRITZ_N_FLOOR_HALF) then {\
[_spritz] call Spritz_Shuffle;\
}
#define SPRITZ_SWAP(IDX_A, IDX_B) \
private _temp = _S select IDX_A;\
_S set [IDX_A, _S select IDX_B];\
_S set [IDX_B, _temp]
Spritz_Init =
{
private _S = [];
_S resize SPRITZ_N;
for "_i" from 0 to (SPRITZ_N - 1) do {
_S set [_i, _i];
};
[_S, 0, 0, 0, 0, 0, 1];
};
// Input is array of SPRITZ_N "bytes" / words
Spritz_Absorb =
{
params ["_spritz", "_input"];
{[_spritz, _x] call Spritz_AbsorbByte} count _input;
};
Spritz_AbsorbByte =
{
params ["_spritz", "_byte"];
[_spritz, _byte mod 16] call Spritz_AbsorbNibble;
[_spritz, floor (_byte / 16)] call Spritz_AbsorbNibble;
};
Spritz_AbsorbNibble =
{
params ["_spritz", "_nibble"];
SPRITZ_SHUFFLE_CHECK;
private _S = _spritz # 0;
private _a = _spritz # SPRITZ_I_A;
SPRITZ_SWAP(_a, (SPRITZ_N_FLOOR_HALF + _nibble));
_spritz set [SPRITZ_I_A, _a + 1];
};
Spritz_AbsorbStop =
{
params ["_spritz"];
SPRITZ_SHUFFLE_CHECK;
private _a = _spritz # SPRITZ_I_A;
_spritz set [SPRITZ_I_A, _a + 1];
};
Spritz_Shuffle =
{
params ["_spritz"];
[_spritz, SPRITZ_N * 2] call Spritz_Whip;
[_spritz] call Spritz_Crush;
[_spritz, SPRITZ_N * 2] call Spritz_Whip;
[_spritz] call Spritz_Crush;
[_spritz, SPRITZ_N * 2] call Spritz_Whip;
_spritz set [SPRITZ_I_A, 0];
};
Spritz_GCD =
{
// We know that one of the numbers is SPRITZ_N.
// We also know that the other number is >0.
params ["_b"];
private _a = SPRITZ_N;
while {_b != 0} do {
private _t = _a mod _b;
_a = _b;
_b = _t;
};
_a;
};
Spritz_Whip =
{
params ["_spritz", "_r"];
for "_i" from 1 to _r do {
[_spritz] call Spritz_Update;
};
private _w = (_spritz # SPRITZ_I_W) + 1;
while {([_w] call Spritz_GCD) != 1} do {
_w = _w + 1;
};
_spritz set [SPRITZ_I_W, _w];
};
Spritz_Crush =
{
params ["_spritz"];
private _S = _spritz # SPRITZ_I_S;
for "_v" from 0 to (SPRITZ_N_FLOOR_HALF-1) do {
private _u = SPRITZ_N - 1 - _v;
if ((_S # _v) > (_S # _u)) then {
SPRITZ_SWAP(_v, _u);
};
};
};
Spritz_Squeeze =
{
params ["_spritz"];
// Temporary only 1.
SPRITZ_SHUFFLE_CHECK;
[_spritz] call Spritz_Drip;
};
Spritz_Drip =
{
params ["_spritz"];
SPRITZ_SHUFFLE_CHECK;
[_spritz] call Spritz_Update;
[_spritz] call Spritz_Output;
};
Spritz_Output =
{
params ["_spritz"];
private _S = _spritz select SPRITZ_I_S;
private _inner = _S # SPRITZ_ADD_M(_spritz # SPRITZ_I_Z, _spritz # SPRITZ_I_K);
_inner = _S # SPRITZ_ADD_M(_spritz # SPRITZ_I_I, _inner);
_inner = _S # SPRITZ_ADD_M(_spritz # SPRITZ_I_J, _inner);
_spritz set [SPRITZ_I_Z, _inner];
_inner;
};
Spritz_Update =
{
params ["_spritz"];
private _S = _spritz # SPRITZ_I_S;
private _i = SPRITZ_ADD_M((_spritz # SPRITZ_I_I) , (_spritz # SPRITZ_I_W));
private _k = _spritz # SPRITZ_I_K;
private _j = _spritz # SPRITZ_I_J;
_j = SPRITZ_ADD_M(_k, (_S # SPRITZ_ADD_M(_j, (_S # _i))));
_k = SPRITZ_ADD_M(_i, SPRITZ_ADD_M(_k, (_S # _j)));
SPRITZ_SWAP(_i, _j);
_spritz set [SPRITZ_I_I, _i];
_spritz set [SPRITZ_I_J, _j];
_spritz set [SPRITZ_I_K, _k];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment