3#ifndef __ASE_RANDOMHASH_HH__
4#define __ASE_RANDOMHASH_HH__
41 static constexpr uint64_t MWC_A3 = 0xff377e26f82da74a;
56 const __uint128_t t = MWC_A3 * __uint128_t (state[0]) + state[3];
63using FastRng = Mwc256;
82void sha3_224_hash (
const void *data,
size_t data_length, uint8_t hashvalue[28]);
100void sha3_256_hash (
const void *data,
size_t data_length, uint8_t hashvalue[32]);
118void sha3_384_hash (
const void *data,
size_t data_length, uint8_t hashvalue[48]);
136void sha3_512_hash (
const void *data,
size_t data_length, uint8_t hashvalue[64]);
154void shake128_hash (
const void *data,
size_t data_length, uint8_t *hashvalues,
size_t n);
172void shake256_hash (
const void *data,
size_t data_length, uint8_t *hashvalues,
size_t n);
178 union alignas (2 * sizeof (uint64_t))
185 explicit KeccakF1600 ();
187 uint64_t& operator[] (
int index) {
return A[index]; }
188 uint64_t operator[] (
int index)
const {
return A[index]; }
189 void permute (uint32_t n_rounds);
191 byte (
size_t state_index)
193#if __BYTE_ORDER == __LITTLE_ENDIAN
194 return bytes[(state_index / 8) * 8 + (state_index % 8)];
195#elif __BYTE_ORDER == __BIG_ENDIAN
196 return bytes[(state_index / 8) * 8 + (8 - 1 - (state_index % 8))];
198# error "Unknown __BYTE_ORDER"
213 template<
typename RandomAccessIterator>
void
214 generate (RandomAccessIterator begin, RandomAccessIterator end)
220 *begin++ =
Value (rbits);
221 if (
sizeof (
Value) <= 4 && begin != end)
222 *begin++ =
Value (rbits >> 32);
234 const uint16_t bit_rate_, n_rounds_;
236 Lib::KeccakF1600 state_;
243 inline size_t n_nums()
const {
return bit_rate_ / 64; }
249 KeccakRng (uint16_t hidden_state_capacity, uint16_t n_rounds) :
250 bit_rate_ (1600 - hidden_state_capacity), n_rounds_ (n_rounds), opos_ (
n_nums())
252 ASE_ASSERT_RETURN (hidden_state_capacity > 0 && hidden_state_capacity <= 1600 - 64);
257 void discard (
unsigned long long count);
258 void xor_seed (
const uint64_t *seeds,
size_t n_seeds);
260 void seed (uint64_t seed_value = 1) {
seed (&seed_value, 1); }
263 seed (
const uint64_t *seeds,
size_t n_seeds)
269 template<
class SeedSeq>
void
273 seed_sequence.generate (&u32[0], &u32[50]);
275 for (
size_t i = 0; i < 25; i++)
276 u64[i] = u32[i * 2] | (
uint64_t (u32[i * 2 + 1]) << 32);
288 return state_[opos_++];
293 template<
typename RandomAccessIterator>
void
294 generate (RandomAccessIterator begin, RandomAccessIterator end)
300 *begin++ =
Value (rbits);
301 if (
sizeof (
Value) <= 4 && begin != end)
302 *begin++ =
Value (rbits >> 32);
309 for (
size_t i = 0; i < 25; i++)
310 if (lhs.state_[i] != rhs.state_[i])
312 return lhs.opos_ == rhs.opos_ && lhs.bit_rate_ == rhs.bit_rate_;
318 return !(lhs == rhs);
333 template<
typename CharT,
typename Traits>
338 const typename IOS::fmtflags saved_flags = os.flags();
339 os.flags (IOS::dec | IOS::fixed | IOS::left);
340 const CharT space = os.widen (
' ');
341 const CharT saved_fill = os.fill();
344 for (
size_t i = 0; i < 25; i++)
345 os << space << self.state_[i];
346 os.flags (saved_flags);
347 os.fill (saved_fill);
351 template<
typename CharT,
typename Traits>
356 const typename IOS::fmtflags saved_flags = is.flags();
357 is.flags (IOS::dec | IOS::skipws);
360 for (
size_t i = 0; i < 25; i++)
361 is >> self.state_[i];
362 is.flags (saved_flags);
375 template<
class SeedSeq>
390 template<
class SeedSeq>
405 template<
class SeedSeq>
423 static constexpr const uint64_t A = 6364136223846793005ULL;
428 return (bits >> offset) | (bits << ((32 - offset) & 31));
435 return ror32 ((input ^ (input >> 18)) >> 27, input >> 59);
439 template<
class SeedSeq>
440 explicit Pcg32Rng (SeedSeq &seed_sequence) : increment_ (0), accu_ (0) {
seed (seed_sequence); }
442 explicit Pcg32Rng (uint64_t offset, uint64_t sequence);
448 void seed (uint64_t offset, uint64_t sequence);
450 template<
class SeedSeq>
void
454 seed_sequence.generate (&seeds[0], &seeds[2]);
455 seed (seeds[0], seeds[1]);
462 accu_ = A * accu_ + increment_;
463 return pcg_xsh_rr (lcgout);
474template<
class Num>
static inline constexpr uint64_t
475fnv1a_consthash64 (
const Num *ztdata)
477 static_assert (
sizeof (Num) <= 1,
"");
480 hash = 0x100000001b3 * (uint8_t (*ztdata++) ^ hash);
485template<
class Num>
static inline constexpr uint64_t
486fnv1a_consthash64 (
const Num *
const data,
size_t length)
488 static_assert (
sizeof (Num) <= 1,
"");
490 for (
size_t j = 0; j < length; j++)
491 hash = 0x100000001b3 * (uint8_t (data[j]) ^ hash);
505template<
class Num>
static ASE_CONST
inline uint32_t
506pcg_hash32 (
const Num *data,
size_t length, uint64_t seed)
508 static_assert (
sizeof (Num) <= 1,
"");
511 h ^= 0x14057b7ef767814fULL;
515 h *= 6364136223846793005ULL;
518 const size_t rsh = h >> 59;
519 const uint32_t xsh = (h ^ (h >> 18)) >> 27;
520 const uint32_t rot = (xsh >> rsh) | (xsh << (32 - rsh));
534template<
class Num>
static ASE_CONST
inline uint64_t
535pcg_hash64 (
const Num *data,
size_t length, uint64_t seed)
537 static_assert (
sizeof (Num) <= 1,
"");
540 h ^= 0x14057b7ef767814fULL;
544 h *= 6364136223846793005ULL;
547 const size_t rsh = h >> 59;
548 const uint64_t rxs = h ^ (h >> (5 + rsh));
549 const uint64_t m = rxs * 12605985483714917081ULL;
556pcg_hash64 (
const char *ztdata, uint64_t seed)
560 h ^= 0x14057b7ef767814fULL;
564 h *= 6364136223846793005ULL;
567 const size_t rsh = h >> 59;
568 const uint64_t rxs = h ^ (h >> (5 + rsh));
569 const uint64_t m = rxs * 12605985483714917081ULL;
586template<
class Num>
static ASE_CONST
inline uint64_t
587byte_hash64 (
const Num *data,
size_t length)
589 static_assert (
sizeof (Num) <= 1,
"");
590 return pcg_hash64 (data, length, hash_secret());
597 return pcg_hash64 (
string.
data(),
string.
size(), hash_secret());
602string_hash64 (
const char *ztdata)
604 return pcg_hash64 (ztdata, hash_secret());
AutoSeeder provides non-deterministic seeding entropy.
uint64 operator()() const
Generate non-deterministic 64bit random value.
void generate(RandomAccessIterator begin, RandomAccessIterator end)
Fill the range [begin, end) with random unsigned integer values.
static uint64 random()
Generate non-deterministic 64bit random value.
KeccakCryptoRng(SeedSeq &seed_sequence)
Initialize and seed the generator from seed_sequence.
KeccakCryptoRng()
Initialize and seed the generator from a system specific nondeterministic random source.
KeccakFastRng()
Initialize and seed the generator from a system specific nondeterministic random source.
KeccakFastRng(SeedSeq &seed_sequence)
Initialize and seed the generator from seed_sequence.
KeccakGoodRng(SeedSeq &seed_sequence)
Initialize and seed the generator from seed_sequence.
KeccakGoodRng()
Initialize and seed the generator from a system specific nondeterministic random source.
void seed(const uint64_t *seeds, size_t n_seeds)
Reinitialize the generator state using a nuber of 64 bit seeds.
uint64_t result_type
Integral type of the KeccakRng generator results.
KeccakRng(uint16_t hidden_state_capacity, uint16_t n_rounds)
Create an unseeded Keccak PRNG with specific capacity and number of rounds, for experts only.
void generate(RandomAccessIterator begin, RandomAccessIterator end)
Fill the range [begin, end) with random unsigned integer values.
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const KeccakRng &self)
Serialize generator state into an OStream.
result_type operator()()
Generate uniformly distributed 32 bit pseudo random number.
size_t bit_capacity() const
Amount of bits used to store hidden random number generator state.
void auto_seed()
Seed the generator from a system specific nondeterministic random source.
void discard(unsigned long long count)
void seed(uint64_t seed_value=1)
Reinitialize the generator state using a 64 bit seed_value.
friend bool operator!=(const KeccakRng &lhs, const KeccakRng &rhs)
Compare two generators for state inequality.
size_t n_nums() const
Amount of 64 bit random numbers per generated block.
result_type min() const
Minimum of the result type, for uint64_t that is 0.
void seed(SeedSeq &seed_sequence)
Seed the generator state from a seed_sequence.
void xor_seed(const uint64_t *seeds, size_t n_seeds)
friend bool operator==(const KeccakRng &lhs, const KeccakRng &rhs)
Compare two generators for state equality.
~KeccakRng()
The destructor resets the generator state to avoid leaving memory trails.
result_type max() const
Maximum of the result type, for uint64_t that is 18446744073709551615.
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, KeccakRng &self)
Deserialize generator state from an IStream.
Marsaglia multiply-with-carry generator, period ca 2^255.
Pcg32Rng(SeedSeq &seed_sequence)
Initialize and seed from seed_sequence.
void auto_seed()
Seed the generator from a system specific nondeterministic random source.
uint32_t random()
Generate uniformly distributed 32 bit pseudo random number.
Pcg32Rng()
Initialize and seed the generator from a system specific nondeterministic random source.
void seed(SeedSeq &seed_sequence)
Seed the generator state from a seed_sequence.
void seed(uint64_t offset, uint64_t sequence)
Seed by seeking to position offset within stream sequence.
#define ASE_ASSERT_RETURN(expr,...)
Return from the current function if expr evaluates to false and issue an assertion warning.
#define ASE_UNLIKELY(expr)
Compiler hint to optimize for expr evaluating to false.
#define ASE_ISLIKELY(expr)
Compiler hint to optimize for expr evaluating to true.
The Anklang C++ API namespace.
void sha3_224_hash(const void *data, size_t data_length, uint8_t hashvalue[28])
Calculate 224 bit SHA3 digest from data, see also class SHA3_224.
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
void shake256_hash(const void *data, size_t data_length, uint8_t *hashvalues, size_t n)
Calculate SHA3 extendable output digest for 256 bit security strength, see also class SHAKE256.
void sha3_384_hash(const void *data, size_t data_length, uint8_t hashvalue[48])
Calculate 384 bit SHA3 digest from data, see also class SHA3_384.
uint64_t cached_hash_secret
Use hash_secret() for access.
void sha3_256_hash(const void *data, size_t data_length, uint8_t hashvalue[32])
Calculate 256 bit SHA3 digest from data, see also class SHA3_256.
int64_t random_irange(int64_t begin, int64_t end)
void sha3_512_hash(const void *data, size_t data_length, uint8_t hashvalue[64])
Calculate 512 bit SHA3 digest from data, see also class SHA3_512.
uint64_t random_nonce()
Provide a unique 64 bit identifier that is not 0, see also random_int64().
void shake128_hash(const void *data, size_t data_length, uint8_t *hashvalues, size_t n)
Calculate SHA3 extendable output digest for 128 bit security strength, see also class SHAKE128.
double random_frange(double begin, double end)
void random_secret(uint64_t *secret_var)
Generate a secret non-zero nonce in secret_var, unless it has already been assigned.
SHA3_224()
Create context to calculate a 224 bit SHA3 hash digest.
void update(const uint8_t *data, size_t length)
Feed data to be hashed.
void digest(uint8_t hashvalue[28])
Retrieve the resulting hash value.
void reset()
Reset state to feed and retrieve a new hash value.
SHA3_256()
Create context to calculate a 256 bit SHA3 hash digest.
void update(const uint8_t *data, size_t length)
Feed data to be hashed.
void digest(uint8_t hashvalue[32])
Retrieve the resulting hash value.
void reset()
Reset state to feed and retrieve a new hash value.
void reset()
Reset state to feed and retrieve a new hash value.
SHA3_384()
Create context to calculate a 384 bit SHA3 hash digest.
void update(const uint8_t *data, size_t length)
Feed data to be hashed.
void digest(uint8_t hashvalue[48])
Retrieve the resulting hash value.
void digest(uint8_t hashvalue[64])
Retrieve the resulting hash value.
SHA3_512()
Create context to calculate a 512 bit SHA3 hash digest.
void update(const uint8_t *data, size_t length)
Feed data to be hashed.
void reset()
Reset state to feed and retrieve a new hash value.
SHAKE128()
Create context to calculate an unbounded SHAKE128 hash digest.
void update(const uint8_t *data, size_t length)
Feed data to be hashed.
void reset()
Reset state to feed and retrieve a new hash value.
void squeeze_digest(uint8_t *hashvalues, size_t n)
Retrieve an arbitrary number of hash value bytes.
void reset()
Reset state to feed and retrieve a new hash value.
SHAKE256()
Create context to calculate an unbounded SHAKE256 hash digest.
void update(const uint8_t *data, size_t length)
Feed data to be hashed.
void squeeze_digest(uint8_t *hashvalues, size_t n)
Retrieve an arbitrary number of hash value bytes.
Value type used to interface with various property types.