% !TEX root = ../thesis.tex \chapter{Metodika testovania dát a merania rozhraní}\label{merania} Pred samotným generovaním dát je nutné zvoliť meracie a testovacie metódy. V~tejto kapitole ich popíšeme. Znázornené demo príklady zdrojových kódov sú obsahom prílohy A, spoločne s makefile-om. Implementáciu rozhraní sme realizovali v programovacom jazyku C. Preklad do strojového kódu zabezpečil prekladač \acrshort{gcc} vo verzii 10.2.0 (04. 03. 2021). \textbf{Overenie kvality dát} vykonáme pomocou NIST štatistickej testovacej sady (ďalej NIST STS), opísanej v podkapitole \ref{nist}. Pri experimentálnych meraniach implementácií RNG rozhraní sme sa zamerali na tri údaje: \begin{itemize} \item čas vykonania samotnej implementácie -- \textbf{$T_A$}, \item dobu vykonania, vrátane bežných úkonov\footnote{Ukladanie dát, overenie úspešnosti generovania, ...} -- \textbf{$T_B$}, \item priemerný počet cyklov API -- \acrshort{anc}. Získa sa ako pomer súčtu všetkých vykonaných cyklov a počtu opakovaní volania testovanej funkcie. Pri výsledkoch uvádzame ANC iba z hodnôt meraní $T_A$. \end{itemize} Pomocou týchto nameraných hodnôt sme vypočítali priepustnosť dát. Použili sme vzťah \eqref{priepustnost}.\\ Nech $_X=\{A,B\}$, $T_X$ -- čas zvoleného procesu, $NI$ -- počet opakovaných volaní\footnote{Z ang. \textit{Number of Iterations}.}, $BS$ -- veľkosť buffer-a\footnote{Z ang. \textit{Buffer Size}.}, $V_D = NI*BS$ -- celkový objem vygenerovaných dát, $P_X$ -- priepustnosť procesu,\\ potom, \begin{equation}\label{priepustnost} P_X = \frac{V_D}{T_X} . \end{equation} Uvedené experimenty boli aplikované na~troch zariadeniach. Špecifikáciu prenosných počítačov znázorňuje tabuľka \ref{pc}. Všetky notebook-y sme počas testovania pripojili do elektrickej siete. Režim napájania sme zmenili na \uv{Vysoký výkon}. \textbf{Označenia} hodnôt a~meracích nástrojov, ktoré vznikli v~tejto kapitole \textbf{sú použité pri~interpretácii výsledkov}. \begin{table}[!ht] \centering \resizebox{\textwidth}{!}{% \begin{tabular}{c|c|c|c} \multirow{2}{*}{\bfseries Komponenty}&\multicolumn{3}{c}{ \bfseries Konfigurácia} \\ & \bfseries{A} -- ASUS TUF A15 & \bfseries{B} -- ASUS Vivo15 & \bfseries{C} -- LENOVO IdeaPad \\\hline\hline \bfseries Model & F506IU-AL006T & X510UN-BQ148R & S540-15IML \\ \bfseries Verzia OS & Win 10 Home; 64-bit.; v.20H2 & Win 10 Pro; 64-bit.; v.2004 & Win 10 Home; 64-bit.; v. 20H2 \\ \bfseries Zostava OS &19042.964 &19041.928 &19042.985 \\ \bfseries CPU& AMD Ryzen 7 Mobile 4800H & Intel Core i5-8250U & Intel Core i5-10210U \\ \bfseries RAM&16 GB DDR4 2x1600 MHz & 8 GB DDR4 1x2400 MHz & 8 GB DDR4 2x1200 MHz \\ \bfseries Úložisko&SSD OM8PCP3512F-AB &HDD MQ04ABF100 &SSD SSDPEKNW512G8L \\ \end{tabular} } \caption{Technická špecifikácia použitých počítačov}\label{pc} \end{table} V~tomto bode treba spomenúť určitú odchýlku experimentálnych meraní od skutočných hodnôt. Najväčším faktor, ktorý mohol spôsobiť chybu merania sú prerušenia operačného systému\footnote{Viď. napríklad elapsedTime v \ref{qpc}.}. Uvedenému procesu je možné sa vyhnúť jedine implementáciou modulu pre prácu v~režime jadra. Následne by sme vyhradili procesor pre vlastné účely. Kladom módu by mohol byť aj menší počet inštrukcií potrebných na vykonanie funkcionality. S týmto postupom sa však používateľ často nestretáva. Uvedený fakt je dôvodom, prečo sme sa pri meraniach zamerali iba na~spúšťanie rozhraní v~používateľskom režime. Pripomenieme však, že rozhrania v~oboch režimoch poskytujú \textbf{identické služby}. \section{Časové meranie rozhraní} Pri meraní dĺžky vykonávania rozhraní sme implementovali Windows API: \begin{itemize} \item \verb|QueryPerformanceCounter()| --\acrshort{qpc} \cite{qpc}, \item \verb|QueryPerformanceFrequency()| --\acrshort{qpf} \cite{qpf}. \end{itemize} Informácie o funkciách sú dostupné vo forme webovej dokumentácie \cite{measure}. Použitie týchto rozhraní pri meraní znázorňuje zdrojový kód \ref{qpc}. Uvedeným postupom dokážeme odmerať čas vykonania algoritmu s rozlíšením nanosekúnd\footnote{API je možné implementovať s presnosťou piko-sekúnd. Viď \cite[Using QPC in native code]{measure}.}. Presnosť metódy sa dá overiť jednoducho. Napríklad pomocou funkcie \verb|Sleep()|\footnote{\textbf{\textit{Sleep(1000)}} reprezentuje jednu sekundu.}. Stačí ju vložiť do 18. riadku v zdrojovom kóde \ref{qpc}. \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, caption={Ukážka použitia QPC/QPF}\label{qpc}, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] #include #define TIMER_INIT \ LARGE_INTEGER frequency; \ LARGE_INTEGER t1,t2; \ double elapsedTime; \ QueryPerformanceFrequency(&frequency); // Use to start the performance timer #define TIMER_START QueryPerformanceCounter(&t1); // Use to stop the timer #define TIMER_STOP \ QueryPerformanceCounter(&t2); \ elapsedTime=(double)(t2.QuadPart-t1.QuadPart)/frequency.QuadPart; int main(){ TIMER_INIT {TIMER_START functionMeasurment(); // code for measurment TIMER_STOP} printf("Time of execution: %f sec\n", elapsedTime); return 0; } \end{lstlisting} \end{minipage}\\ \subsubsection{Odporúčanie pri pretypovaní dát} V jazyku C môže pri pretypovaní dát dochádzať k zmene poradia vygenerovaných reťazcov. Dôvodom je zmena endianity\footnote{\url{https://sk.wikipedia.org/wiki/Endianita}.}, respektíve uloženia dát v pamäti. S týmto problémom sme sa stretli pri zmene z \textbf{unsigned int} na \textbf{unsigned char} vo funkcii \verb|rand_s|. Dáta v pamäti boli uložené metodikou malý endián, ale správne poradie vygenerovaných dát reprezentoval veľký endián. V~tomto prípade bolo nutné vykonať konverziu endianity. Použili sme na to funkcie znázornené pomocou zdrojového kódu \ref{endian}. \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, caption={Ukážka pretypovania premenných}\label{endian}, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] #include #define IS_BIG_ENDIAN (!*(unsigned char *)&(uint16_t){1}) int main (){ unsigned int a = 2343352; unsigned char b; if(!IS_BIG_ENDIAN) castUintToByte(a,b); else b=(unsigned char)a; printf("%lu",b); return 0; } \end{lstlisting} \end{minipage}\\ \section{Meranie počtu cyklov jednotlivých funkcií} Obdobne sme sa zamerali aj na~počet cyklov jednotlivých funkcií. Tento údaj nám z pohľadu dlhodobého vývoja predstavuje kvalitnejšiu informáciu ako čas vykonania. Na základe týchto údajov vieme určiť napríklad či v priebehu času došlo k zefektívneniu algoritmov rozhrania\footnote{Zmenší sa počet cyklov, potrebných na vykonanie.}. Ďalším príkladom je určenie pomeru prerušení \acrshort{os} a mnoho iných. Meranie sme prvotne realizovali pomocou funkcie \verb|cpucycles()|\footnote{Funkcia prebraná z git archívu: \url{https://github.com/newhopecrypto/newhope/tree/master/ref}.}. Zdrojový kód \ref{git}, ju definuje. Táto metóda však neposkytovala dostatočne presné výsledky. \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, caption={Meranie počtu cyklov pomocou funkcie cpucycles()},label=git, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] int64_t cpucycles(void){ uint64_t result; __asm__ volatile(".byte 15;.byte 49;shlq $32, %%rdx;orq %%rdx,%%rax" : "=a" (result) :: "%rdx"); return result; } \end{lstlisting} \end{minipage}\\ Meranie počtu vykonaných cyklov sme, kvôli tomuto faktoru, uskutočnili podľa metód v~Intel dokumente \cite[kap.3.2.1]{intelrd}. Ukážkou aplikovaného riešenia je kód \ref{cycles}. \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, caption={Meranie počtu cyklov Intel metódou},label=cycles, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] #include //cpucyclesS -- Start measure static __inline__ uint64_t cpucyclesS(){ unsigned cycles_low, cycles_high; __asm__ volatile ("CPUID\n\t" "RDTSC\n\t" "mov %%edx, %0\n\t" "mov %%eax, %1\n\t": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx", "%rcx", "%rdx"); return (((uint64_t)cycles_high << 32) | cycles_low ); } //cpucyclesE -- End measure static __inline__ uint64_t cpucyclesE(){ unsigned cycles_low, cycles_high; __asm__ volatile ("RDTSCP\n\t" "mov %%edx, %0\n\t" "mov %%eax, %1\n\t" "CPUID\n\t": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx", "%rcx", "%rdx"); return (((uint64_t)cycles_high << 32) | cycles_low ); } int main(){ uint64_t tick,tock; tick=cpucyclesS(); codeForMeasurment(); tock= cpucyclesE() - tick; printf("Executed: %llu cycles\n", tock); return 0; } \end{lstlisting} \end{minipage}\\ \chapter{Štatistické testovanie generátorov} Pri používaní \acrshort{rng} môže dôjsť k jeho vnútorným zmenám. Na~overenie kvality generátorov náhodných čísel sa~používajú statické testy náhodnosti. Väčšina z~nich preveruje jednu alebo hneď niekoľko štatistických vlastností. Cieľom je~odhaliť anomáliu bitov v~danej postupnosti dát. Pre používateľa sú~k~dispozícií vo~for-me jednotlivých testov alebo štatistických testovacích sád. Takáto zbierka predstavuje implementáciu viacerých štatistických testov, pripravených na~jednoduché použitie, modifikáciu a~vyhodnotenie. Najznámejšími~sú: \begin{itemize} \item\textbf{Dieharder}\cite{dieharder}, \item\textbf{NIST STS}\cite{niststs} -- z~ang. \textit{The NIST Statistical Test Suit}. \end{itemize} Okrem vyššie uvedených je však možné vyhľadať, vytvoriť, a aj upraviť, respektíve optimalizovať rôzne implementácie štatistických testov. Dôkazom toho je aj vznik modifikovanej NIST testovacej sady -- \cite{fasterniststs}. Podľa vyjadrení autorov uvedeného projektu sa im podarilo zefektívniť rýchlosť testovania o vyše 50 percent v porovnaní s originálom. Ďalšie príklady testovacích sád sú napríklad \textbf{ENT} \cite{ent}, \textbf{TestU01} \cite{testu01} a mnohé iné. Je však nutné uvedomiť si, že úspešné absolvovanie ľubovoľného počtu štatistických testov nezabezpečuje kryptografickú bezpečnosť daného generátora. Dôvodom je, že niektoré z nástrojov na generovanie náhodných dát môžu byť pripravené tak, aby boli úspešné pri vykonávaní týchto testov. Avšak platí, že ak má byť \acrshort{rng} označený za \acrshort{csprng}, tak musí úspešne zvládnuť testovanie štatistickými testami. \section{Testovacia sada Dieharder} Sád Diehard vznikla v~roku 2003 a~je aj~naďalej udržiavaná. Slúži na testovanie dát z \acrshort{rng}s. Používateľ môže pomocou sady generovať dáta a následne ich otestovať. Okrem toho je možné testovať aj vlastný súbor s náhodnými dátami. Výstupom sady je výpis vo forme tabuľky s výsledkami použitých štatistických testov. Aktuálna verzia -- 3.31.1 (03. 06. 2020), pozostáva~z: \begin{itemize} \item 17 Diehard, \item 3 NIST STS, \item 10 testov, autora tejto zbierky -- \textit{Róberta G. Brown-a}. \end{itemize} Podrobnejší opis týchto testov je~dostupný online\footnote{\url{https://sites.google.com/site/astudyofentropy/background-information/the-tests/dieharder-test-descriptions}.}$^{,}$\footnote{\url{https://en.wikipedia.org/wiki/Diehard\_tests}.}. Inštalácia sady je jednoduchá najmä v prostredí OS Linux. Realizuje ju príkaz: \\\verb|sudo apt-get install -y dieharder|\footnote{Príkaz pre distribúciu Ubuntu.}.\\V~prostredí systému Windows je potrebná zložitejšia konfigurácia. \section{NIST -- Štatistická testovacia sada}\label{nist} Tento balíček bol vytvorený inštitúciou NIST. Pozostáva z 15 testov. Slúžia na overenie kvality výstupných dát z hardvérových, a aj softvérových generátorov náhodných čísel. V~súčasnosti sa práve táto sada používa aj pri testovaní \acrshort{csprng}. Na rozdiel od spomenutej kolekcie \textit{Dieharder} táto zbierka vyšla s podrobnou dokumentáciou \cite{niststs}. Uvádzame stručný opis metód a použitých testov. \subsection{Obsah sady a opis implementovaných testov} Sada je pre používateľa dostupná vo forme archívu -- \uv{\textbf{sts-2.1.2.zip}}\footnote{\url{https://csrc.nist.gov/CSRC/media/Projects/Random-Bit-Generation/documents/sts-2\_1\_2.zip}.}(09. 07. 2014). Jeho obsahom sú implementácie štatistických testov v~jazyku C. \textbf{Makefile} na jednoduché vytvorenie spustiteľného programu a príklady vstupných dát z~rôznych typov generátorov. Následné spustenie je opísané v \cite[kap. 5.6]{niststs} a pomocou ukážky \ref{sts}. \subsubsection*{Opis testov štatistickej sady:} \begin{enumerate} \item \textbf{Frekvenčný test -- \textit{The Frequency/Monobit Test}\cite[kap. 2.1]{niststs}} Výsledok je určený pomerom jednotkových a nulových bitov v danej testovanej postupnosti. Úspešný je vtedy, ak sa obsah jednotiek v našich dátach blíži k $\frac{1}{2}$ z celkového počtu. Odporúčaná dĺžka testovanej postupnosti je minimálne 100 bitov. Úspešné zvládnutie tohto testu je nutnou podmienkou pre ďalšie pokračovanie testovania. \item \textbf{Blokový frekvenčný test -- \textit{Frequency Test within a Block}\cite[kap. 2.2]{niststs}} Podobný prvému zo spomenutej sady. Namiesto testovania celej postupnosti dát dochádza k frekvenčnému testu $m$-bitových blokov. Úspešný je vtedy, keď sa výsledný pomer rovná $\frac{m}{2}$, pričom $m$ je počet bitov jedného bloku. Obdobne aj v tomto prípade sa odporúča testovať minimálne 100 bitovú postupnosť. \item \textbf{Test rovnakých reťazcov -- \textit{Run Test}\cite[kap. 2.3]{niststs}} Zameraný na celkový počet po sebe idúcich neprerušených a rovnakých bitov -- tzv. \textbf{behov}. Cieľom tohto testu je overiť rôznorodosť striedajúcich sa postupností pri generovaní. Odporúča sa aplikovať na postupnosť s minimálnou dĺžkou 100 bitov \item \textbf{Test najdlhšej postupnosti jednotiek v bloku -- \textit{Test for the longest Run of Ones in a Block}\cite[k. 2.4]{niststs}} Zameraný na najdlhší beh v $m$-bitových blokoch. Má za úlohu overiť, či najväčšia vygenerovaná postupnosť je v súlade s najdlhšou sériou, aká sa očakáva, resp povoľuje v náhodnej postupnosti bitov\footnote{Povolený počet jednotiek závisí od veľkosti testovanej postupnosti.}. Odporúča sa aplikovať test na minimálne 128 bitov náhodnej postupnosti. \footnote{V tomto prípade sa dovoľuje maximálne 8, po sebe idúcich, jednotkových bitov.} \item \textbf{Test hodností binárnych matic -- \textit{Binary Matrix Rank Test}\cite[kap. 2.5]{niststs}} Zameraný na poradie disjunktných\footnote{Disjunktné množiny sú také, ktoré nemajú žiaden spoločný prvok.} submatíc celej testovanej postupnosti. Overuje lineárne závislosti medzi podreťazcami s pevnými veľkosťami. Tento test je obdobne súčasťou sady Dieharder. Pre správne fungovanie je minimálna dĺžka postupnosti stanovená na 38 912 bitov. \item \textbf{Test diskrétnej Fourierovej transformácie -- \textit{Discrete Fourier Transform (Spectral) Test}\cite[kap. 2.6]{niststs}} Zameraný na výšky vrcholov -- \textbf{amplitúd}, jednotlivých bitov testovanej postupnosti v diskrétnej Fourierovej transformácii\footnote{\url{https://cs.wikipedia.org/wiki/Fourierova\_transformace}.}. Cieľom je detekcia periodických znakov, ktorá by naznačovala odchýlku od predpokladu náhodnosti. Zisťujú sa prahové hodnoty\footnote{Prahová hodnota -- krajná, resp. hraničná hodnota. Získava sa prahovaním. Viac informácií o tejto metóde je dostupných v dokumente \cite[k. 1.3]{prahovanie}.} 95\% znakov a zvyšných 5\% testovanej postupnosti. Následne sa overuje, či nedochádza k významnej odlišnosti medzi týmito hodnotami. 1 000 bitov sa odporúča ako minimálna veľkosť postupnosti. \item \textbf{Test neprekrývajúcich sa vzorov -- \textit{Non-overlapping Template Matching Test}\cite[kap. 2.7]{niststs}} Zameraný na počet vopred určených bitov v testovanom reťazci -- tzv. okne. Cieľom je detegovať generátor, ktorý generuje veľa neperiodického vzoru. Test používa $M$-bitové okno na vyhľadanie konkrétneho $m$-bitového vzoru. Ak ho nenájde, nastane posun okna o jednu bitovú pozíciu. Ak sa nájde, okno sa resetuje na bity po nájdenom vzore a vyhľadávanie pokračuje. Nemá odporúčanú dĺžku vstupnej postupnosti. Parametre pre tento test sa vypočítajú na základe požiadavky. \item \textbf{Test prekrývajúcich sa vzorov -- \textit{Overlapping Template Matching Test}\cite[kap. 2.8]{niststs}} Pracuje na rovnakom princípe ako 7. test. Rozdiel je len pri zhode vzoru s~oknom. V tomto prípade sa okno posúva o jeden bit a následne pokračuje prehľadávanie. \item \textbf{Mauerov \uv{univerzálny štatistický} test -- \textit{Maurer's \uv{Universal Statistical} Test}\cite[kap. 2.9]{niststs}} Zameraný na počet bitov medzi zhodnými vzormi. Overuje, či je možné danú postupnosť komprimovať bez straty informácií. Ak je možná veľká kompresia, tak daná postupnosť sa nepovažuje za náhodnú. Vstupná postupnosť môže mať variabilnú dĺžku. Odporúča sa aplikovať na minimálne 1 000 000-bitovú postupnosť. \item \textbf{Test lineárnej zložitosti -- \textit{Linear Complexity Test}\cite[k. 2.10]{niststs}} Zameraný na dĺžku posuvného registra s lineárnou spätnou väzbou -- \acrshort{lfsr}\footnote{Výstup tohto registra je lineárne závislý od jeho počiatočného stavu a predchádzajúcich výstupov. Používa sa napríklad v PRNG a prúdových šifrách.}. Cieľom je zistiť, či je daná postupnosť dostatočne zložitá, aby sa mohla považovať za náhodnú. Platí, že dlhšie \acrshort{lfsr}s spĺňajú tento predpoklad. \\ \item \textbf{Test Sérií -- \textit{Serial Test}\cite[kap. 2.11]{niststs}} Zameraný na frekvenciu všetkých možných prekrývajúcich sa m-bitových vzorov v celej testovanej postupnosti. Cieľom je zistiť, či počet výskytov je približne rovnaký, ako by mal byť v náhodnej postupnosti. Tá by mala byť rovnomerná\footnote{Rovnomernosť, resp. uniformita, náhodnej postupnosti znamená, že každý m-bitový vzor ma rovnakú pravdepodobnosť objaviť sa, ako ktorýkoľvek iný.}. Vyžaduje sa zvoliť $m$ také, pre ktoré platí $m<[log_2 n]-2$. Veľkosť vstupnej postupnosti v bitoch reprezentuje premenná $n$. \item \textbf{Približný test Entropie -- \textit{Approximate Entropy Test}\cite[kap. 2.12]{niststs}} Podobný ako Test Sérií. Zameraný na frekvenciu všetkých možných prekrývajúcich sa vzorov s dĺžkou $m$-bitov. Porovnanie sa aplikuje na frekvencie dvoch po sebe nasledujúcich blokov, ktoré sa prekrývajú. Výsledok je následne porovnaný s ekvivalentom pre náhodnú postupnosť. Vyžaduje sa zvoliť $m$ také, pre ktoré platí $m<[log_2 n]-5$. Veľkosť vstupnej postupnosti v bitoch reprezentuje premenná $n$. \item \textbf{Test kumulatívnych súčtov -- \textit{Cumulative Sums Test}\cite[kap. 2.13]{niststs}} Zameraný na maximálnu odchýlku od nuly pri kumulatívnom súčte všetkých bitov. Pri~tomto postupnom hromadnom sčítaní predstavujú jednotkové bity kladné jednotky. Nuly na druhej strane záporné. Cieľom testu je určiť, či takýto kumulatívny súčet testovaných dát zodpovedá náhodnej sekvencii. Test je úspešný, ak sa výsledok sčítania blíži k nule. Odporúča sa, aby každá testovaná postupnosť mala minimálnu dĺžku 100 bitov. \item \textbf{Test náhodných návštev -- \textit{Random Excursions Test}\cite[kap. 2.14]{niststs}} Zameraný na počet cyklov, ktoré majú presne $K$ náhodných návštev v kumulatívnom súčte. Všetky cykly majú dĺžku zvolenú náhodne. Cieľom je zistiť či sa počet návštev odlišuje od hodnoty platnej pre náhodné dáta. Test pozostáva z 8 čiastočných testov. Každý otestuje jeden zo stavov: -~4, -~3, -~2, -~1, 1, 2, 3, 4. Úspešný je iba ak dáta uspejú vo všetkých čiastočných testoch. Odporúča sa testovať postupnosť s minimálnou dĺžkou 1 000 000 bitov. \item \textbf{Test variantov náhodných návštev -- \textit{Random Excursions Variant Test}\cite[kap. 2.15]{niststs}} Zameraný na celkový počet návštev jednotlivých stavov pri kumulatívnom súčte. Pozostáva z 18 testov. Postupne sa testujú stavy: -~9, -~8, ..., -~1, 1, ..., 8, 9. Odporúčaná minimálna veľkosť vstupu je rovnaká ako v 14. teste. \end{enumerate} \subsection{Interpretácia výsledkov sady štatistických testov} Nasledujúce vety vychádzajú z dokumentu \cite[kap. 1.1.5]{niststs}. Testovanie pomocou sady je založené na overení dvoch predpokladov, tzv. \textbf{nulovej} a \textbf{alternatívnej} hypotézy. Prvá z uvedených, ozn. $H_0$, tvrdí, že testovaná postupnosť je náhodná. Druhú definujeme ako inverznú voči nulovej, teda výstup z RNG je nenáhodný. Len jeden z týchto predpokladov je prijatý v~priebehu aplikácie sady. V~súvislosti s~týmto postupom môže dôjsť k 2 typom chýb v~priebehu testovania. \begin{enumerate} \item Postupnosť je náhodná, ale $H_0$ nebola akceptovaná. \item Postupnosť nie je náhodná, avšak nulová hypotéza je prijatá. \end{enumerate} Pravdepodobnosť, že dôjde k~prvému zo~spomenutých dejov definuje pojem -- \textbf{hladina významnosti}, označíme $\alpha$. Jej~veľkosť závisí od~konkrétneho štatistického testu. Typicky sa volí z~intervalu $\langle 0.001,0.01\rangle$ Na vyhodnotenie uvedených predpokladov dochádza pri~každom teste k~porovnaniu \textbf{výslednej štatistickej hodnoty} $S$\footnote{Hodnota získaná aplikovaním daného testu na~naše dáta.} a~\textbf{kritickej} hodnoty, ďalej \acrshort{cv}\footnote{Z~ang. \textit{Critical Value}.}. \\Každý z~testov má definované štatistické hodnoty, na~základe ktorých môžeme prijať alebo odmietnuť $H_0$. \acrshort{cv} je hodnota získaná štatistickým rozdelením hodnôt. Platí, že táto hodnota predstavuje výsledok testu, ktorý pochádza na~99\% z~nenáhodnej postupnosti testovaných dát. Inými slovami, predstavuje hodnotu, pri~ktorej už neakceptujeme $H_0$ ako pravdivé. Program vytvorí výpis s~medzi-výpočtami pre každý test a~zároveň aj finálny výsledok testu. Používateľ si však môže všimnúť tzv. \textbf{pravdepodobnostnú hodnotu} -- $P\text{-VALUE}$. Viď tabuľku \ref{far}. \begin{table}[!ht] \centering \resizebox{\textwidth}{!}{ \begin{tabular}{ c|c|c|c|c|c|c|c|c|c|c|c|c}\hline \bfseries C1&\bfseries C2&\bfseries C3&\bfseries C4&\bfseries C5&\bfseries C6&\bfseries C7&\bfseries C8&\bfseries C9&\bfseries C10& \bfseries P-VALUE & \bfseries PROPORTION& \bfseries STAT. TEST \\\hline 486& 487& 459& 423& 439& 450& 479& 487& 443& 447& 0.306049& 4546/4600& Frequency \\ 427& 474& 476& 456& 482& 470& 464& 443& 460& 448& 0.776260& 4553/4600& BlockFrequency\\ 495& 490& 449& 425& 462& 438& 426& 475& 457& 483& 0.172899& 4550/4600& CumulativeSums\\ 458& 450& 468& 461& 456& 474& 495& 457& 425& 456& 0.718863& 4553/4600& Runs\\ 438& 500& 445& 484& 495& 462& 417& 473& 440& 446& 0.101732& 4554/4600& LongestRun\\ 464& 440& 481& 484& 459& 428& 442& 455& 477& 470& 0.642552& 4555/4600& Rank\\ 490& 501& 454& 452& 436& 452& 476& 421& 451& 467& 0.251503& 4544/4600& FFT\\ 462& 425& 448& 488& 466& 514& 494& 443& 426& 434& 0.032592& 4560/4600& NonOverlappingTemplate\\ 496& 489& 473& 468& 457& 454& 442& 437& 434& 450& 0.456758& 4536/4600& OverlappingTemplate\\ 483& 453& 461& 456& 445& 445& 450& 438& 469& 500& 0.616757& 4553/4600& Universal\\ 512& 448& 431& 439& 485& 471& 454& 447& 451& 462& 0.260244& 4543/4600& ApproximateEntropy\\ 254& 289& 272& 308& 272& 249& 326& 310& 291& 293& 0.022539& 2833/2864& RandomExcursions\\ 283& 285& 295& 280& 275& 284& 294& 320& 269& 279& 0.706626& 2840/2864& RandomExcursionsVariant\\ 452& 472& 468& 441& 475& 449& 477& 439& 467& 460& 0.922748& 4563/4600& Serial\\ 463& 419& 445& 478& 448& 456& 485& 461& 470& 475& 0.607722& 4553/4600& LinearComplexity\\ \end{tabular} } \caption{Príklad skráteného výpisu sady NIST STS po otestovaní náhodných dát}\label{far} \end{table} Pri testovaní sú vstupné hodnoty testovaných postupnosti rozdelené na 10 približne rovnakých častí ($C1\text{ -- }C10$). Následne dochádza k výpočtu jednotlivých $p\text{-}values$ v každej z týchto častí. Tieto čiastkové $p\text{-}values$ sú vypočítané podľa daného štatistického testu a jeho výsledkov. Výsledná hodnota $P\text{-VALUE}$ je vypočítaná pomocou uvedených čiastkových hodnôt ($p\text{-}values$), dosadených do~vzťahov a~funkcií v~\cite[kap. 4.2.2]{niststs}. Pri úspešnom testovaní platí pre výslednú hodnotu $P\text{-VALUE}$ vzťah \eqref{p-value}. \\ Nech \begin{equation*} X = P\text{-VALUE}, \end{equation*} potom, \begin{equation}\label{p-value} (X \in (\alpha < X \geq 1)) \Leftrightarrow (H_0 = pravda). \end{equation} V tabuľke \ref{far} sa nachádza taktiež stĺpec \textit{PROPORTION}. Ten znázorňuje pomer úspešných a všetkých vykonaných testov pri testovaní sadou NIST. \subsection{Doba vykonávania testovacej sady} Obsahom tejto podkapitoly sú informácie súvisiace s dobou vykonávania sady NIST STS. Testovanie sme uskutočnili na konfigurácii A\footnote{Vid. tabuľku \ref{pc} v kapitole \ref{merania}.}. Na meranie dĺžky času vykonávania sme modifikovali zdrojové kódy sady NIST STS. Použili sme Windows rozhranie na meranie času -- \textbf{QueryPerformanceCounter()}. Taktiež sme zisťovali počet cyklov jednotlivých testov vzhľadom na~veľkosti vstupov $m_1 \text{ a } m_2$. K~tomu nám dopomohli inštrukcie \textbf{RDTSC} a~\textbf{RDTS-CP}. Opis použitých metód je obsahom kapitoly \ref{merania}. Takto upravená testovacia sada je súčasťou prílohy A. Experimentálne výsledky sú znázornené v~tabuľke \ref{ststimes}. Výsledná doba vykonania daného testu zavisí od~veľkosti testovanej postupnosti. Pre celkový čas platí \eqref{totaltime}. Ak~by sme vyhradili procesor iba pre nás, tak potom jednotlivé časy $t_i$ by boli konštantné. Dôvodom je deterministický charakter procesu. Tento úkon však nie je v používateľskom režime možný. Uvedený vzťah ráta s týmto faktom.\\ \\Nech $m$ -- veľkosť vstupnej testovacej postupnosti, $t_i$ -- doba aplikovania všetkých testov na m-bitovú postupnosť, $n$ -- počet testovaných prúdov s veľkosťou m, $T$ -- výsledný čas celého testovania.\\ Potom \begin{equation}\label{totaltime} T = \sum_{i=1}^{n}t_i . \end{equation} Pri meraní času v tabuľke \ref{ststimes} sme zvolili $n = 1$ pre obidve náhodné postupností ($m_1, m_2$). \begin{table}[!ht] \centering \begin{tabular}{ c|c|c|c|c } \multicolumn{5}{c}{\bfseries Veľkosť vstupnej testovanej postupnosti } \\ \multirow{2}*{\bfseries Test č.} & \multicolumn{2}{c}{$m_1 =\text{ } $\bfseries 122kB $\approx$ 1 000 000 b } & \multicolumn{2}{c}{$m_2 =\text{ }$\bfseries 1,165GB $\approx$ 10 000 000 000 b }\\ & \bfseries ČAS [s] & \bfseries CYKLY & \bfseries ČAS [s] & \bfseries CYKLY\\ \hline 1 & 0,004 055 &\multicolumn{1}{r|}{ 11 730 471} &\multicolumn{1}{r|}{ 5,387 021} & \multicolumn{1}{r}{15 593 089 692} \\ 2 & 0,002 740 &\multicolumn{1}{r|}{ 7 921 031} & \multicolumn{1}{r|}{3,591 694} &\multicolumn{1}{r}{10 396 392 294} \\ 3 & 0,009 644 & \multicolumn{1}{r|}{27 907 135} & \multicolumn{1}{r|}{13,367 284} & \multicolumn{1}{r}{38 692 505 860} \\ 4 & 0,014 938 & \multicolumn{1}{r|}{43 230 329} & \multicolumn{1}{r|}{21,562 572} &\multicolumn{1}{r}{62 414 330 729} \\ 5 & 0,007 866 & \multicolumn{1}{r|}{22 760 418} & \multicolumn{1}{r|}{10,895 430} & \multicolumn{1}{r}{ 31 537 547 299} \\ 6 & 0,074 364 & \multicolumn{1}{r|}{215 241 654} & \multicolumn{1}{r|}{104,454 277} & \multicolumn{1}{r}{302 350 042 366} \\ 7 & 0,226 567 & \multicolumn{1}{r|}{655 801 389} & \multicolumn{1}{r|}{0,036 371} & \multicolumn{1}{r}{105 257 157} \\ 8 & 1,763 558 & \multicolumn{1}{r|}{5 104 725 551} & \multicolumn{1}{r|}{2 485,426 270} &\multicolumn{1}{r}{719 423 6071 645} \\ 9 & 0,056 390 & \multicolumn{1}{r|}{163 214 697} & \multicolumn{1}{r|}{78,888 596} & \multicolumn{1}{r}{228 348 426 960} \\ 10 & 0,045 201 & \multicolumn{1}{r|}{130 830 194} & \multicolumn{1}{r|}{67,123 001} & \multicolumn{1}{r}{194 292 108 778} \\ 11 & 0,203 056 & \multicolumn{1}{r|}{587 748 800} & \multicolumn{1}{r|}{285,328 339} & \multicolumn{1}{r}{825 902 376 471} \\ 12 & 0,004 447 & \multicolumn{1}{r|}{12 862 109} & \multicolumn{1}{r|}{10,411 473} & \multicolumn{1}{r}{30 136 705 606} \\ 13 & 0,005 211 & \multicolumn{1}{r|}{15 068 574} & \multicolumn{1}{r|}{76,817 490} & \multicolumn{1}{r}{222 353 456 121} \\ 14 & 0,564 533 & \multicolumn{1}{r|}{1 634 064 740} & \multicolumn{1}{r|}{781,071 777} & \multicolumn{1}{r}{2 260 865 638 374} \\ 15 & 3,703 921 & \multicolumn{1}{r|}{10 721 233 139} & \multicolumn{1}{r|}{5 222,643 066} & \multicolumn{1}{r}{15 117 297 898 720} \\ \hline \centering\bfseries Sumár & 6,686 501 & 19 354 524 033 & 9 167,004 883 & 26 534 522 105 621 \\ \end{tabular} \caption{Meranie testovania sady pomocou konfigurácie A }\label{ststimes} \end{table} \subsubsection{Informácie ku spusteniu sady NIST STS} Na spustenie sady je potrebná inicializácia. Používateľ ju realizuje vstupmi z~príkazového riadku. Zdrojový kód \ref{sts}, znázorňuje tento úkon. Veľkosť otestovaných dát pomocou takejto konfigurácie je 11,92 MB\footnote{1 000 000 b $*$ 100 $=$ 100 000 000 b $\approx$ 11,92 MB.}. Na základe faktov súvisiacich s výpočtom $P\text{-VALUE}$ je potrebné pre správne vyhodnotenie otestovať viacero postupností. Pri určení veľkostí vstupnej postupnosti preto odporúčame zvoliť $m = 1 000 000$ bitov ($\approx$ 122kB) a počet prúdov stanoviť na číslo deliteľné 10. Dôvodom je rozdelenie testovaných postupností práve na 10 rovnakých častí. Parametre jednotlivých testov nemeníme. Týmto postupom zamedzíme chýbam pri inicializácii sady a vykonané testy poskytnú presnejšie výsledky. \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, language=bash, caption={Príklad inicializácie testovacej sady NIST STS}\label{sts}, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,][ht!] > ./assess.exe 1000000 // size of random sequence in bits > 0 // apply tests on input file > myRandomDataFile.bin // name of file with random numbers > 1 // apply all tests > 0 // no changes of default tests values > 100 // number of bit streams > 1 // choosen bin format of input file \end{lstlisting} \end{minipage}\\ \chapter{Generovanie náhodných dát}\label{rng} Na generovanie náhodných dát má používateľ k dispozícii hneď niekoľko možností. V~rámci tejto práce rozhrania rozdelíme do dvoch kategórií: \begin{itemize} \item Hardvérové \acrshort{api} -- závisí od technického vybavenia počítača. \item Softvérové \acrshort{api} -- implementáciu služby \acrshort{rng} zabezpečuje \acrshort{os} alebo knižnice zvoleného jazyka. \end{itemize} V~tejto kapitole uvedené rozdelenie viac charakterizujeme pomocou nasledujúcich podkapitol. Súčasťou každej opísanej funkcie sú aj tabuľky s výsledkami experimentálnych meraní jednotlivých funkcií. Merania boli uskutočnené pomocou metód opísaných v kapitole \ref{merania}. Obdobne sme použili aj opísané označenia. Konkrétne: \begin{itemize} \item počet opakovaní volania testovanej funkcie -- $\acrshort{ni}$, \item veľkosť buffer-a -- $\acrshort{bs}$, \item celková veľkosť vygenerovaných dát -- $V_D$, \item priemerný počet cyklov pri vykonávaní testovanej funkcie -- \textit{\acrshort{anc}}, \item čas vykonávania (bez ukladania dát) -- $T_A$, \item čas vykonávania (s ukladaním dát) -- $T_B$, \item priepustnosť dát procesu $T_A$ -- $P_A$, \item priepustnosť dát procesu $T_B$ -- $P_B$. \end{itemize} Posledný riadok každej konfigurácie v tabuľkách, bol meraný pri maximálnej možnej veľkosti buffer-a, ktorú funkcia dokáže poskytnúť. \section{Hardvérové rozhrania} Súčasťou moderných procesorov sú~aj~implementácie generátorov skutočne náhodných čísel. Ich~použitie je realizované pomocou procesorových inštrukcií \verb|RDRAND| a \verb|RDSEED|. Práca s~inštrukciami vyžaduje znalosti nízko-úrovňových programovacích jazykov, akým je napríklad \textit{Asembler}\footnote{\url{https://en.wikipedia.org/wiki/Assembly\_language}.}. Tie nie sú v~dnešnej dobe veľmi populárne. Aj~dôsledkom toho výrobcovia procesorov sprístupňujú programátorom tzv. \textbf{programovateľné rozhrania -- API}. Štandardne sú~napísané pomocou vysoko-úrovňových jazykov\footnote{Jazyk C, Java, C Sharp a iné.}. Ich transformáciu do strojového kódu zabezpečuje prekladač. V~tejto súvislosti spomenieme dvoch výrobcov procesorových čipov s~najväčším zastúpením na~trhu -- \textbf{\acrshort{amd} a Intel}. Obe firmy sprístupnili používateľom svoje API v~programovacom jazyku C. Najpodstatnejším rozdielom pri~používaní je~vzájomná \textbf{kompatibilita}. Intel rozhranie poskytuje podporu iba pre~vlastné procesory, zatiaľ čo spoločnosť AMD uverejnila sadu, ktorá má~podporu aj~iných výrobcov procesorových čipov. Podmienkou úspešného generovania však ostáva potrebná implementácia inštrukcií \verb|RDRAND| a \verb|RDSEED|. Z~tohto dôvodu sme použili pri generovaní náhodných dát, pomocou vyššie spomenutých inštrukcií, práve riešenie firmy AMD. V súvislosti s inštrukčnými sadami, implementovanými na dnešných mikroprocesoroch, uvádzame dokument \cite{instruction}. Jeho obsahom sú špecifikácie inštrukcií, používaných na rôznych typoch procesorov. Dokument je pravidelne aktualizovaný a udržiavaný. \subsection{RDRAND a RDSEED} Inštrukcie vytvorila spoločnosť Intel. Ich vznik sa datuje do roku \textbf{2012}. Samotní autori (\cite{inteldrng}), odôvodnili implementáciu \acrshort{trng} v procesorových čipoch ako nutný bezpečnostný prvok, ktorý dokáže v~akejkoľvek situácii dodať kvalitné a skutočne náhodné dáta. Samozrejme, nezávislé od deterministických procesov bežiaceho softvéru. Inštrukcia RDSEED je implementáciou \acrshort{ndrng}. Na druhej strane RDRAND realizuje \acrshort{csprng}, ktorého zdrojom entropie je výstup RDSEED inštrukcie. Obidva uvedené typy \acrshort{rng} boli opísané v kapitole \ref{1} tejto práce. Proces generovania náhodných dát pomocou týchto príkazov je znázornený na~obrázku \ref{o:rdimplementacia}\footnote{\acrshort{mac} -- z ang. \textit{Message Authentication Code}.}$^,$\footnote{Prebraté z: \cite[kap. 3.1]{inteldrng}.}. \begin{figure}[!ht] \centering \includegraphics[width=.9\textwidth]{figures/dizajnrdinstrukcii} \caption{Implementácia procesorových inštrukcií RDRAND a RDSEED v procesoroch Intel\label{o:rdimplementacia}} \end{figure} Intel procesory používajú ako hardvérový zdroj entropie tepelný šum procesora pri~rýchlosti 3 GHz. Nepotrebujú žiaden externý zdroj napájania, pretože používajú rovnaký zdroj ako jadro, na ktorom generovanie prebieha. Podrobný opis aplikovaných metód v generátore je dostupný v dokumentácii \cite{inteldrng}. Podporu týchto inštrukcií doplnila aj spoločnosť AMD v roku 2015. Do svojich procesorov implementovali kryptografické ko-procesory. Architektúra je znázornená pomocou schémy \ref{amdrd}. Zdrojom entropie sú tzv. \textbf{kruhové oscilátory}\footnote{Z ang. \textit{Ring Oscillators}.}, ktoré počas behu ko-procesora neustále dodávajú náhodné dáta. Uvedené AMD ko-procesory používajú aj tzv. \acrshort{fifo} buffer \cite{fifo} na~zabezpečenie podpory rýchleho čítanie 32-bitových hodnôt\footnote{Z~ang. \textit{Bursts}.}. Viac podrobností o riešení sa nachádza v~\cite{amdapi}. \begin{figure}[!ht] \centering \includegraphics[width=.9\textwidth]{figures/amdrd} \caption{Kryptografické ko-procesory v AMD procesoroch\label{amdrd}} \end{figure} \subsubsection{AMD Secure RNG API \cite[str. 1-7]{amdapi}} Voľné dostupné rozhranie\footnote{\url{https://developer.amd.com/amd-aocl/rng-library/}.} v~programovacom jazyku C. Aktuálna verzia je 3.0.6 (15. 03. 2021), obsahuje celkovo 14 funkcií. Z~toho dve na kontrolu implementácie inštrukcií a~12 na vytváranie náhodných dát. Programátor má možnosť vygenerovať jedno 16/32/64-bitové číslo alebo ich dátovú štruktúru. Obdobne je k~dispozícii možnosť zvoliť si požadovanú veľkosť vygenerovaných dát v~bajtoch. Pri~našom testovaní sme implementovali možnosť generovania náhodných dát pomocou polí v jazyku C. Zdrojový kód, \ref{amd}, uvádza deklarácie spomenutých implementovaných funkcií. Pomenovania sú jednoznačné. Argument N označuje počet opakovaní a~\textit{retry\_count} udáva počet pokusov v~prípade zlyhania. Obsahom AMD balíka je aj zdrojový kód \textbf{secrng\_test.c}. Ten realizuje príklad použitia každého AMD rozhrania. \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, caption={Funkcie v AMD Secure RNG rozhraní}\label{amd}, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] int is_RDRAND_supported(); int get_rdrand16u(uint16_t* rng_val, unsigned int retry_count); int get_rdrand32u(uint32_t* rng_val, unsigned int retry_count); int get_rdrand64u(uint64_t* rng_val, unsigned int retry_count); int get_rdrand32u_arr(uint32_t* rng_val, unsigned int N, unsigned int retry_count); int get_rdrand64u_arr(uint64_t* rng_arr, unsigned int N, unsigned int retry_count); int get_rdrand_bytes_arr(unsigned char *rng_arr, unsigned int N, unsigned int retry_count); int is_RDRAND_supported(); int get_rdseed16u(uint16_t* rng_val, unsigned int retry_count); int get_rdseed32u(uint32_t* rng_val, unsigned int retry_count); int get_rdseed64u(uint64_t* rng_val, unsigned int retry_count); int get_rdseed32u_arr(uint32_t* rng_arr, unsigned int N, unsigned int retry_count); int get_rdseed64u_arr(uint64_t* rng_arr, unsigned int N, unsigned int retry_count); int get_rdseed_bytes_arr(unsigned char *rng_arr, unsigned int N, unsigned int retry_count); \end{lstlisting} \end{minipage}\\ \subsubsection{Výsledky experimentálnych meraní funkcií rozhrania AMD} Dosiahnuté namerané výsledky sú reprezentované formou tabuliek: \begin{itemize} \item \ref{rdrand} -- RDRAND a \item \ref{rdseed} -- RDSEED. \end{itemize} Jednotlivé označenia stĺpcov sú charakterizované v úvode tejto kapitoly (\ref{rng}). Zdrojový kód \verb|amdSPRNG.c| implementuje testované funkcie a je obsahom prílohy A. \begin{table}[!ht] \centering \resizebox{\textwidth}{!}{ \begin{tabular}{c|c|c|c|r|r|r|c|c} \multirow{2}{*}{\bfseries Počítač}&\multicolumn{8}{c}{ \bfseries Špecifikácie meraní} \\ & \bfseries $NI$ & \bfseries $BS$ & \bfseries $V_D$ & \multicolumn{1}{c|}{ANC} & \multicolumn{1}{c|}{ \bfseries $T_A$ [s] } & \multicolumn{1}{c|}{\bfseries $T_B$[s]} & \multicolumn{1}{c|}{\bfseries $\approx$ $P_A$ [MB/s]} & \multicolumn{1}{c}{\bfseries $\approx$ $P_B$ [MB/s]} \\\hline\hline \multirow{4}{*}{\bfseries A} & 1 024 & 16 kB & 16 MB & 5 628 973 & 1,991 472 & 1,953 684 & 8,034 & 8,190 \\ & 1 024 & 16 MB & 16 GB & 5 676 879 262 & 2 008,291 504 & 2 015,468 384 & 8,158 & 8,129 \\ & 1 024 & 32 MB & 32 GB & 11 354 590 480 & 4 016,876 709 & 4 050,146 973 & 8,158 & 8,091 \\ & 8 & ULONG\_MAX & 32 GB & 1 453 162 191 677 & 4 016,253 662 & 4 051,736 572 & 8,159 & 8,087 \\\hline \multirow{4}{*}{\bfseries B} & 1 024 & 16 kB & 16 MB & 6 241 786 & 3,551 908 & 3,639 144 & 4,505 & 4,397 \\ & 1 024 & 16 MB & 16 GB & 6 440 954 785 & 3 664,190 186 & 3 685,320 801 & 4,471 & 4,445 \\ & 1 024 & 32 MB & 32 GB & 12 897 904 573 & 7 337,478 516 & 7 486,955 566 & 4,466 & 4,377 \\ & 8 & ULONG\_MAX & 32 GB & 1 650 387 205 662 & 7 335,057 129 & 7 598,942 383 & 4,467 & 4,312 \\\hline \multirow{4}{*}{\bfseries C} & 1 024 & 16 kB & 16 MB & 4 805 709 & 2,330 819 & 2,351 972 & 6,865 & 8,803 \\ & 1 024 & 16 MB & 16 GB & 4 810 432 963 & 2 332,328 369 & 2 338,702 881 & 7,025 & 7,006 \\ & 1 024 & 32 MB & 32 GB & 9 617 320 340 & 4 662,936 523 & 4 707,775 879 & 7,029 & 6,960 \\ & 8 & ULONG\_MAX & 32 GB & 1 232 428 756 993 & 4 668,283 203 & 4 790,067 383 & 7,019 & 6,841 \\ \end{tabular} } \caption{Výsledky meraní funkcie get\_rand\_bytes\_arr}\label{rdrand} \end{table} \begin{table}[!ht] \centering \resizebox{\textwidth}{!}{ \begin{tabular}{c|c|c|c|r|r|r|c|c} \multirow{2}{*}{\bfseries Počítač }&\multicolumn{8}{c}{ \bfseries Špecifikácie meraní } \\ & \bfseries $NI$ & \bfseries $BS$ & \bfseries $V_D$ & \multicolumn{1}{c|}{ANC} & \multicolumn{1}{c|}{ \bfseries $T_A$ [s] } & \multicolumn{1}{c|}{\bfseries $T_B$[s]} & \multicolumn{1}{c|}{\bfseries $\approx$ $P_A$ [MB/s]} & \multicolumn{1}{c}{\bfseries $\approx$ $P_B$ [MB/s]} \\\hline\hline \multirow{4}{*}{\bfseries A} & 1 024 & 16 kB & 16 MB & 24 876 680 & 8,800 674 & 8,673 107 & 1,818 & 1,845 \\ & 1 024 & 16 MB & 16 GB & 25 529 272 494 & 9 031,408 203 & 8 902,758 789 & 1,814 & 1,840 \\ & 1 024 & 32 MB & 32 GB & 50 962 566 174 & 17 528,861 328 & 17 621,734 375 & 1,869 & 1,860 \\ & 8 & ULONG\_MAX & 32 GB & 6 374 627 781 381 & 17 618,212 891 & 18 180,208 984 & 1,860 & 1,802 \\\hline \multirow{4}{*}{\bfseries B} & 1 024 & 16 kB & 16 MB & 6 390 445 & 3,636 515 & 4,014 131 & 4,400 & 3,990 \\ & 1 024 & 16 MB & 16 GB & 6 447 545 248 & 3 667,939 209 & 3 675,636 963 & 4,467 & 4,457 \\ & 1024 & 32 MB & 32 GB & 13 112 239 637 & 7 459,411 621 & 7 479,892 578 & 4,393 & 4,381 \\ & 8 & ULONG\_MAX & 32 GB & 1 688 133 062 298 & 7 502,824 219 & 7 615,551 758 & 4,367 & 4,303 \\\hline \multirow{4}{*}{\bfseries C} & 1 024 & 16 kB & 16 MB & 4 811 400 & 2,333 592 & 2,367 678 & 6,856 & 6,758 \\ & 1 024 & 16 MB & 16 GB & 4 819 373 956 & 2 336,663 330 & 2 338,929 688 & 7,012 & 7,005 \\ & 1 024 & 32 MB & 32 GB & 9 615 872 296 & 4 662,234 375 & 4 706,395 508 & 7,028 & 6,962 \\ & 8 & ULONG\_MAX & 32 GB & 1 231 308 014 422 & 4 664,037 598 & 4 769,422 363 & 7,026 & 6,870 \\ \end{tabular} } \caption{Výsledky meraní funkcie get\_rdseed\_bytes\_arr}\label{rdseed} \end{table} \section{Rozhrania operačného systému Windows}\label{winapi} Používateľ má v aktuálnom \acrshort{os} Windows\footnote{Windows 10 Home -- 64-bit, verzia 20H2, zostava OS -- 19042.964.} prístup k trojici funkcií realizujúcich službu \acrshort{rng}\cite[str. 5]{win10rng}. \begin{itemize} \item \verb|RtlGenRandom| \cite{rtlgenrandom}, \item \verb|CryptGenRandom| \cite{crypt}, \item \verb|BCryptGenRandom| \cite{bcrypt}. \end{itemize} Vyššie uvedené realizujú generovanie náhodných čísel pomocou používateľského rozhrania -- \verb|ProcessPrng|. V prípade kernel režimu je vytváranie náhodných dát vykonané primárne pomocou \verb|SystemPrng| API. Tie boli spomenuté v \ref{access}. Obsahom tejto podkapitoly je opis týchto funkcií. Ten bol vytvorený na základe dokumentácií spoločnosti Microsoft \cite{rtlgenrandom}, \cite{crypt}, \cite{bcrypt}. \subsection{RtlGenRandom} \label{rtl} Funkcia je deklarovaná v hlavičkovom súbore \textbf{ntsecapi.h}, ale nemá knižnicu, ktorá ju vykonáva. Slúži na generovanie pseudonáhodných čísel. Pomocou makra je definovaná ako \verb|SystemFunction036| a až táto je realizovaná v dynamickej knižnici \textbf{Advapi32.dll}. Pri použití je teda potrebné načítať tento modul. V súčasnosti je tento krok automatizovaný. Generovanie je realizované použitím rozhrania \textbf{ProcessPrng}. Microsoft však odporúča namiesto používania tejto funkcie použitie \verb|CryptGenRandom|. \subsubsection{Špecifikácia funkcie RtlGenRandom \cite{rtlgenrandom}} \verb|RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);| \begin{enumerate} \item \verb|PVOID RandomBuffer| -- adresa premennej na uloženie náhodnosti. \item \verb|ULONG RandomBufferLength| -- veľkosť prvého parametra (max. \verb|ULONG_MAX|). \end{enumerate} Funkcia je typu \verb|boolean|. Teda návratové hodnoty sú \verb|TRUE/FALSE| pri úspechu, resp. neúspechu generovania. Príkladom použitia je zdrojový kód \ref{rtlgr}. Tento demo príklad je súčasťou prílohy A. Nachádza sa v priečinku \textit{DemoExamples}. \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, caption={Príklad použitia funkcie RtllGenRandom}, label={rtlgr}, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] #include #include // for variable types definition #include // declaration RtlGenRandom() int main(){ BYTE *pbData=(BYTE*)malloc(sizeof(BYTE) * 10); if(RtlGenRandom(pbData,10) == TRUE){ for (int i = 0; i < 10; i++){ printf("%u",pbData[i]); } free(pbData); return 0; } free(pbData); return -1; } \end{lstlisting} \end{minipage}\\ \subsubsection{Výsledky experimentálnych meraní} Dosiahnuté výsledky meraní sú znázornené pomocou tabuľky \ref{rtlexp}. \begin{table}[!ht] \centering \resizebox{\textwidth}{!}{ \begin{tabular}{c|c|c|c|r|r|r|c|c} \multirow{2}{*}{\bfseries Počítač}&\multicolumn{8}{c}{ \bfseries Špecifikácie meraní} \\ & \bfseries $NI$ & \bfseries $BS$ & \bfseries $V_D$ & \multicolumn{1}{c|}{ANC} & \multicolumn{1}{c|}{ \bfseries $T_A$ [s] } & \multicolumn{1}{c|}{\bfseries $T_B$[s]} & \multicolumn{1}{c|}{\bfseries $\approx$ $P_A$ [MB/s]} & \multicolumn{1}{c}{\bfseries $\approx$ $P_B$ [MB/s]} \\\hline\hline \multirow{4}{*}{\bfseries A} & 1 024 & 16 kB & 16 MB & 15 074 & 0,005 451 & 0,020 702 & 2 935,241 & 772,872 \\ & 1 024 & 16 MB & 16 GB & 16 907 537 & 5,982 000 & 166,227 746 & 2 738,883 & 98,564 \\ & 1 024 & 32 MB & 32 GB & 33 698 517 & 11,922 174 & 524,159 006 & 2 758,492 & 62,515 \\ & 8 & ULONG\_MAX & 32 GB & 4 489 111 941 & 12,407 025 & 500,792 203 & 2 641,084 & 65,432 \\\hline \multirow{4}{*}{\bfseries B} & 1 024 & 16 kB & 16 MB & 10 580 & 0.006 771 & 0.021 564 & 2 363,019 & 741,977 \\ & 1 024 & 16 MB & 16 GB & 14 072 032 & 8,006 607 & 136,472 897 & 2 046,310 & 120,053 \\ & 1 024 & 32 MB & 32 GB & 29 400 765 & 16,726 991 & 984,013 108 & 1 958,990 & 33,300 \\ & 8 & ULONG\_MAX & 32 GB & 3 940 128 574 & 17,511 696 & 275,192 794 & 1 871,207 & 119,073 \\\hline \multirow{4}{*}{\bfseries C} & 1 024 & 16 kB & 16 MB & 14 630 & 0,007 994 & 0,024 424 & 2 001,501 & 655,093 \\ & 1 024 & 16 MB & 16 GB & 11 823 989 & 5,733 827 & 217,114 585 & 2 857,428 & 75,462 \\ & 1 024 & 32 MB & 32 GB & 23 913 126 & 11,595 265 & 513,567 815 & 2 825,981 & 63,805 \\ & 8 & ULONG\_MAX & 32 GB & 3 347 779 853 & 12,680 974 & 561,609 795 & 2 584,029 & 58,347 \\ \end{tabular} } \caption{Výsledky meraní funkcie RtlGenRandom}\label{rtlexp} \end{table} \subsection{CryptGenRandom} Funkcia na generovanie kryptograficky bezpečných náhodných dát. Vznikla pri prvom riešení kryptografického rozhrania -- CAPI. \textbf{Zastaraná}, ale zatiaľ podporovaná aj v súčasnom CNG. Microsoft však \textbf{neodporúča} jej používanie z dôvodu možného odstránenia v~budúcnosti. Jej deklarácia je obsahom hlavičkového súboru \textbf{wincrypt.h}. Realizuje ju dynamická knižnica \textbf{Advapi32.dll}. Následne je použitý modul \textbf{brcyptprimitives.dll}. \subsubsection{Špecifikácia funkcie CryptGenRandom \cite{crypt}} \verb|CryptGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer);| \begin{enumerate} \item \verb|HCRYPTPROV hProv|\footnote{Nutná inicializácia tejto premennej.} -- opis \acrshort{csp}\footnote{Opísané v \ref{cryptoapi}.}, vytvorený funkciou \verb|CryptAcquireContext|, \item \verb|DWORD dwLen| -- veľkosť výstupu (max. \verb|ULONG_MAX|), \item \verb|BYTE *pbBuffer| -- adresa úložiska, veľkosť musí byť najmenej \verb|dwLen|. \end{enumerate} Funkcia \verb|CryptGenRandom| je typu \verb|BOOL|. Návratová hodnota je \verb|TRUE|, resp. \verb|FALSE|. V~prípade zlyhania je dôvod zapísaný do \acrshort{csp} premennej \verb|hProv|. \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, caption={Príklad použitia funkcie CryptGenRandom},label={crypt}, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] #include #include int main(){ HCRYPTPROV hCryptProv; BYTE *pbData=(BYTE*)malloc(sizeof(BYTE)* 10); CryptAcquireContext(&hCryptProv,NULL, "Microsoft Base Cryptographic Provider v1.0", PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); if(CryptGenRandom(hCryptProv,10,pbData)!=0){ printf("Random sequence generated. \n"); } else { printf("Error during CryptGenRandom.\n"); free(pbData); return -1; } free(pbData); return 0; } \end{lstlisting} \end{minipage}\\ \subsubsection{Výsledky experimentálnych meraní funkcie CryptGenRandom} Výsledky experimentov funkcie \verb|CryptGenRandom| znázorňuje tabuľka \ref{cryptexp}. Zdrojové kódy \verb|winAPIprng.c| a ukážka \ref{crypt} implementujú túto funkciu a sú obsahom prílohy A. \begin{table}[h!] \centering \resizebox{\textwidth}{!}{ \begin{tabular}{c|c|c|c|r|r|r|c|c} \multirow{2}{*}{\bfseries Počítač}&\multicolumn{8}{c}{ \bfseries Špecifikácie meraní} \\ & \bfseries $NI$ & \bfseries $BS$ & \bfseries $V_D$ & \multicolumn{1}{c|}{ANC} & \multicolumn{1}{c|}{ \bfseries $T_A$ [s] } & \multicolumn{1}{c|}{\bfseries $T_B$[s]} & \multicolumn{1}{c|}{\bfseries $\approx$ $P_A$ [MB/s]} & \multicolumn{1}{c}{\bfseries $\approx$ $P_B$ [MB/s]} \\\hline\hline \multirow{4}{*}{\bfseries A} & 1 024 & 16 kB & 16 MB & 14 242 & 0,006 430 & 0,022 011 & 2 488,336 & 726,909 \\ & 1 024 & 16 MB & 16 GB & 16 991 496 & 6,013 020 & 143,722 924 & 2 724,754 & 113,997 \\ & 1 024 & 32 MB & 32 GB & 33795736 & 11,957515 & 480,253462 & 2 740,369 & 68,231 \\ & 8 & ULONG\_MAX & 32 GB & 4 525 421 725 & 12,508601 & 452,834846 & 2 619,637 & 72,362 \\\hline \multirow{4}{*}{\bfseries B} & 1 024 & 16 kB & 16 MB & 10 545 & 0,008 252 & 0,021 986 & 1 938,924 & 727,736 \\ & 1 024 & 16 MB & 16 GB & 14 174 624 & 8,066 505 & 120,477 247 & 2 031,115 & 135,992 \\ & 1 024 & 32 MB & 32 GB & 29 485 483 & 16,776 389 & 982,773 749 & 1 953,221 & 33,342 \\ & 8 & ULONG\_MAX & 32 GB & 3 969 183 958 & 17,642 095 & 283,746 065 & 1 857,376 & 115,484 \\\hline \multirow{4}{*}{\bfseries C} & 1 024 & 16 kB & 16 MB & 10 884 & 0.007 010 & 0.024 739 & 2 282,454 & 646,752 \\ & 1 024 & 16 MB & 16 GB & 11 819 580 & 5,733 101 & 213,303 019 & 2 857,790 & 76,811 \\ & 1 024 & 32 MB & 32 GB & 23 865 849 & 11,573 146 & 509,545 807 & 2 831,382 & 64,308 \\ & 8 & ULONG\_MAX & 32 GB & 5 285 174 011 & 20,022 825 & 561,612 424 & 1 636,532 & 58,346 \\ \end{tabular} } \caption{Výsledky meraní funkcie CryptGenRandom}\label{cryptexp} \end{table} \subsection{BCryptGenRandom} Implementácia služby generovania náhodných čísel v~druhej verzii kryptografického rozhrania. Ako jediná z uvedených je navrhnutá na použitie v používateľskom aj kernel režime. \textbf{Deklarácia} je uvedená v hlavičkovom súbore \textbf{bcrypt.h}. Funkcia je následne vykonaná pomocou \textbf{bcrypt.dll}. Knižnicu je potrebné pri kompilácií programu prilinkovať. Tento úkon realizujeme pomocou prepínača \verb| -lbcrypt|. \subsubsection{Špecifikácia funkcie BCryptGenRandom\cite{bcrypt}} \verb|BCryptGenRandom(BCRYPT_ALG_HANDLE hAlgorithm, PUCHAR pbBuffer,|\\ \verb|ULONG cbBuffer, ULONG dwFlags);| \begin{enumerate} \item\verb|BCRYPT_ALG_HANDLE hAlgorithm| -- opis algoritmu \acrshort{csp}. Vytvára sa použitím funkcie \verb| BCryptOpenAlgorithmProvider|. Tú však nie je nutné inicializovať. Pri použití makra \verb|NULL| sa použije predvolený poskytovateľ\footnote{Microsoft Cryptographic Service Provider.}, ktorý poskytuje služby generovania náhodných čísel. \item\verb|PUCHAR pbBuffer| -- adresa úložiska dát. Veľkosť musí byť najmenej cbBuffer. \item\verb|ULONG cbBuffer| -- veľkosť vygenerovaných dát (max. \verb|ULONG_MAX|). \item\verb|ULONG dwFlags| -- prepínač na modifikovanie správania funkcie. \end{enumerate} Parameter \verb|dvFlags| môže nadobúdať hodnoty: \begin{itemize} \item nula -- je nutné inicializovať \acrshort{csp}, \item \verb|BCRYPT_RNG_USE_ENTROPY_IN_BUFFER|\footnote{ Od verzie Windows 8 a vyššie je ignorovaný.} -- obsah dát v pbBuffer sa použije ako dodatočný zdroj entropie. \item \verb|BCRYPT_USE_SYSTEM_PREFERRED_RNG|\footnote{Windows Vista nepodporuje tento prepínač.} -- v prípade, že \acrshort{csp} je rovný NULL, volíme tento parameter. \end{itemize} Funkcia \verb|BCryptGenRandom| je typu \verb|NTSTATUS|. Návratové hodnoty môžu byť \verb|STATUS_SUCCESS|, \verb|STATUS_INVALID_HANDLE| a \verb|STATUS_INVALID_PARAMETER|. \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, caption={Príklad použitia funkcie BCryptGenRandom},label=bcrypt, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] #include #include #include int main(){ BYTE *pbData=(BYTE*)malloc(sizeof(BYTE)* 10); if (STATUS_SUCCESS!=BCryptGenRandom(NULL,pbData,10, BCRYPT_USE_SYSTEM_PREFERRED_RNG)) printf("BCryptGenRandom error.\n"); else printf("Random sequence generated.\n"); free(pbData); return 0; } \end{lstlisting} \end{minipage}\\ \subsubsection{Výsledky experimentálnych meraní funkcie BCryptGenRandom} Výsledky meraní funkcie sú znázornené pomocou tabuľky \ref{bcryptexp}. Programy použité pri experimentoch sú obsahom prílohy A, spoločne so zdrojovým kódom \ref{bcrypt} a implementáciou Windows rozhraní (\verb|winAPIprng.c|). \begin{table}[!ht] \centering \resizebox{\textwidth}{!}{ \begin{tabular}{c|c|c|c|r|r|r|c|c} \multirow{2}{*}{\bfseries Počítač}&\multicolumn{8}{c}{ \bfseries Špecifikácie meraní} \\ & \bfseries $NI$ & \bfseries $BS$ & \bfseries $V_D$ & \multicolumn{1}{c|}{ANC} & \multicolumn{1}{c|}{ \bfseries $T_A$ [s] } & \multicolumn{1}{c|}{\bfseries $T_B$[s]} & \multicolumn{1}{c|}{\bfseries $\approx$ $P_A$ [MB/s]} & \multicolumn{1}{c}{\bfseries $\approx$ $P_B$ [MB/s]} \\\hline\hline \multirow{4}{*}{\bfseries A} & 1 024 & 16 kB & 16 MB & 15 376 & 0,005 560 & 0,020 745 & 2 877,698 & 771,270 \\ & 1 024 & 16 MB & 16 GB & 16 905 128 & 5,981 131 & 236,919 392 & 2 739,281 & 69,154 \\ & 1 024 & 32 MB & 32 GB & 33 805 640 & 11,960 016 & 506,876 314 & 2 739,796 & 64,647 \\ & 8 & ULONG\_MAX & 32 GB & 4 538 998 240 & 12,544 902 & 568,900 696 & 2 612,057 & 57,599 \\\hline \multirow{4}{*}{\bfseries B} & 1 024 & 16 kB & 16 MB & 11 011 & 0,007 250 & 0,066 015 & 2 206,897 & 242,369 \\ & 1 024 & 16 MB & 16 GB & 14 093 652 & 8,018 871 & 117,026 229 & 2 043,180 & 140,003 \\ & 1 024 & 32 MB & 32 GB & 29 396 766 & 16,724 702 & 845,170 274 & 1 959,257 & 38,771 \\ & 8 & ULONG\_MAX & 32 GB & 3 951 000 676 & 17,560 018 & 252,854 179 & 1 866,057 & 129,592 \\\hline \multirow{4}{*}{\bfseries C} & 1024 & 16 kB & 16 MB & 10 912 & 0,005 963 & 0,025 895 & 2 683,213 & 617,880 \\ & 1 024 & 16 MB & 16 GB & 11 825 926 & 5,734 744 & 102,225 511 & 2 856,971 & 160,273 \\ & 1 024 & 32 MB & 32 GB & 23 915 195 & 11,596 222 & 437,033 046 & 2 825,748 & 74,978 \\ & 8 & ULONG\_MAX & 32 GB & 3 346 909 253 & 12,677 676 & 591,363 044 & 2 584,701 & 55,411 \\ \end{tabular} } \caption{Výsledky meraní funkcie BCryptGenRandom }\label{bcryptexp} \end{table} \section{Rozhrania na generovanie náhodných čísel v jazyku C a knižnici OpenSSL} Používateľ pracujúci na platforme Windows môže okrem softvérových riešení OS použiť aj implementácie rôznych knižníc. Uvedenou metódou môžeme vytvoriť aplikáciu, resp. službu, nezávislú od operačného systému. Tzv. \textbf{muti-platformové programy}. V~tejto kapitole demonštrujeme vyššie opísaný postup. Použijeme štandardné knižničné rozhrania jazyka C\footnote{Funkcie \textbf{\textit{rand, srand}} a \textbf{\textit{rand\_s}}.} a celosvetovo známu kryptografickú knižnicu -- OpenSSL\footnote{Funkcie \textbf{\textit{RAND\_bytes}} a \textbf{\textit{RAND\_priv\_bytes}}.} \cite{osslweb}. Zdrojové kódy v tejto podkapitoly sú obsahom prílohy A. \subsection{rand() a srand()} Funkcia \verb|rand()| je zrejme najznámejšou funkciou na generovanie pseudonáhodných výstupov, s ktorou sa používateľ stretne. Vo väčšine prípadov je implementáciou lineárne kongruentného generátora. Jeho inicializačná hodnota sa mení pomocou funkcie \verb|srand()|. Pri tejto metóde je teda nutnosťou kooperácia týchto funkcií. Ak by sme neurčili seed generátora, výstup by bol vždy rovnaký\footnote{Rovný \textbf{\textit{srand(1)}}.}. Výstupom funkcie je hodnota z číselnej množiny prvkov 0 až 32767. Použitie rozhrania na kryptografické účely sa \textbf{neodporúča}. Z toho dôvodu nevykonáme testovanie tohto rozhrania. Príkladom použitia je zdrojový kód \ref{srand}. \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, caption={Príklad použitia funkcie rand a srand}, label=srand, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] #include #include int main () { time_t t; /* Intializes random number generator */ srand((unsigned) time(&t)); /* Print random numbers from 0 to 32767 */ printf("%d\n", rand()); return(0); } \end{lstlisting} \end{minipage}\\ Viac informácia čitateľ nájde v \cite{crand}. \subsection{rand\_s} Funkcia \verb|rand_s|\footnote{Kompatibilné iba s OS Windows.} je vylepšením rozhrania \verb|rand|. Výstupom sú \textbf{pseudonáhodné} dáta v~rozmedzí od 0 až \verb|UINT_MAX|\footnote{\textbf{\textit{UINT\_MAX}} = \textbf{\textit{ULONG\_MAX}} = 4 294 967 295.}. Minimálna a zároveň aj maximálna veľkosť generovaných dát pri jednom volaní funkcie je 32 bitov (\verb|u_int|). Funkcia používa operačný systém, aby vygenerovala kryptograficky bezpečné náhodné dáta. Nepotrebuje \verb|srand()| funkciu. \subsubsection{Špecifikácia funkcie rand\_s} \verb|rand_s(unsigned int* randomValue);|\\ Funkcia používa jeden vstupný parameter. Ním je adresa na uloženie náhodnosti. Premenná musí byť typu \verb|unsigned int|. \verb|Rand_s| je typu \verb|errno_t|. Návratové hodnoty sú \textbf{nula} pri úspechu alebo chybový kód pri zlyhaní. Príkladom použitia je zdrojový kód \ref{rands}, ktorý je obsahom priečinku \textit{DemoExamples} v Prílohe A. Obdobne je funkcia implementovaná v \verb|winAPIprng.c|. \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, caption={Príklad použitia funkcie rand\_s}, label=rands, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] #include #define _CRT_RAND_S #include int main () { unsigned int data; //generating 10*32bit value for (int i = 0; i < 10 ; i++) if(rand_s(&data)==0) printf("%u\n",data); else printf("Rand_s error\n"); return 0; } \end{lstlisting} \end{minipage}\\ Pred použitím je nutné definovať makro \verb|_CRT_RAND_S| pred linkovaním knižnice \textbf{stdlib.h}. Tým je zabezpečená deklarácia \verb|rand_s|. Pri skúmaní dokumentácie sme zistili, že \textbf{používa rozhranie} \verb|RtlGenRandom|, konkrétne makro \verb|SystemFunction036|. Uvedená funkcia je obsahom podkapitoly \ref{rtl}. \subsubsection{Výsledky experimentálnych meraní funkcie rand\_s} Výsledky dosiahnuté pri meraní tejto funkcie sú znázornené pomocou tabuľky \ref{rnds}. Programy spoločne s výsledkami, na základe ktorých táto tabuľka vznikla, sú obsahom prílohy A. \begin{table}[!ht] \centering \resizebox{\textwidth}{!}{ \begin{tabular}{c|c|c|c|r|r|r|c|c} \multirow{2}{*}{\bfseries Počítač}&\multicolumn{8}{c}{ \bfseries Špecifikácie meraní} \\ & \bfseries $NI$ & \bfseries $BS$ & \bfseries $V_D$ & \multicolumn{1}{c|}{ANC} & \multicolumn{1}{c|}{ \bfseries $T_A$ [s] } & \multicolumn{1}{c|}{\bfseries $T_B$[s]} & \multicolumn{1}{c|}{\bfseries $\approx$ $P_A$ [MB/s]} & \multicolumn{1}{c}{\bfseries $\approx$ $P_B$ [MB/s]} \\\hline\hline \multirow{4}{*}{\bfseries A} & 4 194 304 & 32 b & 16 MB & 767 988 443 354 161 & 0,505 931 & 0,555 474 & 31,625 & 28,804 \\ & 4 294 967 296 & 32 b & 16 GB & 768 430 967 898 097 & 513,802 964 & 562,708 093 & 31,888 & 29,116 \\ & 8 589 934 592 & 32 b & 32 GB & 768 535 482 013 732 & 1 025,192 557 & 1 166,065 347 & 31,963 & 28,101 \\\hline \multirow{4}{*}{\bfseries B} & 4 194 304 & 32 b & 16 MB & 15 547 492 712 804 349 & 4,381 201 & 4,313 881 & 3,652 & 3,709 \\ & 4 294 967 296 & 32 b & 16 GB & 5 446 628 539 601 029 & 4 481,040 633 & 4 521,708 060 & 3,656 & 3,623 \\ & 8 589 934 592 & 32 b & 32 GB & 5 447 757 045 127 528 & 8 955,748 443 & 9 164,667 793 & 3,659 & 3,575 \\\hline \multirow{4}{*}{\bfseries C} & 4 194 304 & 32 b & 16 MB & 1 729 007 496 224 506 & 5,719 874 & 3,098 462 & 2,797 & 5,164 \\ & 4 294 967 296 & 32 b & 16 GB & 690 952 124 931 332 & 4 147,831 673 & 3 149,553 623 & 3,950 & 5,202 \\ & 8 589 934 592 & 32 b & 32 GB & 689 962 359 510 427 & 6 229,372 939 & 11 885,556 796 & 5,260 & 2,757 \\ \end{tabular} } \caption{Výsledky meraní funkcie rand\_s }\label{rnds} \end{table} \subsection{Kryptografická knižnica OpenSSL} OpenSSL \cite{osslweb} je široko použiteľná a modifikovateľná knižnica, určená pre~kryptografické aplikácie. Jej obsahom sú kvalitné a udržiavané algoritmy. Obdobne obsahuje aj funkcie, ktorých úlohou je generovanie kryptograficky bezpečných náhodných dát. Podľa dokumentácie \cite{openssl} je ich implementácia skonštruovaná podľa odporúčania \cite{book}, teda knižnica \textbf{používa} na generovanie čísel \textbf{AES256-DRBG v čítačovom režime}. Ekvivalentná bezpečnosť výstupov je teda na úrovni 256 bitov. \subsubsection{Špecifikácia RNG funkcií v knižnici OpenSSL\cite[kap. 5]{ossltechreport}} V tejto práci budeme pracovať s OpenSSL verzia 1.1.1k (25. 03. 2021). Predvolený generátor sa inicializuje pri spustení a automaticky vykonáva reseed-ovanie. Pri tomto procese používa dôveryhodné zdroje daného operačného systému. V~prípade \acrshort{os} Windows nimi sú výstupy funkcie \verb|BCryptGenRandom| a \verb|CryptGenRandom|. Tie sú opísané v podkapitole \ref{winapi} Prístup k \acrshort{csprng} sprostredkúva dvojica funkcií: \begin{itemize} \item \verb|int RAND_bytes(unsigned char * buf, int num)|, \item \verb|int RAND_priv_bytes(unsigned char * buf, int num)|. \end{itemize} Obidve sú deklarované v \textbf{rand.h} a poskytujú výstup z rovnakého \acrshort{csprng}. Druhá z uvedených funkcií používa unikátnu inštanciu generátora. Odporúča sa ju používať pri tvorbe citlivých dát. Napríklad pri procese generovania kľúčov. Ukážku jednoduchého použitia v jazyku C znázorňuje zdrojový kód \ref{openssl}. Viac informácií o metódach RNG rozhraní je možne nájsť v riporte \cite[kap. 5]{ossltechreport} \noindent \begin{minipage}{\linewidth} %\section{Výpis kódu jazyka C} \begin{lstlisting}[frame=single, numbers=left, caption={Príklad použitia RNG funkcií knižnice OpenSSL},label=openssl, basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] #include #include int main(){ unsigned char * data =(unsigned char*)malloc( sizeof(unsigned char)*10); if(RAND_bytes(data,10)) for (int i = 0; i < 10; i++) printf("%u", data[i]); else printf("RAND_bytes error\n"); printf("\n"); if (RAND_priv_bytes(data,10)) for (int i = 0; i < 10; i++) printf("%u", data[i]); else printf("RAND_priv_bytes error\n"); free(data); return 0; } \end{lstlisting} \end{minipage}\\ \subsubsection{Výsledky experimentálnych meraní} Aj napriek faktu, že knižnica čerpá zdroj náhodnosti z rozhraní operačného systému Windows, sme sa rozhodli aplikovať naše testovacie metódy na funkcie v OpenSSL. Dôvodom je vysoká miera používania v bežnej prevádzke. Prehľad nameraných hodnôt pri časovom meraní znázorňujú tabuľky č.: \begin{itemize} \item \ref{ossltable1} -- funkcia \verb|RAND_bytes|, \item \ref{ossltable2} -- funkcia \verb|RAND_priv_bytes|. \end{itemize} Funkcie sú implementované v súbore \verb|openssl_rng.c|. Spoločne s ukážkou \ref{openssl}, sú obsahom prílohy A. \begin{table}[!ht] \centering \resizebox{\textwidth}{!}{ \begin{tabular}{c|c|c|c|r|r|r|c|c} \multirow{2}{*}{\bfseries Počítač}&\multicolumn{8}{c}{ \bfseries Špecifikácie meraní} \\ & \bfseries $NI$ & \bfseries $BS$ & \bfseries $V_D$ & \multicolumn{1}{c|}{ANC} & \multicolumn{1}{c|}{ \bfseries $T_A$ [s] } & \multicolumn{1}{c|}{\bfseries $T_B$[s]} & \multicolumn{1}{c|}{\bfseries $\approx$ $P_A$ [MB/s]} & \multicolumn{1}{c}{\bfseries $\approx$ $P_B$ [MB/s]} \\\hline\hline \multirow{4}{*}{\bfseries A} & 1 024 & 16 kB & 16 MB & 12 700 & 0,008 139 & 0,022 769 & 1 965,843 & 702,710 \\ & 1024 & 16 MB & 16 GB & 12 371 900 & 7,039 314 & 114,814 303 & 2 327,500 & 142,700 \\ & 1 024 & 32 MB & 32 GB & 23 384 922 & 13,304 316 & 806,312 717 & 2 462,960 & 40,640 \\ & 16 & INT\_MAX & 32 GB & 1 662 721 364 & 9,190 874 & 814,555 646 & 3 565,276 & 40,228 \\\hline \multirow{4}{*}{\bfseries B} & 1 024 & 16 kB & 16 MB & 12 700 & 0,008 139 & 0,022 769 & 1 965,843 & 702,710 \\ & 1 024 & 16 MB & 16 GB & 12 371 900 & 7,039 314 & 114,814 303 & 2 327,500 & 142,700 \\ & 1 024 & 32 MB & 32 GB & 23 384 922 & 13,304 316 & 806,312 717 & 2 462,960 & 40,639 \\ & 16 & INT\_MAX & 32 GB & 2 079 574 215 & 18,485 125 & 252,108 430 & 1 772,669 & 129,976 \\\hline \multirow{4}{*}{\bfseries C} & 1 024 & 16 kB & 16 MB & 14 043 & 0,007 516 & 0,021 354 & 2 128,792 & 749, 274 \\ & 1 024 & 16 MB & 16 GB & 10 805 372 & 5,239 904 & 232,817 471 & 3 126,775 & 70,373 \\ & 1 024 & 32 MB & 32 GB & 21 915 623 & 10,626 684 & 517,460 051 & 3 083,558 & 63,325 \\ & 16 & INT\_MAX & 32 GB & 1 515 908 023 & 11,484 146 & 564,056 276 & 2 853,325 & 58,093 \\ \end{tabular} } \caption{Výsledky meraní funkcie RAND\_bytes }\label{ossltable1} \end{table} \begin{table}[!ht] \centering \resizebox{\textwidth}{!}{ \begin{tabular}{c|c|c|c|r|r|r|r|r} \multirow{2}{*}{\bfseries Počítač}&\multicolumn{8}{c}{ \bfseries Špecifikácie meraní} \\ & \bfseries $NI$ & \bfseries $BS$ & \bfseries $V_D$ & \multicolumn{1}{c|}{ANC} & \multicolumn{1}{c|}{ \bfseries $T_A$ [s] } & \multicolumn{1}{c|}{\bfseries $T_B$[s]} & \multicolumn{1}{c|}{\bfseries $\approx$ $P_A$ [MB/s]} & \multicolumn{1}{c}{\bfseries $\approx$ $P_B$ [MB/s]} \\\hline\hline \multirow{4}{*}{\bfseries A} & 1 024 & 16 kB & 16 MB & 16 877 & 0,006 082 & 0,005 921 & 2 630,714 & 2 702,246 \\ & 1 024 & 16 MB & 16 GB & 12 359 089 &4,372 758 & 255,915 867 & 3 746,834 & 64,021 \\ & 1 024 & 32 MB & 32 GB & 24 664 863 & 8,726 003 & 650,850 067 & 3 755,213 & 50,346 \\ & 16 & INT\_MAX & 32 GB & 1 261 401 535 & 6,972 535 & 436,126 318 & 4 699,582 & 75,134 \\\hline \multirow{4}{*}{\bfseries B} & 1 024 & 16 kB & 16 MB & 12 676 & 0,007 968 & 0,008 675 & 2 008,032 & 1 844,380 \\ & 1 024 & 16 MB & 16 GB & 12 450 851 & 7,084 268 & 116,442 791 & 2 312,730 & 140,704 \\ & 1024 & 32 MB & 32 GB & 23 206 632 & 13,202 893 & 1 006,623 945 & 2 481,880 & 32,552 \\ & 16 & INT\_MAX & 32 GB & 1 566 820 326 & 13,927 308 & 279,844 212 & 2 352,788 & 117,094 \\\hline \multirow{4}{*}{\bfseries C} & 1 024 & 16 kB & 16 MB & 13 622 & 0,007 342 & 0,007 162 & 2 179,243 & 2 234,013 \\ & 1 024 & 16 MB & 16 GB & 10 483 219 & 5,083 700 & 217,651 658 & 3 222,849 & 75,276 \\ & 1 024 & 32 MB & 32 GB & 21 078 845 & 10,220 949 & 514,842 818 & 3 205,965 & 63,647 \\ & 16 & INT\_MAX & 32 GB & 2 431 597 459 & 18,421 180 & 613,641 577 & 1 778,822 & 53,399 \\ \end{tabular} } \caption{Výsledky meraní funkcie RAND\_priv\_bytes }\label{ossltable2} \end{table}