Generatore di numeri casuali AVR


12

Ho letto un appnote di TI ( slaa338 ) che descrive una tecnica per generare numeri casuali "reali" (anziché "pseudo"). Sfrutta il sottosistema di clock in qualche modo esotico dell'MSP430 per raggiungere questo obiettivo. Qualcuno sa di una tecnica che può essere implementata su un AVR (in particolare mi interessano gli XMega) per generare numeri casuali "reali"?


1
psuedo random funziona per i giochi di dadi. Penso che voglia crittograficamente sicuro.
Kortuk,

2
Puoi dare un suggerimento sull'applicazione e / o sul grado di casualità richiesto? Se è per la crittografia, ci sono ulteriori considerazioni oltre alla qualità del seme. Alcuni dei suggerimenti già formulati, come il campionamento di input ambientali di vario tipo, possono o meno essere appropriati in base alle tue esigenze.
Windell Oskay,

Risposte:


6

Quanto male usi XMega? Se la generazione di numeri crittografici e casuali è una parte importante del tuo progetto, la serie SecureAVR di Atmel ha un numero casuale hardware incorporato ed è progettata per applicazioni crittografiche.

Indipendentemente da ciò, dubito che troverai una fonte di seme casuale che abbia una buona distribuzione. Avrai bisogno di eseguirlo un generatore di numeri pseudo casuali alcune volte Finché inizi con un seme diverso ogni volta, questo ti darà un bel set di numeri casuali. Un LGC è un generatore pseudo casuale semplice e veloce:

static unsigned long Seed; 

/* Call before first use of NextVal */
unsigned long InitSeed()
{
   //Your code for random seed here

   // Correct distribution errors in seed
   NextVal();
   NextVal();
   NextVal();
   return NextVal();
}

 /* Linear Congruential Generator 
  * Constants from  
  * "Numerical Recipes in C" 
  * by way of 
   * <http://en.wikipedia.org/wiki/Linear_congruential_generator#LCGs_in_common_use>
   * Note: Secure implementations may want to get uncommon/new LCG values
  */
unsigned long NextVal()
{
  Seed=Seed*1664525L+1013904223L;
  return Seed;
} 

1
È fantastico, non mi ero reso conto che esistesse la linea SecureAVR, grazie per il puntatore!
vicatcu,

A proposito: se hai davvero bisogno di sicurezza, il metodo LCG semplice, efficace e veloce che ho presentato non è quello che vuoi: molti LCG possono essere rotti; ottieni 2-3 valori di fila e collegali a un generatore LCG con una serie di costanti conosciute - questo includerebbe tutto sulla pagina di Wikipedia. Un modello di corrispondenza consentirà all'attaccante di prevedere quale sarà il prossimo numero. È anche possibile (ma più difficile) capire quali sono le costanti dal nulla.
Kevin Vermeer,

1
@reemrevnivek FYI, Atmel sta vendendo la sua linea SecureAVR ... raccomandano i loro processori a 32 bit basati su ARM se si desidera roba crittografica che è un gioco di ruolo completamente diverso in termini di ambiente di sviluppo da AVR. Hanno una coppia con True RNG su di loro, forse un giorno giocherò con loro.
vicatcu,

7

Collegare l'ADC a una sorgente di rumore hardware e utilizzare il software per "sbiancare" i numeri casuali, se necessario.

Ecco un progetto basato su AVR che fa questo: Mini Portable Random Number Generator (mPRNG) di Leon

A seconda della sicurezza crittografica necessaria, è possibile utilizzare il rumore di un ingresso analogico collegato a terra o il " sensore di temperatura interno " come seme di casualità anziché hardware esterno.

Aggiornamento : in seguito ho scritto un programma per Arduino che utilizza i timer del chip come fonte di entropia (l'ADC si è rivelato inutile perché i bit rumorosi vengono troncati) e questo ha ispirato la creazione della libreria Entropy .

In entrambi i casi, la casualità non proviene, ad esempio, dal valore della temperatura stessa, che cambia solo lentamente, ma dai bit meno significativi , che variano casualmente da una lettura all'altra. Ho letto il valore più volte, una volta per ogni bit di output, bitshifting e XORing con la lettura precedente. XORing di un bit veramente casuale con un bit non correlato preserva la casualità , quindi la casualità si diffonde su tutti i bit e diventa un vero rumore bianco. Tuttavia, la velocità in bit non sarà molto elevata, poiché si ottiene solo un bit di output per tempo di acquisizione o ciclo del timer. Con il metodo timer, stavo ottenendo circa 64 bit / s.


5
Chiamare un RNG (più o meno vero), "-PRNG" è sfortunato.
Nick T,

+1 per ADC, penso che probabilmente stai cercando qualcosa che cambi ad una frequenza superiore rispetto a un sensore di temperatura.
Polpo,

1
@Octopus Beh, non stai usando la temperatura come fonte di entropia, stai usando i bit meno significativi e rumorosi, che cambieranno casualmente ogni volta che leggi l'ADC anche se la temperatura è costante. Quando ho provato su Arduino, tuttavia, questi bit erano sempre 0, quindi non era fattibile e ho dovuto usare invece la variazione del timer. Su un altro MCU su cui ho usato quel metodo, gli LSB dell'ADC erano rumorosi e utilizzabili.
endolith il

3

Un altro trucco per generare un seme casuale, è contare il numero di cicli di clock fino a quando un evento esterno. Ad esempio, se si tratta di un dispositivo che può essere utilizzato da una persona, contare il numero di cicli di clock fino a quando non preme il pulsante "Vai" e utilizzarlo come seme casuale.


4
Questo potrebbe non essere molto sicuro contro gli attacchi dei canali laterali in quanto possono penetrare assicurando il controllo di un dispositivo, ma come per tutta la crittografia, l'applicazione determina la fattibilità.
Kortuk,

3

Per essere sicuro di non riavviare con la stessa sequenza, utilizzo somme byte nell'eeprom:

#include <avr/eeprom.h>
#include <stdlib.h> // rand

u16  EEMEM randinit; 

int main(void) {
        srand(eeprom_read_word(&randinit));
        eeprom_write_word(&randinit,rand());
        [...]
 }

Questo dà abbastanza casuale e non costa molto in programma / memoria.


2
Questo legge byte 0 ogni volta. Quali prove hai che questo byte è casuale? Se lo è, questa è un'ottima tecnica!
Kevin Vermeer,

Questa parola (byte 0 e 1 in effetti) sarà casuale, perché ad ogni avvio inizializzo il generatore casuale con il suo contenuto. ALLORA lo carico con un nuovo rand (). Quindi il prossimo init sembrerà casuale da quello attuale ... e così via ... Ma se reimposto randinit su ffff (o 0000?), Avrò la stessa sequenza randinit! Quindi non è perfetto. Ho dimenticato un avvertimento sulla miccia che cancella l'eeprom durante il caricamento di * .hex;)
jojo l'abricot


2

Hai mai usato qualcosa come randomSeed () ? - utilizzato nell'IDE di Arduino

È possibile utilizzare questa funzione per campionare un pin analogico mobile (libero) sull'AVR atmel, quindi utilizza il valore per creare un punto di partenza arbitrario per la funzione di numero pseudo casuale - random ().

Il valore creato da random () può essere un numero pseudo casuale - ma il punto di partenza arbitrario creato da randomSeed () dovrebbe essere un numero / valore casuale il più reale possibile.


2
Campionare cose come i pin analogici è quasi casuale, ma non avrà una distribuzione uniforme. Esegui il seme in modo casuale un paio di volte, tuttavia, e lo farà.
Kevin Vermeer,

.... attraverso un pseudo generatore di numeri casuali una coppia ... <- Come è andata persa? NTS: coinvolgi prima il cervello, poi le dita.
Kevin Vermeer,

Esatto - Non è anche il più sicuro se lo si utilizza per crittografia / protezione ecc., Ma ti darà un bel numero casuale per qualcosa come musica generativa o giochi di dadi. È buono e facile da implementare anche :)
Jim

1

C'è un documento su come raggiungere questo obiettivo con l'hardware AVR. Si tratta di fare affidamento sul jitter dell'orologio. Fondamentalmente, si utilizza un interrupt del timer basato su una sorgente di clock per campionare i bit inferiori di un timer separato che è sincronizzato su una sorgente di clock indipendente separata. I due orologi avranno alcuni jitter casuali associati e il campionamento non sarà perfettamente periodico.

Ho fatto una piccola prova del concetto di questo su un microcontrollore STM32, qui il codice è su github . Ha ottenuto alcuni buoni risultati basati su una serie di suite di test di randomizzazione.

Secondo me, penso che sia meglio che campionare un pin mobile con un ADC che è estremamente facile da attaccare (legare il pin a terra e il tuo numero non è più così casuale!). Sono sicuro che esiste un modo per manipolare un RNG basato su jitter di clock, ma mi fa sentire un po 'meglio che posso farlo puramente basato su sorgenti di clock interne su chip.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.