summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobert-hh <robert@hammelrath.com>2023-02-14 10:02:22 +0100
committerDamien George <damien@micropython.org>2023-02-21 23:17:44 +1100
commitb11026689724830fcfcb5060df2c5a17cb4dbc65 (patch)
tree9cd3a0cebe306251f2571db5a8bd6da1d59e3d72
parent4160ec087b265cfef320140e99449271a7757374 (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.h5
-rw-r--r--ports/samd/moduos.c20
-rw-r--r--ports/samd/samd_isr.c9
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) {