1 /*
2 * Copyright (c) 2026, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <stdbool.h>
9 #include <string.h>
10
11 #include "sfcp_random.h"
12
13 struct xorshift_plus_128_state_t {
14 uint64_t state[2];
15 };
16
lfsr_seed(struct xorshift_plus_128_state_t * lfsr,uint8_t * seed,size_t seed_len)17 static inline void lfsr_seed(struct xorshift_plus_128_state_t *lfsr,
18 uint8_t *seed, size_t seed_len)
19 {
20 if (seed_len < sizeof(lfsr->state)) {
21 memcpy(lfsr->state, seed, seed_len);
22 } else {
23 memcpy(lfsr->state, seed, sizeof(lfsr->state));
24 }
25 }
26
27 /* See https://en.wikipedia.org/wiki/Xorshift#xorshift+ */
xorshift_plus_128_lfsr(struct xorshift_plus_128_state_t * lfsr,uint8_t * seed,size_t seed_len)28 static uint64_t xorshift_plus_128_lfsr(struct xorshift_plus_128_state_t *lfsr,
29 uint8_t *seed, size_t seed_len)
30 {
31 uint64_t temp0, temp1;
32
33 lfsr_seed(lfsr, seed, seed_len);
34
35 temp0 = lfsr->state[0];
36 temp1 = lfsr->state[1];
37 lfsr->state[0] = lfsr->state[1];
38
39 temp0 ^= temp0 << 23;
40 temp0 ^= temp0 >> 18;
41 temp0 ^= temp1 ^ (temp1 >> 5);
42
43 lfsr->state[1] = temp0;
44
45 return temp0 + temp1;
46 }
47
sfcp_random_generate_random_lfsr(uint8_t * seed,size_t seed_len)48 uint64_t sfcp_random_generate_random_lfsr(uint8_t *seed, size_t seed_len)
49 {
50 struct xorshift_plus_128_state_t lfsr = { 0 };
51
52 return xorshift_plus_128_lfsr(&lfsr, seed, seed_len);
53 }
54