• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
3 
4    To the extent possible under law, the author has dedicated all copyright
5    and related and neighboring rights to this software to the public domain
6    worldwide. This software is distributed without any warranty.
7 
8    See <https://creativecommons.org/publicdomain/zero/1.0/>.
9 
10    This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.
11    It has excellent (sub-ns) speed, a state (256 bits) that is large
12    enough for any parallel application, and it passes all tests we are
13    aware of.
14 
15    For generating just floating-point numbers, xoshiro256+ is even faster.
16 
17    The state must be seeded so that it is not everywhere zero. If you have
18    a 64-bit seed, we suggest to seed a splitmix64 generator and use its
19    output to fill s[].
20 */
21 
22 #include <stdint.h>
23 #include "afl-fuzz.h"
24 #include "types.h"
25 
26 #define XXH_INLINE_ALL
27 #include "xxhash.h"
28 #undef XXH_INLINE_ALL
29 
rand_set_seed(afl_state_t * afl,s64 init_seed)30 void rand_set_seed(afl_state_t *afl, s64 init_seed) {
31 
32   afl->init_seed = init_seed;
33   afl->rand_seed[0] =
34       hash64((u8 *)&afl->init_seed, sizeof(afl->init_seed), HASH_CONST);
35   afl->rand_seed[1] = afl->rand_seed[0] ^ 0x1234567890abcdef;
36   afl->rand_seed[2] = (afl->rand_seed[0] & 0x1234567890abcdef) ^
37                       (afl->rand_seed[1] | 0xfedcba9876543210);
38 
39 }
40 
41 #define ROTL(d, lrot) ((d << (lrot)) | (d >> (8 * sizeof(d) - (lrot))))
42 
43 #ifdef WORD_SIZE_64
44 // romuDuoJr
rand_next(afl_state_t * afl)45 inline AFL_RAND_RETURN rand_next(afl_state_t *afl) {
46 
47   AFL_RAND_RETURN xp = afl->rand_seed[0];
48   afl->rand_seed[0] = 15241094284759029579u * afl->rand_seed[1];
49   afl->rand_seed[1] = afl->rand_seed[1] - xp;
50   afl->rand_seed[1] = ROTL(afl->rand_seed[1], 27);
51   return xp;
52 
53 }
54 
55 #else
56 // RomuTrio32
rand_next(afl_state_t * afl)57 inline AFL_RAND_RETURN rand_next(afl_state_t *afl) {
58 
59   AFL_RAND_RETURN xp = afl->rand_seed[0], yp = afl->rand_seed[1],
60                   zp = afl->rand_seed[2];
61   afl->rand_seed[0] = 3323815723u * zp;
62   afl->rand_seed[1] = yp - xp;
63   afl->rand_seed[1] = ROTL(afl->rand_seed[1], 6);
64   afl->rand_seed[2] = zp - yp;
65   afl->rand_seed[2] = ROTL(afl->rand_seed[2], 22);
66   return xp;
67 
68 }
69 
70 #endif
71 
72 #undef ROTL
73 
74 /* returns a double between 0.000000000 and 1.000000000 */
75 
rand_next_percent(afl_state_t * afl)76 inline double rand_next_percent(afl_state_t *afl) {
77 
78   return (double)(((double)rand_next(afl)) / (double)0xffffffffffffffff);
79 
80 }
81 
82 /* we switch from afl's murmur implementation to xxh3 as it is 30% faster -
83    and get 64 bit hashes instead of just 32 bit. Less collisions! :-) */
84 
85 #ifdef _DEBUG
hash32(u8 * key,u32 len,u32 seed)86 u32 hash32(u8 *key, u32 len, u32 seed) {
87 
88 #else
89 inline u32 hash32(u8 *key, u32 len, u32 seed) {
90 
91 #endif
92 
93   (void)seed;
94   return (u32)XXH3_64bits(key, len);
95 
96 }
97 
98 #ifdef _DEBUG
99 u64 hash64(u8 *key, u32 len, u64 seed) {
100 
101 #else
102 inline u64 hash64(u8 *key, u32 len, u64 seed) {
103 
104 #endif
105 
106   (void)seed;
107   return XXH3_64bits(key, len);
108 
109 }
110 
111