Skip to content

Instantly share code, notes, and snippets.

@grafi-tt
Last active February 6, 2020 00:42
Show Gist options
  • Save grafi-tt/886e0ced880195eac50ffae50e4d101f to your computer and use it in GitHub Desktop.
Save grafi-tt/886e0ced880195eac50ffae50e4d101f to your computer and use it in GitHub Desktop.
/* Written by Shunsuke Shimizu.
*
* 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/>.
*/
#include <stddef.h>
#include <stdint.h>
#include <unif01.h>
#include <bbattery.h>
typedef struct melty2_name_ {
uint32_t v[8];
} melty2_name;
typedef struct melty2_key_ {
uint32_t v_[6];
} melty2_key;
static inline uint32_t melty2_rotl_(uint32_t v, int n) {
return (v << n) | (v >> (32 - n));
}
static void melty2_inject_(uint32_t *v, uint32_t a, uint32_t b) {
v[0] += a;
v[1] -= a;
v[2] += b;
v[3] -= b;
}
static void melty2_permute_(uint32_t *v) {
v[0] = melty2_rotl_(v[0], 7);
v[1] += v[0];
v[2] ^= v[1];
v[2] = melty2_rotl_(v[2], 9);
v[3] += v[2];
v[4] ^= v[3];
v[4] = melty2_rotl_(v[4], 13);
v[5] += v[4];
v[0] ^= v[5];
v[0] = melty2_rotl_(v[0], 18);
v[1] -= v[0];
v[2] ^= v[1];
v[2] = melty2_rotl_(v[2], 7);
v[3] -= v[2];
v[4] ^= v[3];
v[4] = melty2_rotl_(v[4], 9);
v[5] -= v[4];
v[0] ^= v[5];
v[0] = melty2_rotl_(v[0], 13);
v[1] += v[0];
v[2] ^= v[1];
v[2] = melty2_rotl_(v[2], 18);
v[3] += v[2];
v[4] ^= v[3];
v[4] = melty2_rotl_(v[4], 12);
v[5] += v[4];
v[0] ^= v[5];
}
static inline void melty2_initkey(melty2_key *key, const melty2_name *name, uint64_t global_seed, uint64_t global_ctr) {
uint32_t v0[6] = {2718281828, 2718281828, 2718281828, 2718281828, 2718281828, 2718281828};
uint32_t v1[6] = {2718281828, 3141592653, 2718281828, 3141592653, 2718281828, 3141592653};
uint32_t v2[6] = {3141592653, 2718281828, 3141592653, 2718281828, 3141592653, 2718281828};
uint32_t v3[6] = {3141592653, 3141592653, 3141592653, 3141592653, 3141592653, 3141592653};
if (name) {
melty2_inject_(v0, name->v[0], name->v[1]);
melty2_inject_(v1, name->v[2], name->v[3]);
melty2_inject_(v2, name->v[4], name->v[5]);
melty2_inject_(v3, name->v[6], name->v[7]);
}
uint32_t a = v0[0];
uint32_t b = v1[0];
uint32_t c = v2[0];
uint32_t d = v3[0];
melty2_inject_(v0, d, (uint32_t)global_seed);
melty2_inject_(v1, a, (uint32_t)global_ctr);
melty2_inject_(v2, b, (uint32_t)(global_seed >> 32));
melty2_inject_(v3, c, (uint32_t)(global_ctr >> 32));
melty2_permute_(v0);
melty2_permute_(v1);
melty2_permute_(v2);
melty2_permute_(v3);
melty2_permute_(v0);
melty2_permute_(v1);
melty2_permute_(v2);
melty2_permute_(v3);
key->v_[0] = v0[0] ^ v1[0] ^ v2[0] ^ v3[0];
key->v_[1] = v0[1] ^ v1[1] ^ v2[1] ^ v3[1];
key->v_[2] = v0[2] ^ v1[2] ^ v2[2] ^ v3[2];
key->v_[3] = v0[3] ^ v1[3] ^ v2[3] ^ v3[3];
key->v_[4] = v0[4] ^ v1[4] ^ v2[4] ^ v3[4];
key->v_[5] = v0[5] ^ v1[5] ^ v2[5] ^ v3[5];
}
static inline void melty2_splitkey(melty2_key *key, melty2_key *newkey) {
uint32_t v0[6] = {key->v_[0], key->v_[1], key->v_[2], key->v_[3], key->v_[4], key->v_[5]};
uint32_t v1[6] = {key->v_[0], key->v_[1], key->v_[2], key->v_[3], key->v_[4], key->v_[5]};
uint32_t v2[6] = {key->v_[0], key->v_[1], key->v_[2], key->v_[3], key->v_[4], key->v_[5]};
uint32_t v3[6] = {key->v_[0], key->v_[1], key->v_[2], key->v_[3], key->v_[4], key->v_[5]};
melty2_inject_(v0, 2718281828, 0);
melty2_inject_(v1, 0, 2718281828);
melty2_inject_(v2, 3141592653, 0);
melty2_inject_(v3, 0, 3141592653);
melty2_permute_(v0);
melty2_permute_(v1);
melty2_permute_(v2);
melty2_permute_(v3);
melty2_permute_(v0);
melty2_permute_(v1);
melty2_permute_(v2);
melty2_permute_(v3);
uint32_t a = v0[0];
uint32_t b = v1[0];
uint32_t c = v2[0];
uint32_t d = v3[0];
melty2_inject_(v0, d, 0);
melty2_inject_(v1, a, 0);
melty2_inject_(v2, b, 0);
melty2_inject_(v3, c, 0);
melty2_permute_(v0);
melty2_permute_(v1);
melty2_permute_(v2);
melty2_permute_(v3);
key->v_[0] = v0[0] ^ v2[0];
key->v_[1] = v0[1] ^ v2[1];
key->v_[2] = v0[2] ^ v2[2];
key->v_[3] = v0[3] ^ v2[3];
key->v_[4] = v0[4] ^ v2[4];
key->v_[5] = v0[5] ^ v2[5];
newkey->v_[0] = v1[0] ^ v3[0];
newkey->v_[1] = v1[1] ^ v3[1];
newkey->v_[2] = v1[2] ^ v3[2];
newkey->v_[3] = v1[3] ^ v3[3];
newkey->v_[4] = v1[4] ^ v3[4];
newkey->v_[5] = v1[5] ^ v3[5];
}
static uint32_t melty2_gen32(const melty2_key *key, uint64_t idx) {
uint32_t v[6] = {key->v_[0], key->v_[1], key->v_[2], key->v_[3], key->v_[4], key->v_[5]};
melty2_inject_(v, (uint32_t)idx, (uint32_t)(idx >> 32));
melty2_permute_(v);
return v[0] ^ v[3];
}
//
// TestU01
uint32_t melty2() {
static melty2_key key;
static uint64_t idx = 0;
static uint32_t buf[4];
static int pos = 0;
if (pos == 0) {
melty2_initkey(&key, NULL, 0, 0);
pos = 4;
}
if (pos == 4) {
pos = 0;
// exploit superscalar
buf[0] = melty2_gen32(&key, idx++);
buf[1] = melty2_gen32(&key, idx++);
buf[2] = melty2_gen32(&key, idx++);
buf[3] = melty2_gen32(&key, idx++);
}
uint32_t r = buf[pos++];
#ifdef BITREV
uint32_t t;
t = r & UINT32_C(0x00FF00FF);
r = (t << 16) | (t >> 16) | (t ^ r);
t = r & UINT32_C(0x0F0F0F0F);
r = (t << 8) | (t >> 24) | (t ^ r);
t = r & UINT32_C(0x33333333);
r = (t << 4) | (t >> 28) | (t ^ r);
t = r & UINT32_C(0x55555555);
r = (t << 2) | (t >> 30) | (t ^ r);
r = (r << 1) | (r >> 31);
#endif
return r;
}
int main() {
unif01_Gen *gen;
gen = unif01_CreateExternGenBits("melty2", melty2);
// bbattery_SmallCrush(gen);
// bbattery_Crush(gen);
bbattery_BigCrush(gen);
unif01_DeleteExternGenBits(gen);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment