Skip to content

Commit

Permalink
Add base/random module for random utilities.
Browse files Browse the repository at this point in the history
  • Loading branch information
john-preston committed Sep 15, 2021
1 parent 50d2d31 commit e8adbd1
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 24 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ PRIVATE
base/qthelp_url.h
base/qt_connection.h
base/qt_signal_producer.h
base/random.cpp
base/random.h
base/required.h
base/runtime_composer.cpp
base/runtime_composer.h
Expand Down
3 changes: 2 additions & 1 deletion base/base_pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@
#include "base/flat_map.h"
#include "base/flat_set.h"
#include "base/optional.h"
#include "base/openssl_help.h"
#include "base/algorithm.h"
#include "base/basic_types.h"
6 changes: 2 additions & 4 deletions base/bytes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
//
#include "base/bytes.h"

#include "base/openssl_help.h"
#include "base/random.h"

namespace bytes {

void set_random(span destination) {
if (!destination.empty()) {
RAND_bytes(
reinterpret_cast<unsigned char*>(destination.data()),
destination.size());
base::RandomFill(destination.data(), destination.size());
}
}

Expand Down
2 changes: 1 addition & 1 deletion base/call_delayed.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace base {

void call_delayed(crl::time delay, FnMut<void()> &&callable);
void call_delayed(crl::time delay, FnMut<void()> &&callable);

template <
typename Guard,
Expand Down
18 changes: 0 additions & 18 deletions base/openssl_help.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
extern "C" {
#include <openssl/bn.h>
#include <openssl/sha.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
#include <openssl/modes.h>
#include <openssl/crypto.h>
Expand Down Expand Up @@ -546,23 +545,6 @@ template <
args...);
}

inline void AddRandomSeed(bytes::const_span data) {
RAND_seed(data.data(), data.size());
}

template <
typename T,
typename = std::enable_if_t<std::is_trivially_copyable_v<T>>>
[[nodiscard]] inline T RandomValue() {
unsigned char buffer[sizeof(T)];
if (!RAND_bytes(buffer, sizeof(T))) {
Unexpected("Could not generate random bytes!");
}
auto result = T();
memcpy(&result, buffer, sizeof(T));
return result;
}

inline bytes::vector Pbkdf2Sha512(
bytes::const_span password,
bytes::const_span salt,
Expand Down
42 changes: 42 additions & 0 deletions base/random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// This file is part of Desktop App Toolkit,
// a set of libraries for developing nice desktop applications.
//
// For license and copyright information please follow this link:
// https://github.com/desktop-app/legal/blob/master/LEGAL
//
#include "base/random.h"

extern "C" {
#include <openssl/rand.h>
} // extern "C"

namespace base {

void RandomFill(bytes::span bytes) {
const auto result = RAND_bytes(
reinterpret_cast<unsigned char*>(bytes.data()),
bytes.size());

Ensures(result);
}

int RandomIndex(int count) {
Expects(count > 0);

if (count == 1) {
return 0;
}
const auto max = (std::numeric_limits<uint32>::max() / count) * count;
while (true) {
const auto random = RandomValue<uint32>();
if (random < max) {
return int(random % count);
}
}
}

void RandomAddSeed(bytes::const_span bytes) {
RAND_seed(bytes.data(), bytes.size());
}

} // namespace base
35 changes: 35 additions & 0 deletions base/random.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// This file is part of Desktop App Toolkit,
// a set of libraries for developing nice desktop applications.
//
// For license and copyright information please follow this link:
// https://github.com/desktop-app/legal/blob/master/LEGAL
//
#pragma once

#include <cstddef>
#include <type_traits>

#include "base/bytes.h"

namespace base {

void RandomFill(bytes::span bytes);

inline void RandomFill(void *data, std::size_t length) {
RandomFill({ static_cast<bytes::type*>(data), length });
}

template <
typename T,
typename = std::enable_if_t<std::is_trivially_copyable_v<T>>>
[[nodiscard]] inline T RandomValue() {
auto result = T();
RandomFill({ reinterpret_cast<std::byte*>(&result), sizeof(T) });
return result;
}

[[nodiscard]] int RandomIndex(int count);

void RandomAddSeed(bytes::const_span bytes);

} // namespace base

0 comments on commit e8adbd1

Please sign in to comment.