blob: c16dc7783210d550da5783bb154e834e0619f8c2 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COBALT_SRC_ALGORITHMS_RANDOM_RANDOM_H_
#define COBALT_SRC_ALGORITHMS_RANDOM_RANDOM_H_
#include <cstdint>
#include <random>
#include <type_traits>
namespace cobalt {
// A class template for an interface to a source of random instances of an
// unsigned integer type |T|. On Fuchsia this can be implemented by a class
// which draws from the Zircon CPRNG.
//
// Classes generated from this template satisfy the requirements of the
// UniformRandomBitGenerator C++ concept.
template <typename T>
class BitGeneratorInterface {
public:
static_assert(std::is_unsigned<T>::value,
"BitGeneratorInterface is only valid for unsigned integer types");
using result_type = T;
BitGeneratorInterface() = default;
virtual ~BitGeneratorInterface() = 0;
static constexpr result_type min() { return std::numeric_limits<result_type>::min(); }
static constexpr result_type max() { return std::numeric_limits<result_type>::max(); }
virtual result_type operator()() = 0;
};
template <typename T>
BitGeneratorInterface<T>::~BitGeneratorInterface() = default;
// A class template for a cryptographically secure RNG or PRNG.
template <typename T>
class SecureBitGeneratorInterface : public BitGeneratorInterface<T> {};
// An implementation of SecureBitGeneratorInterface.
//
// SecureRandomNumberGenerator maintains a buffer of random numbers obtained through boringssl's
// RAND_bytes function in order to reduce the frequency of system calls to get randomness.
class SecureRandomNumberGenerator : public SecureBitGeneratorInterface<uint32_t> {
public:
SecureRandomNumberGenerator();
result_type operator()() override;
};
// A placeholder implementation of BitGeneratorInterface.
class RandomNumberGenerator : public BitGeneratorInterface<uint32_t> {
public:
RandomNumberGenerator() { engine_ = std::mt19937(rd_()); };
explicit RandomNumberGenerator(uint32_t seed) { engine_ = std::mt19937(seed); };
result_type operator()() override { return static_cast<uint32_t>(engine_()); }
private:
std::random_device rd_;
std::mt19937 engine_;
};
// A fake random number generator that always returns |val|.
class FakeRandomNumberGenerator : public BitGeneratorInterface<uint32_t> {
public:
explicit FakeRandomNumberGenerator(uint32_t val) : val_(val) {}
result_type operator()() override { return val_; }
private:
uint32_t val_;
};
} // namespace cobalt
#endif // COBALT_SRC_ALGORITHMS_RANDOM_RANDOM_H_