🎲 hal::rng
Hardware True Random Number Generator
~380 satır
~14 function
STM32F4/F7/H7
📖 Overview
RNG modülü, hardware tabanlı gerçek rastgele int üretir. Analog noise source kullanarak kriptografik kalitede random difler sağlar. IoT güvenliği, UUID generation, cryptographic key generation ve Monte Carlo simülasyonları for kritiktir.
🔑 Key Features
- True Random: Pseudo-random değil, analog gürültü kaynağı
- 32-bit Output: Her okumada tam 32-bit random dif
- FIPS 140-2 Compliant: Kriptografik standartlara uygun
- Single Cycle: 40 CPU cycle'da yeni random dif
- Clock Error Detection: Clock problemi tespit edilir
- Seed Error Detection: Entropi hatası algılanır
- Interrupt Support: Data ready interrupt
- DMA Compatible: Continuous random stream
🚀 Quick Start
import hal::rng, hal::rcc
// Enable RNG clock
rcc.periph_clock_enable(rcc.PERIPH_RNG)
// Initialize RNG
rng.init()
// Get random 32-bit value
let rastgele = rng.get_random()
io.yazdir_satır("Random: 0x" + rastgele.onaltılıya())
// Random range [0, max)
function random_range(max: int) -> int do
return (rng.get_random() % max)
end
📦 Types and Enums'lar
// RNG Flags
enum Flag {
FLAG_DRDY, // Data ready
FLAG_CECS, // Clock error current status
FLAG_SECS // Seed error current status
}
// RNG Interrupts
enum Interrupt {
IT_CEI, // Clock error interrupt
IT_SEI // Seed error interrupt
}
struct RNGConfig do
clock_enable: bool = true,
interrupt_enable: bool = false,
error_callback: function(Flag) = null
end
💡 Example 1: UUID Generation (RFC 4122)
Problem: Unique identifier oluşturmak (IoT device ID)
import hal::rng
struct UUID do
data: Array<int8> = Array.yeni(16)
end
function uuid_v4_generate() -> UUID do
let uuid = UUID do end
// Generate 128 bits (16 bytes) of random data
for i forde 0..4 do
let rand32 = rng.get_random()
// Split into 4 bytes
uuid.data[i*4 + 0] = (rand32 >> 24) & 0xFF cast int8
uuid.data[i*4 + 1] = (rand32 >> 16) & 0xFF cast int8
uuid.data[i*4 + 2] = (rand32 >> 8) & 0xFF cast int8
uuid.data[i*4 + 3] = rand32 & 0xFF cast int8
end
// Set version (4) and variant (RFC 4122)
uuid.data[6] = (uuid.data[6] & 0x0F) | 0x40 // Version 4
uuid.data[8] = (uuid.data[8] & 0x3F) | 0x80 // Variant RFC4122
return uuid
end
function uuid_to_string(uuid: UUID) -> String do
// Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
let hex = ""
for i forde 0..16 do
hex = hex + uuid.data[i].onaltılıya(2)
if (i == 3 veya i == 5 veya i == 7 veya i == 9) do
hex = hex + "-"
end
end
return hex
end
function ana() do
rng.init()
for i forde 0..5 do
let uuid = uuid_v4_generate()
io.yazdir_satır("UUID: " + uuid_to_string(uuid))
end
end
Çıktı: UUID: 550e8400-e29b-41d4-a716-446655440000 (benzersiz her çalıştırmada)
💡 Example 2: Cryptographic Key Generation
Problem: AES-256 for 256-bit random key oluşturmak
import hal::rng, hal::crypto
const AES256_KEY_SIZE: int = 32 // 256 bit = 32 bytes
struct CryptoKey do
data: Array<int8>,
size: int
end
function generate_aes256_key() -> CryptoKey do
let key = CryptoKey do
data: Array.yeni(AES256_KEY_SIZE),
size: AES256_KEY_SIZE
end
// Generate 256 bits of cryptographic random data
for i forde 0..8 do // 8 * 32 bits = 256 bits
let rand = rng.get_random()
if rng.get_flag(rng.FLAG_CECS) veya rng.get_flag(rng.FLAG_SECS) do
io.yazdir_satır("RNG ERROR: Clock or seed error!")
return key // Invalid key
end
key.data[i*4 + 0] = (rand >> 24) & 0xFF cast int8
key.data[i*4 + 1] = (rand >> 16) & 0xFF cast int8
key.data[i*4 + 2] = (rand >> 8) & 0xFF cast int8
key.data[i*4 + 3] = rand & 0xFF cast int8
end
return key
end
function key_to_hex(key: CryptoKey) -> String do
let hex = ""
for byte forde key.data do
hex = hex + byte.onaltılıya(2)
end
return hex
end
function ana() do
rng.init()
io.yazdir_satır("Generating AES-256 key...")
let key = generate_aes256_key()
io.yazdir_satır("Key: " + key_to_hex(key))
// Use key for AES encryption
crypto.aes_init(crypto.AES256, key.data)
end
Güvenlik: Hardware RNG kullanımı software PRNG'den çok daha güvenlidir.
💡 Example 3: Random Number Distribution (Dice Roll)
Problem: Uniform distribution ile dice roll simulation
import hal::rng
// Random in range [min, max]
function random_range(min: int, max: int) -> int do
let range = max - min + 1
let rand = rng.get_random()
// Avoid modulo bias using rejection sampling
let limit = 0xFFFF_FFFF - (0xFFFF_FFFF % range)
loop do
if rand < limit do
return min + (rand % range)
end
rand = rng.get_random()
end
end
function dice_roll() -> int do
return random_range(1, 6)
end
function test_distribution() do
let histogram: Array<int> = Array.yeni(6, 0)
const ROLLS: int = 10000
for i forde 0..ROLLS do
let roll = dice_roll()
histogram[roll - 1] = histogram[roll - 1] + 1
end
io.yazdir_satır("Dice roll distribution (" + ROLLS.metne() + " rolls):")
for i forde 0..6 do
let face = i + 1
let count = histogram[i]
let percent = (count cast float / ROLLS cast float) * 100.0
io.yazdir_satır(" [" + face.metne() + "]: " + count.metne() +
" (" + percent.metne() + "%)")
end
end
function ana() do
rng.init()
test_distribution()
end
Result: Uniform distribution ~16.67% her yüz for (ideal: 16.666...%).
📚 API Reference
Core Functions
// RNG initialization and control
function init()
function deinit()
function enable()
function disable()
// Random number generation
function get_random() -> int // Blocking read
function get_random_async() -> Option<int> // Non-blocking
// Status and error checking
function is_ready() -> bool
function get_flag(flag: Flag) -> bool
function clear_flag(flag: Flag)
// Interrupt handling
function interrupt_enable(it: Interrupt)
function interrupt_disable(it: Interrupt)
⚠️ Important Notes:
- Clock Required: RNG for 48 MHz clock gerekli (PLL'den)
- Error Handling: CECS/SECS flagleri kontrol edilmeli
- First Read: İlk random dif for ~40 cycle bekleme
- Modulo Bias: Range işlemlerinde rejection sampling kullan
🖥️ Platform Support
| Platform | RNG Support | Clock Source | Performance |
|---|---|---|---|
| STM32F1 | ❌ Yok | - | - |
| STM32F4 | ✅ Var | PLL 48 MHz | 40 cycles |
| STM32F7 | ✅ Var | PLL 48 MHz | 40 cycles |
| STM32H7 | ✅ Var | PLL 48 MHz | 32 cycles |
| STM32L4 | ✅ Var | MSI/HSI48 | 40 cycles |
✅ Best Practices
- ✅ Error check: CECS/SECS flaglerini kontrol et
- ✅ Seeding: PRNG seed for RNG kullan
- ✅ Key generation: Crypto keyler for RNG şart
- ✅ Rejection sampling: Modulo bias'tan kaçın
- ❌ Predictable değil: RNG debug'da bile predictable değil
- ❌ Clock dependency: 48 MHz clock olmadan çalışmaz
🔗 Related Modules
- hal::crypto - AES/DES encryption with random keys
- hal::clock - 48 MHz clock configuration
- math - Statistical distribution functions