Tu sú vecné/logické chyby a nepresnosti v texte (stručne, podľa tém):
1. Popletené príznaky CPU
Autor dvakrát nazýva CF „príznakom pretečenia“. CF je carry flag, pretečenie je OF. To je faktická chyba pri popise stavových príznakov x86.
2. Správanie RDRAND pri zlyhaní
Text tvrdí, že „ak inštrukcia neprebehne, register sa vynuluje a CF=0“. Architektúra x86 uvádza: CF=0 znamená, že sa nevrátila platná hodnota; obsah cieľového registra je nedefinovaný (nie garantovane nulový).
Ak procesor inštrukciu nepodporuje, nedeje sa „vynulovanie“ – vyvolá sa #UD (invalid opcode). Preto je zle miešať „neúspech kvôli nedostupným dátam“ s „nepodporovanou inštrukciou“.
3. Mylné tvrdenie o „reštarte po 511 cykloch“
Pasáž „generátor je vždy po maximálne 511 cykloch reštartovaný“ je nesprávna. Intel DRNG používa CTR-DRBG, ktorý sa periodicky reseeduje podľa počtu vygenerovaných hodnôt, nie „taktovacích cyklov CPU“. Číslo 511/512 sa vzťahuje na počet výstupov (blokov) medzi reseedmi, nie cykly.
4. „Jediný senzor tepelného šumu“ a „zdieľanie medzi všetkými jadrami“
Text kategoricky tvrdí, že je k dispozícii iba jediný senzor a ten sa delí medzi všetky jadrá, preto je RDSEED „pomalý“. Intel dokumentácia popisuje viacstupňový hardvérový entropický reťazec a kondicionovanie; implementačné detaily (počet senzorov, per-core/per-package) nie sú takto zjednodušene garantované. Toto je prinajmenšom nepodložené zovšeobecnenie.
5. „RDSEED vracia skutočne náhodné bity“
Presnejšie: RDSEED vracia kondicionované full-entropy (FIPS/NIST) bity z hardvérového zdroja (po prechode cez kondicionér). Nazývať to bez kvalifikácie „skutočne náhodné“ je terminologicky nepresné; ide o výstup po kryptografickom spracovaní entropie.
6. Detekcia a reakcia na nepodporované inštrukcie
Časť o CPUID je OK (RDRAND = leaf 1 ECX bit 30), ale text neskôr naznačuje, že „ak nie je podporovaná“, jednoducho sa vráti nula/CF=0. Správne: ak sa pokúsite vykonať nepodporovanú inštrukciu bez kontroly CPUID, dostanete #UD.
7. GCC builtins a prepínače
Autor tvrdí, že je nutné -mrdrnd, inak builtins neexistujú. V praxi stačí aj -march=… s RDRAND (alebo cieľ so zahrnutou inštrukciou); -mrdrnd je jedna z ciest, nie jediná. Formulácia je príliš kategorická.
8. Nesúlad „sekvencia bude vždy iná“
„Prakticky isté, že nikdy nezískate rovnakú sekvenciu“ je prehnané. Pravdepodobnosť duplicity je zanedbateľná, nie nulová. Ide o logické zveličenie.
9. Nesúlad názvov/typos
Viackrát sa objaví preklep RDRND namiesto RDRAND.
V kap. 16 sa testuje súbor random.bit, no predtým sa generoval random.bin. To je nekonzistentné.
10. Chyby/nekorektnosti v ukážkovej ASM
id_string: resb 8, no následne sa ukladá 12 bajtov (EBX, EDX, ECX) a tlačí sa 12 znakov buffer overflow.
V poznámkach sa CF opäť volá „príznak pretečenia“.
V časti s LOOP je síce upozornené na modifikáciu ECX a použitie push/pop, to je správne; inak OK.
11. Kódovanie inštrukcie a tabuľka
Tabuľka uvádza „NFx 0F C7 /6“ – označenie NFx nie je štandardná notácia; nepôsobí ako vecná chyba, ale mätie.
12. Zámena „assembler“ vs. „vyššie jazyky“ pri RDRAND/privilegiách
Veta „ak je podporovaná, malo by byť volanie úspešné (nevyžaduje privilégiá)“ je správna, ale následné zovšeobecnenie, že „ak prebehne v poriadku, CF=1; v opačnom prípade register vynulovaný“ je (opäť) nesprávne – viď body 2 a 3.
13. Randomness testy – interpretácia
Uvádza sa, že neprešiel iba random_excursion_test. SP 800-22 má známe limity a výsledky sa môžu podstatne líšiť podľa implementácie, veľkosti vzorky a endianity; autor to berie ako definitívny verdikt bez diskusie o parametroch (napr. --be prepínač, veľkosť okna), čo je metodologicky slabé.
Porovnanie s xorshift32 je korektné, ale „horšie (podľa očakávania)“ bez kvantifikácie a diskusie o špecifikách testov je zjednodušené.
Zhrnutie najdôležitejších faktických chýb:
CF ≠ overflow flag (zásadná chyba).
Pri CF=0 je hodnota nedefinovaná, nie nulová; nepodpora #UD.
„511 cyklov“ je nesprávne; reseed sa viaže na počet výstupov, nie CPU cykly.
ASM ukážka prepisuje 12 bajtov do 8-bajtového bufferu.
Zovšeobecnenie o „jedinom senzore“ a absolútne tvrdenia o „skutočne náhodnom“ sú nepresné.
Ináč skvelý článok :-)
NFx není nestandardní, je to jen nová notace, kterou intel začal používat.
Příklad:
NFx REX.W + 0F C7 /6 RDRAND r64
V podstatě to říká, že tato instrukce nepoužívá F2/F3 prefix. Při použití toho prefixu buď #UD a nebo to bude jiná instrukce. Hold dochází instrukce a je potřeba definovat co se ještě dá použít a co už ne :)
Stejně tak třeba NP (no-prefix), atd...
"„Prakticky isté, že nikdy nezískate rovnakú sekvenciu“ je prehnané. Pravdepodobnosť duplicity je zanedbateľná, nie nulová. Ide o logické zveličenie." - no on se generuje 256 bitovej seed. Takze dokonce by se dalo rict: je to prakticky jiste, mnohem (MNOHEM, o 2^128 vice) jistejsi, nez ze dostanete dva stejny UUID (o kterych se predpoklada, ze kolize prakticky nenastanou). Ja chapu slovo "prakticky jiste" jako ze s tim urcite neni zapotrebi pocitat.
Zrovna včera jsem na internetu hledal crypto knihovnu v C (potřebuji šifrovat pomocí ElGamal a nechce se mi to psát) a jedna z nich měla self-test. Self-test testoval, mimo jiné, i generátor náhodných čísel. Ten test spočíval v tom, že knihovna vygenerovala řadu náhodných čísel a tu potom zkomprimovala pomocí zlib/deflate. Test uspěl pouze tehdy, když množství dat po komprimaci narostlo. Zajímavé. Mimochodem: Máte někdo tip na články, nebo studie zabývající se constant time kryptografií? Nejlépe v Céčku, ASM se mi moc psát nechce, zvláště s nástupem ARM a RISC-V architektur.
to muzu taky zkusit. Zatim jsem jen rychle prohnal ta data gzipem a vysledek ma 4000644 bajtu, tedy je vetsi. Jenze gzip tam ma nejakou hlavicku, takze to moc prukazne neni (resp. ta hlavicka ma par bajtu, takze tech 644 je uz hodne pres, takze to mozna i prukazne je). Pozdeji zkusim skutecne jen komprimaci bez pridani hlavicek.
import zlib
with open("random.bin", "rb") as fin:
random = fin.read()
print(len(random))
compressed = zlib.compress(random, level=zlib.Z_BEST_COMPRESSION, wbits=-15)
print(len(compressed))
uncompressed = zlib.decompress(compressed, wbits=-15)
print(len(uncompressed))
Vychazi to ale nejak moc:
4000000
4001220
4000000
14. 8. 2025, 18:22 editováno autorem komentáře
Výstup ze zdroje entropie není nikde k dispozici, byly pochybnosti o jeho náhodnosti, když to nejde nijak ověřit.
Generátor je jeden sdílený přes všechny core, na starších CPU existoval exploit, kdy si jeden thread generoval klíče, z jiného threadu šlo získat stejnou sekvenci.
RDRAND vrací číslo podle SP800-90A, kdy z jednoho seedu vygeneruje 511 čísel a čekají předpřipravené v bufferu.
RDSEED vrací číslo podle SP800-90B, kde se seed použije jen jednou.
Aby to splňovalo NIST, generátor by měl mít interní self-test a přes CF hlásit když nějaká komponenta selže.
Ak vas to zaujima tak ked sme robili kryptografiu a chceli sme ju robit poriadne tak sme skusali Intel random generator vs specialny USB kluc. Presli sme to sadou testou a ten Intel sa sprava naozaj cudne. Ako velmi je predikovatelny neviem ale kvalita podla tychto testov nebola dobra. USB kluc vykazoval nasobne lepsie vysledky.
https://webhome.phy.duke.edu/~rgb/General/dieharder.php
strace python -c "import os; print(os.urandom(32).hex())"
.....
getrandom("\xd0\x71\x1f\x07\x8a\x56\x66\x05\x1d\xcd\x0e\x68\x57\xe6\x1a\xed\xf4\x0b\xe7\x66\x1b\x6a\xce\xad\x72\xb1\xff\xea\x09\x8c\xbc\x13", 32, 0) = 32
write(1, "d0711f078a5666051dcd0e6857e61aed"..., 65d0711f078a5666051dcd0e6857e61aedf40be7661b6acead72b1ffea098cbc13
) = 65
....
Zajímalo by mně jestli tyhle funkce využívá linux při čtení z /dev/random a /dev/urandom případně /dev/hwrng ?
Vzpomínám si že pred časem proletěla nějaká zprávička že hw random generator od intelu je na prd, a že ho kernel nebude používat. Ale nevzpomenu si jestli to byl tenhle v CPU, nebo v chipsetu.
Jak jsou na tom knihovny openssl a gnutls nebo implementace VPN? (OpenVPN, wireguard).
Jak se tyhle instrukce chovají ve virtualizaci?