mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-02-15 09:05:52 +00:00
Add new randomness subsystem
This commit is contained in:
parent
c9365a3266
commit
9664352a11
7 changed files with 282 additions and 0 deletions
|
@ -1362,6 +1362,9 @@ void DSQ::init()
|
||||||
title(false);
|
title(false);
|
||||||
else
|
else
|
||||||
enqueueJumpState("BitBlotLogo");
|
enqueueJumpState("BitBlotLogo");
|
||||||
|
|
||||||
|
// Use the time needed to load everything as an extra source of entropy
|
||||||
|
Randomness::addEntropy(SDL_GetTicks());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSQ::recreateBlackBars()
|
void DSQ::recreateBlackBars()
|
||||||
|
|
|
@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "DSQ.h"
|
#include "DSQ.h"
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <SDL_main.h>
|
#include <SDL_main.h>
|
||||||
|
#include "Randomness.h"
|
||||||
|
|
||||||
|
|
||||||
extern "C" int main(int argc,char *argv[])
|
extern "C" int main(int argc,char *argv[])
|
||||||
|
@ -45,6 +46,13 @@ extern "C" int main(int argc,char *argv[])
|
||||||
extraDataDir = AQUARIA_EXTRA_DATA_DIR;
|
extraDataDir = AQUARIA_EXTRA_DATA_DIR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Couple pointers to help enhance entropy, suppported by the system's ASLR if available
|
||||||
|
{
|
||||||
|
void *p = malloc(1);
|
||||||
|
Randomness::init((uintptr_t)argv, (uintptr_t)&dsqParam, (uintptr_t)&(malloc), (uintptr_t)&p);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
DSQ dsql(dsqParam, extraDataDir);
|
DSQ dsql(dsqParam, extraDataDir);
|
||||||
dsql.init();
|
dsql.init();
|
||||||
|
|
|
@ -65,6 +65,8 @@ set(BBGE_SRCS
|
||||||
Quad.h
|
Quad.h
|
||||||
QuadGrid.cpp
|
QuadGrid.cpp
|
||||||
QuadGrid.h
|
QuadGrid.h
|
||||||
|
Randomness.cpp
|
||||||
|
Randomness.h
|
||||||
ReadXML.cpp
|
ReadXML.cpp
|
||||||
ReadXML.h
|
ReadXML.h
|
||||||
Rect.h
|
Rect.h
|
||||||
|
|
|
@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "GLLoad.h"
|
#include "GLLoad.h"
|
||||||
#include "RenderBase.h"
|
#include "RenderBase.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
#include "Randomness.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -1152,6 +1153,15 @@ void Core::run(float runTime)
|
||||||
dt = (nowTicks-thenTicks)/1000.0;
|
dt = (nowTicks-thenTicks)/1000.0;
|
||||||
thenTicks = nowTicks;
|
thenTicks = nowTicks;
|
||||||
|
|
||||||
|
uint64_t entropy = nowTicks;
|
||||||
|
entropy <<= 3;
|
||||||
|
entropy ^= frames;
|
||||||
|
entropy <<= 3;
|
||||||
|
entropy += (mouse.buttons.left << 1) | (mouse.buttons.middle << 2) | (mouse.buttons.right << 3);
|
||||||
|
entropy ^= lastEventTimestamp;
|
||||||
|
Randomness::addEntropy(entropy);
|
||||||
|
|
||||||
|
|
||||||
if (!avgFPS.empty())
|
if (!avgFPS.empty())
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1459,6 +1469,8 @@ static const TextInputMapping textInputMap[]
|
||||||
|
|
||||||
void Core::onEvent(const SDL_Event& event)
|
void Core::onEvent(const SDL_Event& event)
|
||||||
{
|
{
|
||||||
|
lastEventTimestamp = event.common.timestamp;
|
||||||
|
|
||||||
const bool focus = window->hasFocus();
|
const bool focus = window->hasFocus();
|
||||||
if(event.type == sdlUserMouseEventID)
|
if(event.type == sdlUserMouseEventID)
|
||||||
{
|
{
|
||||||
|
|
|
@ -320,6 +320,7 @@ public:
|
||||||
bool loopDone;
|
bool loopDone;
|
||||||
|
|
||||||
Mouse mouse;
|
Mouse mouse;
|
||||||
|
unsigned lastEventTimestamp;
|
||||||
|
|
||||||
AfterEffectManager *afterEffectManager;
|
AfterEffectManager *afterEffectManager;
|
||||||
|
|
||||||
|
|
182
BBGE/Randomness.cpp
Normal file
182
BBGE/Randomness.cpp
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
// Must be included first to put the implementation here
|
||||||
|
#include "ascon-sponge.h"
|
||||||
|
|
||||||
|
#include "Base.h"
|
||||||
|
#include "Randomness.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "SDLwrap.h"
|
||||||
|
|
||||||
|
|
||||||
|
static SlowRand s_sysrand;
|
||||||
|
static SplitMix64 s_splitmix;
|
||||||
|
static Xoshiro128 s_xosh;
|
||||||
|
static FastRand s_fastr;
|
||||||
|
|
||||||
|
|
||||||
|
static inline uint32_t rotl32(const uint32_t x, uint32_t k)
|
||||||
|
{
|
||||||
|
return (x << k) | (x >> (32u - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
// via https://blog.bithole.dev/blogposts/random-float/
|
||||||
|
static inline float int_to_float01(uint32_t r)
|
||||||
|
{
|
||||||
|
union { uint32_t u32; float f; } u;
|
||||||
|
u.u32 = (r >> 9u) | 0x3f800000;
|
||||||
|
return u.f - 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Randomness::init(uintptr_t a, uintptr_t b, uintptr_t c, uintptr_t d)
|
||||||
|
{
|
||||||
|
uint64_t v[] =
|
||||||
|
{
|
||||||
|
uint64_t(a),
|
||||||
|
uint64_t(rand()),
|
||||||
|
uint64_t(rand()),
|
||||||
|
uint64_t(rand()),
|
||||||
|
uint64_t(time(NULL)),
|
||||||
|
uint64_t(clock()),
|
||||||
|
uint64_t(&SDL_GetTicks),
|
||||||
|
uint64_t(&time),
|
||||||
|
uint64_t(&s_sysrand),
|
||||||
|
// These functions should be ok to call without calling SDL_Init() first
|
||||||
|
uint64_t(SDL_GetThreadID(NULL)),
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
|
uint64_t(SDL_GetPerformanceCounter()),
|
||||||
|
uint64_t(SDL_GetPerformanceFrequency()),
|
||||||
|
uint64_t(SDL_GetSystemRAM()),
|
||||||
|
uint64_t(SDL_GetCPUCount())
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
s_sysrand.absorb(v, Countof(v));
|
||||||
|
s_splitmix.state = s_sysrand.duplex(b);
|
||||||
|
|
||||||
|
s_xosh.u.q[0] = s_sysrand.duplex(c);
|
||||||
|
s_xosh.u.q[1] = s_sysrand.duplex(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Randomness::addEntropy(uint64_t x)
|
||||||
|
{
|
||||||
|
s_fastr.state ^= s_sysrand.duplex(x);
|
||||||
|
s_sysrand.absorb(s_splitmix.next()); // pulling from splitmix permutes it
|
||||||
|
s_sysrand.absorb(s_xosh.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Randomness::getBits64()
|
||||||
|
{
|
||||||
|
return s_splitmix.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Randomness::getBits32()
|
||||||
|
{
|
||||||
|
return s_fastr.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
float Randomness::getFloat01()
|
||||||
|
{
|
||||||
|
return s_fastr.f01();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SplitMix64::SplitMix64()
|
||||||
|
: state(s_sysrand.next())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SplitMix64::SplitMix64(uint64_t seed)
|
||||||
|
: state(seed)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t SplitMix64::next()
|
||||||
|
{
|
||||||
|
uint64_t z = (state += UINT64_C(0x9e3779b97f4a7c15));
|
||||||
|
z = (z ^ (z >> 30u)) * UINT64_C(0xbf58476d1ce4e5b9);
|
||||||
|
z = (z ^ (z >> 27u)) * UINT64_C(0x94d049bb133111eb);
|
||||||
|
return z ^ (z >> 31u);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SlowRand::SlowRand()
|
||||||
|
{
|
||||||
|
ascon_sponge_init(&ascon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SlowRand::absorb(const uint64_t* seed, size_t n)
|
||||||
|
{
|
||||||
|
ascon_sponge_absorb_blocks(&ascon, seed, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlowRand::absorb(uint64_t val)
|
||||||
|
{
|
||||||
|
ascon_sponge_absorb_block(&ascon, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t SlowRand::duplex(uint64_t duplex)
|
||||||
|
{
|
||||||
|
return ascon_sponge_duplex_block(&ascon, duplex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t SlowRand::next()
|
||||||
|
{
|
||||||
|
return ascon_sponge_squeeze_block(&ascon);
|
||||||
|
}
|
||||||
|
|
||||||
|
Xoshiro128::Xoshiro128()
|
||||||
|
{
|
||||||
|
u.q[0] = s_splitmix.next();
|
||||||
|
u.q[1] = s_sysrand.duplex((uintptr_t)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Xoshiro128::Xoshiro128(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
||||||
|
{
|
||||||
|
u.s[0] = a;
|
||||||
|
u.s[1] = b;
|
||||||
|
u.s[2] = c;
|
||||||
|
u.s[3] = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Xoshiro128::next()
|
||||||
|
{
|
||||||
|
const uint32_t result = u.s[0] + u.s[3];
|
||||||
|
const uint32_t t = u.s[1] << 9;
|
||||||
|
u.s[2] ^= u.s[0];
|
||||||
|
u.s[3] ^= u.s[1];
|
||||||
|
u.s[1] ^= u.s[2];
|
||||||
|
u.s[0] ^= u.s[3];
|
||||||
|
u.s[2] ^= t;
|
||||||
|
u.s[3] = rotl32(u.s[3], 11);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Xoshiro128::f01()
|
||||||
|
{
|
||||||
|
return int_to_float01(next());
|
||||||
|
}
|
||||||
|
|
||||||
|
FastRand::FastRand()
|
||||||
|
: state(s_sysrand.next())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FastRand::FastRand(uint64_t state)
|
||||||
|
: state(state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FastRand::next()
|
||||||
|
{
|
||||||
|
// SDL3's rand()
|
||||||
|
state = state * 0xff1cd035u + 0x05;
|
||||||
|
return state >> 32u;
|
||||||
|
}
|
||||||
|
|
||||||
|
float FastRand::f01()
|
||||||
|
{
|
||||||
|
return int_to_float01(next());
|
||||||
|
}
|
74
BBGE/Randomness.h
Normal file
74
BBGE/Randomness.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
#ifndef RANDOMNESS_H
|
||||||
|
#define RANDOMNESS_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define ASCON_SPONGE_TYPES_ONLY
|
||||||
|
#include "ascon-sponge.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Randomness
|
||||||
|
{
|
||||||
|
// Call this once on startup
|
||||||
|
void init(uintptr_t a, uintptr_t b, uintptr_t c, uintptr_t d);
|
||||||
|
|
||||||
|
// Call this once per frame with some number
|
||||||
|
void addEntropy(uint64_t x);
|
||||||
|
|
||||||
|
uint64_t getBits64();
|
||||||
|
uint32_t getBits32();
|
||||||
|
float getFloat01(); // in [0..1)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SplitMix64
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SplitMix64();
|
||||||
|
SplitMix64(uint64_t seed);
|
||||||
|
uint64_t next();
|
||||||
|
uint64_t state;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SlowRand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SlowRand();
|
||||||
|
void absorb(const uint64_t *seed, size_t n);
|
||||||
|
void absorb(uint64_t val);
|
||||||
|
uint64_t next();
|
||||||
|
uint64_t duplex(uint64_t in); // extract one, put one back in
|
||||||
|
private:
|
||||||
|
ascon_state_t ascon;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Xoshiro128+ actually
|
||||||
|
struct Xoshiro128
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Xoshiro128();
|
||||||
|
Xoshiro128(uint32_t a, uint32_t b, uint32_t c, uint32_t d);
|
||||||
|
uint32_t next();
|
||||||
|
float f01();
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t s[4];
|
||||||
|
uint64_t q[2];
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FastRand
|
||||||
|
{
|
||||||
|
FastRand();
|
||||||
|
FastRand(uint64_t state);
|
||||||
|
|
||||||
|
uint32_t next();
|
||||||
|
float f01();
|
||||||
|
|
||||||
|
uint64_t state;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Loading…
Add table
Reference in a new issue