#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "../../dilithium/ref/randombytes.h"
#include "../../dilithium/ref/api.h"
#include "../../dilithium/ref/fips202.h"
#include "../../dilithium/ref/params.h"
#include "libbitcoinpqc/ml_dsa.h"
static const uint8_t *g_random_data = NULL;
static size_t g_random_data_size = 0;
static size_t g_random_data_offset = 0;
void ml_dsa_init_random_source(const uint8_t *random_data, size_t random_data_size) {
g_random_data = random_data;
g_random_data_size = random_data_size;
g_random_data_offset = 0;
}
void ml_dsa_setup_custom_random() {
}
void ml_dsa_restore_original_random() {
g_random_data = NULL;
g_random_data_size = 0;
g_random_data_offset = 0;
}
void custom_randombytes_impl(uint8_t *out, size_t outlen) {
if (!out || outlen == 0) {
return;
}
if (g_random_data == NULL || g_random_data_size == 0) {
FILE *f = fopen("/dev/urandom", "r");
if (!f) {
memset(out, 0, outlen);
return;
}
size_t bytes_read = fread(out, 1, outlen, f);
fclose(f);
if (bytes_read < outlen) {
memset(out + bytes_read, 0, outlen - bytes_read);
}
return;
}
size_t total_copied = 0;
while (total_copied < outlen) {
size_t amount = outlen - total_copied;
if (amount > g_random_data_size - g_random_data_offset) {
amount = g_random_data_size - g_random_data_offset;
}
memcpy(out + total_copied, g_random_data + g_random_data_offset, amount);
total_copied += amount;
g_random_data_offset += amount;
if (g_random_data_offset >= g_random_data_size) {
g_random_data_offset = 0;
}
}
}
void ml_dsa_derandomize(uint8_t *seed, const uint8_t *m, size_t mlen, const uint8_t *sk) {
keccak_state state;
shake256_init(&state);
shake256_absorb(&state, sk, CRYPTO_SECRETKEYBYTES);
shake256_absorb(&state, m, mlen);
shake256_finalize(&state);
shake256_squeeze(seed, 64, &state);
}