Software APIs
random_order.h
Go to the documentation of this file.
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_RANDOM_ORDER_H_
6#define OPENTITAN_SW_DEVICE_LIB_BASE_RANDOM_ORDER_H_
7
8#include <stddef.h>
9#include <stdint.h>
10
12
13#ifdef __cplusplus
14extern "C" {
15#endif // __cplusplus
16
17/**
18 * @file
19 * @brief Functions for generating random traversal orders.
20 */
21
22/**
23 * Expects some external implementation of randomness to be linked.
24 *
25 * @return A fresh random word.
26 */
27extern uint32_t random_order_random_word(void);
28
29/**
30 * Context for a random traversal order.
31 *
32 * A "random traversal order" specifies a random order to walk through some
33 * buffer of length `n`, which is an important building block for
34 * constant-power code. Given `n`, the random order emits integers in the
35 * range `0..m`, where `m` is an implementation-defined, per-random-order
36 * value greater than `n`. The order is guaranteed to visit each integer in
37 * `0..n` at least once, but with some caveats:
38 * - Values greater than `n` may be returned.
39 * - The same value may be returned multiple times.
40 *
41 * Users must be mindful of these constraints when using `random_order_t`.
42 * These caveats are intended to allow for implementation flexibility, such as
43 * intentionally adding decoys to the sequence.
44 */
45typedef struct random_order {
46 /**
47 * Next index to return.
48 */
49 size_t state;
50 /**
51 * Step size.
52 */
53 size_t step;
54 /**
55 * Maximum index to return (exclusive).
56 */
57 size_t max;
58 /**
59 * Total number of iterations so far.
60 */
61 size_t ctr;
63
64/**
65 * Hardened check that a random_order iteration is complete.
66 *
67 * @param ctx The context to check.
68 */
69#define RANDOM_ORDER_HARDENED_CHECK_DONE(ctx_) \
70 HARDENED_CHECK_EQ(ctx_.max, ctx_.ctr)
71
72/**
73 * Constructs a new, randomly-seeded traversal order,
74 * running from `0` to at least `min_len`.
75 *
76 * This function does not take a seed as input; instead, the seed is
77 * extracted, in some manner or another, from the hardware by this function.
78 *
79 * The EDN must be initialized before calling this function, since it uses the
80 * Ibex RND interface and will wait until entropy is available.
81 *
82 * @param rnd Function to call for fresh randomness.
83 * @param ctx The context to initialize.
84 * @param min_len The minimum length this traversal order must visit.
85 */
86void random_order_init(random_order_t *ctx, size_t min_len);
87
88/**
89 * Returns the length of the sequence represented by `ctx`.
90 *
91 * This value may be greater than `min_len` specified in
92 * `random_order_init()`, but the sequence is guaranteed to contain every
93 * integer in `0..min_len`.
94 *
95 * This value represents the number of times `random_order_advance()` may be
96 * called.
97 *
98 * @param ctx The context to query.
99 * @return The length of the sequence.
100 */
101size_t random_order_len(const random_order_t *ctx);
102
103/**
104 * Returns the next element in the sequence represented by `ctx`.
105 *
106 * See `random_order_len()` for discovering how many times this function can
107 * be called.
108 *
109 * @param ctx The context to advance.
110 * @return The next value in the sequence.
111 */
113
114#ifdef __cplusplus
115} // extern "C"
116#endif // __cplusplus
117
118#endif // OPENTITAN_SW_DEVICE_LIB_BASE_RANDOM_ORDER_H_