samd/moduos: Add uos.urandom() using the phase-jitter rng.
This RNG passes many of the Diehard tests and also the AIS31 test suite. The RNG is quite slow, delivering 200bytes/s. Tested on boards with and without a crystal.
This commit is contained in:
parent
4160ec087b
commit
b110266897
|
@ -22,8 +22,8 @@
|
|||
#define MICROPY_PY_CMATH (0)
|
||||
#endif
|
||||
|
||||
#define MICROPY_PY_URANDOM_SEED_INIT_FUNC (trng_random_u32())
|
||||
unsigned long trng_random_u32(void);
|
||||
#define MICROPY_PY_URANDOM_SEED_INIT_FUNC (trng_random_u32(300))
|
||||
unsigned long trng_random_u32(int delay);
|
||||
|
||||
#define VFS_BLOCK_SIZE_BYTES (1536) // 24x 64B flash pages;
|
||||
|
||||
|
@ -36,6 +36,7 @@ unsigned long trng_random_u32(void);
|
|||
#define MICROPY_PY_MACHINE_RTC (1)
|
||||
#endif
|
||||
#endif
|
||||
#define MICROPY_PY_UOS_URANDOM (1)
|
||||
|
||||
#ifndef MICROPY_PY_MACHINE_PIN_BOARD_CPU
|
||||
#define MICROPY_PY_MACHINE_PIN_BOARD_CPU (1)
|
||||
|
|
|
@ -52,6 +52,23 @@ uint32_t trng_random_u32(void) {
|
|||
return REG_TRNG_DATA;
|
||||
}
|
||||
|
||||
#define TRNG_RANDOM_U32 trng_random_u32()
|
||||
#endif // defined(MCU_SAMD51)
|
||||
|
||||
#if defined(MCU_SAMD21)
|
||||
extern volatile uint32_t rng_state;
|
||||
|
||||
uint32_t trng_random_u32(int delay) {
|
||||
mp_hal_delay_ms(delay); // wait a few cycles
|
||||
uint32_t upper = rng_state;
|
||||
mp_hal_delay_ms(delay); // wait again a few cycles
|
||||
return (upper & 0xffff0000) | (rng_state >> 16);
|
||||
}
|
||||
|
||||
#define trng_start()
|
||||
#define TRNG_RANDOM_U32 trng_random_u32(10)
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_UOS_URANDOM
|
||||
STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) {
|
||||
mp_int_t n = mp_obj_get_int(num);
|
||||
|
@ -62,7 +79,7 @@ STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) {
|
|||
trng_start();
|
||||
for (int i = 0; i < n; i++) {
|
||||
if ((i % 4) == 0) {
|
||||
rngval = trng_random_u32();
|
||||
rngval = TRNG_RANDOM_U32;
|
||||
}
|
||||
vstr.buf[i] = rngval & 0xff;
|
||||
rngval >>= 8;
|
||||
|
@ -72,7 +89,6 @@ STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) {
|
|||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom);
|
||||
|
||||
#endif // MICROPY_PY_UOS_URANDOM
|
||||
#endif // defined(MCU_SAMD51)
|
||||
|
||||
#if MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM
|
||||
bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream) {
|
||||
|
|
|
@ -96,7 +96,7 @@ void Default_Handler(void) {
|
|||
void SysTick_Handler(void) {
|
||||
#if defined(MCU_SAMD21)
|
||||
// Use the phase jitter between the clocks to get some entropy
|
||||
// and accumulate the random number register.
|
||||
// and accumulate the random number register with a "spiced" LCG.
|
||||
rng_state = (rng_state * 32310901 + 1) ^ (REG_TC4_COUNT32_COUNT >> 1);
|
||||
#endif
|
||||
|
||||
|
@ -108,13 +108,6 @@ void SysTick_Handler(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(MCU_SAMD21)
|
||||
uint32_t trng_random_u32(void) {
|
||||
mp_hal_delay_ms(320); // wait for ten cycles of the rng_seed register
|
||||
return rng_state;
|
||||
}
|
||||
#endif
|
||||
|
||||
void us_timer_IRQ(void) {
|
||||
#if defined(MCU_SAMD21)
|
||||
if (TC4->COUNT32.INTFLAG.reg & TC_INTFLAG_OVF) {
|
||||
|
|
Loading…
Reference in New Issue