Генератор случайных чисел на SM32F4. TRNG.

Аппаратный генератор случайных чисел (генератор истинно случайных чисел) — устройство, которое генерирует последовательность случайных чисел на основе измеряемых параметров протекающего физического процесса. Работа таких устройств часто основана на использовании надёжных источников энтропии, таких как тепловой шум, фотоэлектрический эффект, квантовые явления и т.д. Эти процессы в теории абсолютно непредсказуемы, на практике же получаемые из них случайные числа проверяются с помощью специальных статистических тестов .

Истинный генератор случайных чисел STM32F4.

Истинный генератор случайных чисел реализован на F4 серии, как аналоговый источник тока. Этот источник тока
генерирует непрерывный аналоговый шум, который охвачен обратной связью. Регистр сдвига (LFSR) используют
для получения 32-битное случайного числа.
Аналоговый источник состоит из нескольких кольцевых генераторов, выходы которых используют операцию XOR.
LFSR тактируется частотой (PLL48CLK), так что качество случайного числа не зависит от частоты HCLK.
Содержание LFSR передается в регистр данных (RNG_DR).

Алгоритм использования TRNG:
1. Запускаем STM32CubeMX.
2. Выбираем отладочную плату stm32f429i-disco.
3. Добавляем rng в нашу программу.
4. Для rng можно использовать функцию глобальное прерывания.
5. Генерируем проект для отладочной платы stm32f429i-disco, я чаще всего использую MDK Keil, поэтому генерирую проект для Keil.

Прототипы функций для работы с TRNG:

/* Функции инициализации и деинициализации  **********************************/
HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng);
HAL_StatusTypeDef HAL_RNG_DeInit (RNG_HandleTypeDef *hrng);
void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng);
void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng);

/* Функции управления периферией   ************************************************/
uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng);
uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng);
void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng);
void HAL_RNG_ReadyCallback(RNG_HandleTypeDef* hrng);
void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng);

/* Функция статуса периферии  **************************************************/
HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng);

Функцию которую мы будем использовать называется HAL_RNG_GetRandomNumber, все очень легко, передаем укзатель на структуру RNG_HandleTypeDef, а функция нам возвращает истинное случайное число в формате uint32_t.

Основная часть исходного кода программы:

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include <stdint.h>

/* Private variables ---------------------------------------------------------*/
RNG_HandleTypeDef hrng;

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_RNG_Init(void);

int main(void)
{
	volatile uint32_t trng;
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* System interrupt init*/
  /* Sets the priority grouping field */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_RNG_Init();

  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* USER CODE BEGIN 3 */
  /* Infinite loop */
  while (1)
  {
		trng = HAL_RNG_GetRandomNumber(&hrng);

  }
  /* USER CODE END 3 */

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  __PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
                              |RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);

}

/* RNG init function */
void MX_RNG_Init(void)
{

  hrng.Instance = RNG;
  HAL_RNG_Init(&hrng);

}

Аппаратные генераторы случайных чисел главным образом применяются для проведения статистических испытаний и в криптографии, где они используются для создания криптографических ключей для зашифрованной передачи данных. Также такие аппараты широко используются в интернет-казино для имитации, например, рулетки. Но из-за сложности реализации и относительной медленности использование подобных генераторов зависит от потребностей конкретной предметной области и от устройства самого генератора.

trng.7z