#ifndef RANDOMINUS_H #define RANDOMINUS_H /* To randomize an array - hopefully as fast as possible */ #include "fastrand/fastrand.h" /** swap */ static void inline rd_swap(uint32_t *a, uint32_t *b) { uint32_t tmp = *a; *a = *b; *b = tmp; } /** This is by no means "cryptographically correct" or stuff, but fast */ static inline void randominus(uint32_t *a, int n, uint32_t seed) { /** Initialized ILP random generator */ uint32_t ilp_seeds[8]; rand_ilp_state rsi; rand_state rs = init_rand(); for(int i = 0; i < 8; ++i) { uint32_t choice = rand_between(&rs, 0, n); ilp_seeds[i] = choice; } /** Go over the array and randomly swap stuff - hand unrolled with ILP random get! */ for(int i = 0; i < (n - 8); i += 8) { uint32_t to0 = fastmodlike(lcg_ilp(&rsi, A), n); uint32_t to1 = fastmodlike(lcg_ilp(&rsi, B), n); uint32_t to2 = fastmodlike(lcg_ilp(&rsi, C), n); uint32_t to3 = fastmodlike(lcg_ilp(&rsi, D), n); uint32_t to4 = fastmodlike(lcg_ilp(&rsi, E), n); uint32_t to5 = fastmodlike(lcg_ilp(&rsi, F), n); uint32_t to6 = fastmodlike(lcg_ilp(&rsi, G), n); uint32_t to7 = fastmodlike(lcg_ilp(&rsi, H), n); rd_swap(&a[i], &a[to0]); rd_swap(&a[i + 1], &a[to1]); rd_swap(&a[i + 2], &a[to2]); rd_swap(&a[i + 3], &a[to3]); rd_swap(&a[i + 4], &a[to4]); rd_swap(&a[i + 5], &a[to5]); rd_swap(&a[i + 6], &a[to6]); rd_swap(&a[i + 7], &a[to7]); } } #endif /* RANDOMINUS_H */