summaryrefslogtreecommitdiff
path: root/test/rng_benchmark.cc
blob: 10716f863d916fec3e9935dbcee58ef1963634bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/* Copyright 2022 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Measure performance of the hardware True Random Number Generator (TRNG)
 * compared to the std::rand().
 */

#include "benchmark.h"
#include "console.h"

#include <array>
#include <cstdint>
#include <cstdlib>

extern "C" {
#include "test_util.h"
#include "trng.h"
}

test_static int test_rng()
{
	constexpr int num_iterations = 100;
	Benchmark benchmark({ .num_iterations = num_iterations });
	std::array<uint32_t, num_iterations> trng_out;
	std::array<int, num_iterations> rand_out;

	// Try the hardware true random number generator
	trng_out.fill(0);

	trng_init();
	auto result = benchmark.run("trng", [&trng_out]() {
		static int i = 0;
		trng_rand_bytes(&trng_out[i++], sizeof(uint32_t));
	});
	trng_exit();

	TEST_ASSERT(result.has_value());
	for (int i = 0; i < trng_out.size() - 1; ++i) {
		TEST_NE(trng_out[i], trng_out[i + 1], "%d");
		cflush();
	}

	// Repeat the test by turning the TNRG on and off at each iteration
	trng_out.fill(0);
	result = benchmark.run("trng_on_off", [&trng_out]() {
		trng_init();
		static int i = 0;
		trng_rand_bytes(&trng_out[i++], sizeof(uint32_t));
		trng_exit();
	});

	TEST_ASSERT(result.has_value());
	for (int i = 0; i < trng_out.size() - 1; ++i) {
		TEST_NE(trng_out[i], trng_out[i + 1], "%d");
		cflush();
	}

	// Repeat the test using std::rand() for comparison
	rand_out.fill(0);
	result = benchmark.run("std::rand", [&rand_out]() {
		static int i = 0;
		rand_out[i++] = std::rand();
	});

	TEST_ASSERT(result.has_value());
	for (int i = 0; i < rand_out.size() - 1; ++i) {
		TEST_NE(rand_out[i], rand_out[i + 1], "%d");
		cflush();
	}

	benchmark.print_results();
	return EC_SUCCESS;
}

void run_test(int argc, const char **argv)
{
	test_reset();
	RUN_TEST(test_rng);
	test_print_result();
}