Skip to content

Commit

Permalink
add Doxygen comments to randapi.hpp
Browse files Browse the repository at this point in the history
Document classes RandomAPI, StrongRandomAPI and WeakRandomAPI

Signed-off-by: Heiko Hund <heiko@openvpn.net>
  • Loading branch information
d12fk authored and dsommers committed Nov 29, 2023
1 parent deaced4 commit c5d37c4
Showing 1 changed file with 116 additions and 22 deletions.
138 changes: 116 additions & 22 deletions openvpn/random/randapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.

// API for random number implementations.
/**
* @file randapi.cpp
* @brief Implementation of the base classes for random number generators
*/

#pragma once

Expand All @@ -34,29 +37,60 @@

namespace openvpn {

/**
* @class RandomAPI
* @brief Abstract base class for random number generators
*
* This class cannot be inherited from directly, use \ref StrongRandomAPI
* or \ref WeakRandomAPI to implement random number generators.
*/
class RandomAPI : public RC<thread_unsafe_refcount>
{
public:
/**
* @typedef RCPtr<RandomAPI> Ptr
* @brief Smart pointer type for managing the ownership of RandomAPI objects
*/
typedef RCPtr<RandomAPI> Ptr;

// Random algorithm name
/**
* @brief Get the name of the random number generation algorithm
* @return The name of the algorithm
*/
virtual std::string name() const = 0;

// Fill buffer with random bytes
/**
* @brief Fill a buffer with random bytes
* @param buf Pointer to the buffer
* @param size Number of bytes to generate
*/
virtual void rand_bytes(unsigned char *buf, size_t size) = 0;

// Like rand_bytes, but don't throw exception.
// Return true on successs, false on fail.
/**
* @brief Fill a buffer with random bytes without throwing exceptions
* @param buf Pointer to the buffer
* @param size Number of bytes to generate
* @return true on success
* @return false on failure
*/
virtual bool rand_bytes_noexcept(unsigned char *buf, size_t size) = 0;

// Fill a data object with random bits
/**
* @brief Fill a data object with random bytes
* @tparam T Type of the object
* @param obj Reference to the object to be filled
*/
template <typename T>
void rand_fill(T &obj)
{
rand_bytes(reinterpret_cast<unsigned char *>(&obj), sizeof(T));
}

// Return a data object with random bits
/**
* @brief Create a data object filled with random bytes
* @tparam T Type of the object
* @return The generated object
*/
template <typename T>
T rand_get()
{
Expand All @@ -65,7 +99,11 @@ class RandomAPI : public RC<thread_unsafe_refcount>
return ret;
}

// Return a data object with random bits, always >= 0 for signed types
/**
* @brief Create a data object filled with random bytes, always >= 0 for signed types
* @tparam T Type of the object
* @return The generated data object
*/
template <typename T>
T rand_get_positive()
{
Expand All @@ -75,19 +113,28 @@ class RandomAPI : public RC<thread_unsafe_refcount>
// maps (T:min, -1) to (0, T:max) which is fine for random generation
ret &= std::numeric_limits<T>::max();
}

return ret;
}

// Return a uniformly distributed random number in the range [0, end).
// end must be > 0.
/**
* @brief Return a uniformly distributed random number in the range [0, end)
* @tparam T Type of the object
* @param end The upper bound (exclusive)
* @return The generated random number
*/
template <typename T>
T randrange(const T end)
{
return rand_get_positive<T>() % end;
}

// Return a uniformly distributed random number in the range [start, end].
/**
* @brief Return a uniformly distributed random number in the range [start, end]
* @tparam T Type of the object
* @param start The lower bound
* @param end The upper bound
* @return The generated random number
*/
template <typename T>
T randrange(const T start, const T end)
{
Expand All @@ -97,20 +144,31 @@ class RandomAPI : public RC<thread_unsafe_refcount>
return start + rand_get_positive<T>() % (end - start + 1);
}

// Return a uniformly distributed random number in the range [0, end).
// If end==0 or end==1, will always return 0.
// This version is strictly 32-bit only and optimizes by avoiding
// integer division.
/**
* @brief Return a uniformly distributed random number in the range [0, end)
* @param end The upper bound (exclusive)
* @return The generated random number
*
* If end==0 or end==1, will always return 0.
* This version is strictly 32-bit only and optimizes by avoiding
* integer division.
*/
std::uint32_t randrange32(const std::uint32_t end)
{
std::uint32_t r;
rand_fill(r);
return rand32_distribute(r, end);
}

// Return a uniformly distributed random number in the range [start, end].
// This version is strictly 32-bit only and optimizes by avoiding
// integer division.
/**
* @brief Return a uniformly distributed random number in the range [start, end]
* @param start The lower bound
* @param end The upper bound
* @return The generated random number
*
* This version is strictly 32-bit only and optimizes by avoiding
* integer division.
*/
std::uint32_t randrange32(const std::uint32_t start, const std::uint32_t end)
{
if (start >= end)
Expand All @@ -119,21 +177,34 @@ class RandomAPI : public RC<thread_unsafe_refcount>
return start + randrange32(end - start + 1);
}

// Return a random byte
/**
* @brief Return a random byte
* @return The generated random byte
*/
std::uint8_t randbyte()
{
std::uint8_t byte;
rand_fill(byte);
return byte;
}

// Return a random boolean
/**
* @brief Return a random boolean
* @return The generated random boolean
*/
bool randbool()
{
return bool(randbyte() & 1);
}

// UniformRandomBitGenerator for std::shuffle
/**
* @name UniformRandomBitGenerator members
*
* These members implement the C++11 UniformRandomBitGenerator requirements
* so that RandomAPI instances can be used with std::shuffle (and others).
* See https://en.cppreference.com/w/cpp/named_req/UniformRandomBitGenerator
*/
///@{
typedef unsigned int result_type;
static constexpr result_type min()
{
Expand All @@ -147,22 +218,45 @@ class RandomAPI : public RC<thread_unsafe_refcount>
{
return rand_get<result_type>();
}
///@}

private:
friend class StrongRandomAPI;
friend class WeakRandomAPI;
RandomAPI() = default;
};

/**
* @class StrongRandomAPI
* @brief Abstract base class for cryptographically strong random number generators
*
* Inherit from this class if your random number generator produces cryptographically
* strong random numbers.
*/
class StrongRandomAPI : public RandomAPI
{
public:
/**
* @typedef RCPtr<StrongRandomAPI> Ptr
* @brief Smart pointer type for managing the ownership of StrongRandomAPI objects
*/
typedef RCPtr<StrongRandomAPI> Ptr;
};

/**
* @class WeakRandomAPI
* @brief Abstract base class for pseudo random number generators
*
* Inherit from this class if your random number generator produces pseudo random numbers
* which are deterministic and should not be used for operations requiring true randomness.
*/
class WeakRandomAPI : public RandomAPI
{
public:
/**
* @typedef RCPtr<WeakRandomAPI> Ptr
* @brief Smart pointer type for managing the ownership of WeakRandomAPI objects
*/
typedef RCPtr<WeakRandomAPI> Ptr;
};

Expand Down

0 comments on commit c5d37c4

Please sign in to comment.