Skip to content

Instantly share code, notes, and snippets.

@magurosan
Created December 6, 2020 06:46
Show Gist options
  • Save magurosan/c9199b8cc8838a7e99d52295d7a9bdc2 to your computer and use it in GitHub Desktop.
Save magurosan/c9199b8cc8838a7e99d52295d7a9bdc2 to your computer and use it in GitHub Desktop.
Multiple instance capable xoshiro256 implementation on C
/*
xoshiro256+/++/* implementation for multiple instances
(C)2020 Masaki Ota. Some rights reserved.
Original codes are written by
2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
*/
#include "xoshiro256.h"
static void jump_common(xoshiro256_t *state, const uint64_t jump_array[4]) {
uint64_t s0, s1, s2, s3;
s0 = s1 = s2 = s3 = 0;
for(int i = 0; i < 4; i++) {
for(int b = 0; b < 64; b++) {
if (jump_array[i] & UINT64_C(1) << b) {
s0 ^= state->s[0];
s1 ^= state->s[1];
s2 ^= state->s[2];
s3 ^= state->s[3];
}
next_common(state);
}
}
state->s[0] = s0;
state->s[1] = s1;
state->s[2] = s2;
state->s[3] = s3;
}
void jump(xoshiro256_t *state) {
static const uint64_t JUMP[] = {
0x180ec6d33cfd0aba,
0xd5a61266f0c9392c,
0xa9582618e03fc9aa,
0x39abdc4529b1661c
};
jump_common(state, JUMP);
}
void long_jump(xoshiro256_t *state) {
static const uint64_t LONG_JUMP[] = {
0x76e15d3efefdcbbf,
0xc5004e441c522fb3,
0x77710069854ee241,
0x39109bb02acbe635
};
jump_common(state, LONG_JUMP);
}
#include <stdint.h>
/*
xoshiro256+/++/* implementation for multiple instances
(C)2020 Masaki Ota. Some rights reserved.
Original codes are written by
2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
*/
struct XOSHIRO256 { uint64_t s[4]; };
typedef struct XOSHIRO256 xoshiro256_t;
inline void next_common(xoshiro256_t *state) {
const uint64_t t = state->s[1] << 17;
state->s[2] ^= state->s[0];
state->s[3] ^= state->s[1];
state->s[1] ^= state->s[2];
state->s[0] ^= state->s[3];
state->s[2] ^= t;
state->s[3] = rotl(state->s[3], 45);
}
inline uint64_t star_star_next(xoshiro256_t *state) {
const uint64_t result = rotl(state->s[1] * 5, 7) * 9;
next_common(state);
return result;
}
inline uint64_t plus_next(xoshiro256_t *state) {
const uint64_t result = state->s[0] + state->s[3];
next_common(state);
return result;
}
inline uint64_t plus_plus_next(xoshiro256_t *state) {
const uint64_t result = rotl(state->s[0] + state->s[3], 23) + state->s[0];
next_common(state);
return result;
}
/* jump functions */
void long_jump(xoshiro256_t *state);
void jump(xoshiro256_t *state);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment