Table of Contents

Introducere

Generarea numerelor aleatoare are o serie de aplicații în criptografie, testarea sistemelor, debugging, trageri la sorți, jocuri RPG, în general situații în care sunt de preferat evenimente imprevizibile. Pentru acest scop se folosesc fie numere pseudoaleatoare (cum sunt cele întoarse de funcția rand(), de exemplu), sau numere produse de un generator hardware (true random numbers). Dezavantajul primelor este că, în unele condiții, se poate afla următorul număr generat aleator chiar dacă nu se cunoaște seed-ul sau algoritmul, analizând secvența de numere.

Generatoarele de numere aleatoare hardware nu sunt influențate de evenimente macroscopice, și de aceea sunt utile în aplicații în care securitatea este vitală (generarea de chei publice sau de chei de sesiune) Ele folosesc ca suport pentru generare un fenomen fizic microscopic: se pot servi, de exemplu, de zgomotul produs de diverse fenomene electrice, de descompunerea radioactivă, de zgomot atmosferic sau de fenomene cuantice.

Mi-am propus să realizez un astfel de generator de numere aleatoare, folosind ca sursă de zgomot o joncțiune PN polarizată invers.

Descriere generală

Sursa de zgomot va produce tensiuni mici variabile. Ele vor fi amplificate și apoi, cu ajutorul unui inversor, transformate în impulsuri digitale. Impulsurile vor fi citite de microcontroller, unde vor fi folosite ca suport pentru obținerea unei secvențe de biți random. Aceasta va fi prelucrată mai departe pentru a elimina diversele neajunsuri impuse de sursa de zgomot, obținând byte stream-ul final.

Webserver-ul va primi cereri de numere aleatoare și se va folosi de byte stream pentru a răspunde la ele.

Hardware Design

Generarea de numere aleatoare:

Schema 1:

schema1.jpg

Circuitul folosește ca sursă de zgomot jonctiunea BE a primului tranzistor, polarizată invers, iar tranzistorii 2 și 3 amplifică zgomotul joncțiunii.

Am realizat montajul de mai sus, am conectat circuitul pe un input de ADC de la microcontroller și am făcut sampling la diverse intervale de timp (cu ajutorul timerului 1). Am alimentat întâi direct de la un adaptor (are tensiunea nominală de 12V, dar output-ul real e cam de 17V) dar se vedeau variațiile de tensiune de pe alimentare și nu zgomotul. Apoi am folosit un stabilizator de 12V și nu am detectat variații semnificative ale tensiunii (chiar și după amplificarea dată). Am decis să încerc și o altă schemă.

Schema 2:

schema2.jpg

Această schemă folosește tot un tranzistor pentru generarea noise-ului, dar pentru amplificare folosește inversoare aduse în zona liniară cu ajutorul unor rezistențe de valoare foarte mare. Ultimul inversor nu e folosit ca amplificator; rolul lui e de a prelua spike-urile din noise-ul amplificat de celelalte două și de a le aduce la 5V.

Schema originală era cu inversoare TTL și rezistențe de 2.7k în paralel dar mi s-au părut prea mici; am simulat un inversor CMOS cu o rezistență de 1M în paralel și avea o amplificare cam de 150x, deci asta am folosit și eu.

Circuitul integrat e alimentat la 5V, iar restul direct de la adaptor (tensiunea e folosită doar pentru polarizarea inversă deci e bine să fie cât mai mare, și nu se regăsește pe ieșire).

Această schemă a funcționat din prima, cam la orice sample rate genera spike-uri de 5V la intervale de timp neregulate.

Interfatarea cu ATMEGA16:

Am conectat iesirea ultimului inversor la pinul ADC5 (PA5) al microcontrollerului.

Interfatarea ENC28J60:

schema_eth.jpg

Am realizat montajul conform datasheet-ului și am conectat pinii SPI la microcontroller. Se execută funcțiile de inițializare din laboratorul 6, și led-ul A pâlpâie dar nu are link.

Va trebui să scad viteza de generare a numerelor random pentru a nu încurca funcționarea webserverului.

Software Design

Programare: PonyProg 2000 Conectare pe interfața serială: minicom

Am folosit interfața serială pentru a verifica output-ul generatorului (9600 baud, 8 biți de date, 2 biți de stop). Am salvat un fișier de 29k cu random bytes pentru analiză, cu minicom -C (capture file)

Prelucrarea noise-ului:

Pentru fiecare succesiune de măsurători LOW-HIGH-HIGH-…-HIGH-LOW, am considerat un spike.

În varianta finală a algoritmului (vezi Jurnal pentru variante intermediare), am folosit o rată de sampling de 8MHZ (Timer1 fără prescaling și OCR1A = 1) pentru a citi intrarea ADC a microcontrollerului și a detecta spike-uri. Pentru obținerea unui bit random, am folosit paritatea numărului de măsurări între două spike-uri succesive (la fiecare măsurare, se incrementează un contor, iar când se detectează un spike, se generează bitul contor % 2 după care se resetează contorul). Viteza de generare cu această metodă s-a dovedit a fi foarte bună (cam 20 bytes/sec), iar distribuția numerelor este suficient de uniformă pentru a nu fi nevoie de aplicarea unui algoritm de debiasing.

Pentru codul final și câteva progrămele de analiza output-ului, vezi secțiunea Download.

Webserver-ul

Nu am mai ajuns acolo.

Probleme

Încă de la început, curentul prin circuit era de câteva zeci de mA (stabilizatorul se încălzea foarte tare) dar nu am reușit să îmi dau seama de ce (am încercat să fac debug, să înlocuiesc capacități / tranzistoare / microcontrollerul / alte integrate, dar degeaba). L-am lăsat așa cât timp am făcut partea de generare a numerelor aleatoare. După ce am lipit enc28j60, în timp ce integram codul webserverului, s-a ars microcontrollerul - doar partea de ADC (măsura 5V orice i-aș fi pus acolo), USART încă mergea. Am cumpărat alt microcontroller pe care mergeau timerele dar nu și interfațarea serială (exact cu codul vechi despre care știam că era corect pentru că mergea pe microcontrollerul semi-ars). Pentru că n-am putut să îl fac să scoată output pe serială, nu aveam cum să-mi dau seama dacă merge ADC-ul (nu că mi-ar fi folosit la mare lucru). Am împrumutat un microcontroller care mergea și am mai încercat o dată să îmi dau seama care e cauza curentului mare dar nu am reușit, și am renunțat.

Rezultate Obţinute

Experiență.

schema_toata.jpg

Concluzii

Se poate face destul de simplu acasă un generator hardware de numere aleatoare, cu piese comune, dar partea dificilă este a-l face fiabil și a-l calibra astfel încât să aibă o viteză decentă de generare și să obțină rezultate bune la testele de randomness. E nevoie și de mai mult timp pentru a-l testa (pentru a obține un output suficient de mare încât să fie relevant).

Download

Surse proiect

Jurnal

23.05

24.05

25.05

26.05

27.05

28.05: algoritmul de conversie

29.05

30.05

31.05

Bibliografie/Resurse

Random Number Generators:

Rob Seward's random number generator and version 2

Aaron Logue's random number generator

Resurse software:

Teste pentru generatoare de numere aleatoare

Embedded web server

Datasheet-uri:

Datasheet ATMega16

Datasheet ENC28J60