diff options
| author | robert-hh <robert@hammelrath.com> | 2023-02-14 10:02:22 +0100 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2023-02-21 23:17:44 +1100 |
| commit | b11026689724830fcfcb5060df2c5a17cb4dbc65 (patch) | |
| tree | 9cd3a0cebe306251f2571db5a8bd6da1d59e3d72 | |
| parent | 4160ec087b265cfef320140e99449271a7757374 (diff) | |
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.
| -rw-r--r-- | ports/samd/mcu/samd21/mpconfigmcu.h | 5 | ||||
| -rw-r--r-- | ports/samd/moduos.c | 20 | ||||
| -rw-r--r-- | ports/samd/samd_isr.c | 9 |
3 files changed, 22 insertions, 12 deletions
diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index 150a378a3..db4e58753 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -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) diff --git a/ports/samd/moduos.c b/ports/samd/moduos.c index e0237fd88..3404919d2 100644 --- a/ports/samd/moduos.c +++ b/ports/samd/moduos.c @@ -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) { diff --git a/ports/samd/samd_isr.c b/ports/samd/samd_isr.c index 838800bdb..a12140313 100644 --- a/ports/samd/samd_isr.c +++ b/ports/samd/samd_isr.c @@ -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) { |
