🎲 hal::rng
Hardware True Random Number Generator
~380 satır
~14 fonksiyon
STM32F4/F7/H7
📖 Genel Bakış
RNG modülü, hardware tabanlı gerçek rastgele sayı üretir. Analog noise source kullanarak kriptografik kalitede random değerler sağlar. IoT güvenliği, UUID generation, cryptographic key generation ve Monte Carlo simülasyonları için kritiktir.
🔑 Temel Özellikler
- True Random: Pseudo-random değil, analog gürültü kaynağı
- 32-bit Output: Her okumada tam 32-bit random değer
- FIPS 140-2 Compliant: Kriptografik standartlara uygun
- Single Cycle: 40 CPU cycle'da yeni random değer
- 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
🚀 Hızlı Başlangıç
içe_aktar hal::rng, hal::rcc
// Enable RNG clock
rcc.periph_clock_enable(rcc.PERIPH_RNG)
// Initialize RNG
rng.init()
// Get random 32-bit value
değişken rastgele = rng.get_random()
io.yazdir_satır("Random: 0x" + rastgele.onaltılıya())
// Random range [0, max)
fonksiyon random_range(max: sayı) -> sayı yap
dön (rng.get_random() % max)
son
📦 Tipler ve Enum'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
}
yapı RNGConfig yap
clock_enable: mantık = doğru,
interrupt_enable: mantık = yanlış,
error_callback: fonksiyon(Flag) = boş
son
💡 Örnek 1: UUID Generation (RFC 4122)
Problem: Unique identifier oluşturmak (IoT device ID)
içe_aktar hal::rng
yapı UUID yap
data: Dizi<sayı8> = Dizi.yeni(16)
son
fonksiyon uuid_v4_generate() -> UUID yap
değişken uuid = UUID yap son
// Generate 128 bits (16 bytes) of random data
için i içinde 0..4 yap
değişken rand32 = rng.get_random()
// Split into 4 bytes
uuid.data[i*4 + 0] = (rand32 >> 24) & 0xFF kayıt sayı8
uuid.data[i*4 + 1] = (rand32 >> 16) & 0xFF kayıt sayı8
uuid.data[i*4 + 2] = (rand32 >> 8) & 0xFF kayıt sayı8
uuid.data[i*4 + 3] = rand32 & 0xFF kayıt sayı8
son
// 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
dön uuid
son
fonksiyon uuid_to_string(uuid: UUID) -> Metin yap
// Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
değişken hex = ""
için i içinde 0..16 yap
hex = hex + uuid.data[i].onaltılıya(2)
eğer (i == 3 veya i == 5 veya i == 7 veya i == 9) yap
hex = hex + "-"
son
son
dön hex
son
fonksiyon ana() yap
rng.init()
için i içinde 0..5 yap
değişken uuid = uuid_v4_generate()
io.yazdir_satır("UUID: " + uuid_to_string(uuid))
son
son
Çıktı: UUID: 550e8400-e29b-41d4-a716-446655440000 (benzersiz her çalıştırmada)
💡 Örnek 2: Cryptographic Key Generation
Problem: AES-256 için 256-bit random key oluşturmak
içe_aktar hal::rng, hal::crypto
sabit AES256_KEY_SIZE: sayı = 32 // 256 bit = 32 bytes
yapı CryptoKey yap
data: Dizi<sayı8>,
size: sayı
son
fonksiyon generate_aes256_key() -> CryptoKey yap
değişken key = CryptoKey yap
data: Dizi.yeni(AES256_KEY_SIZE),
size: AES256_KEY_SIZE
son
// Generate 256 bits of cryptographic random data
için i içinde 0..8 yap // 8 * 32 bits = 256 bits
değişken rand = rng.get_random()
eğer rng.get_flag(rng.FLAG_CECS) veya rng.get_flag(rng.FLAG_SECS) yap
io.yazdir_satır("RNG ERROR: Clock or seed error!")
dön key // Invalid key
son
key.data[i*4 + 0] = (rand >> 24) & 0xFF kayıt sayı8
key.data[i*4 + 1] = (rand >> 16) & 0xFF kayıt sayı8
key.data[i*4 + 2] = (rand >> 8) & 0xFF kayıt sayı8
key.data[i*4 + 3] = rand & 0xFF kayıt sayı8
son
dön key
son
fonksiyon key_to_hex(key: CryptoKey) -> Metin yap
değişken hex = ""
için byte içinde key.data yap
hex = hex + byte.onaltılıya(2)
son
dön hex
son
fonksiyon ana() yap
rng.init()
io.yazdir_satır("Generating AES-256 key...")
değişken 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)
son
Güvenlik: Hardware RNG kullanımı software PRNG'den çok daha güvenlidir.
💡 Örnek 3: Random Number Distribution (Dice Roll)
Problem: Uniform distribution ile dice roll simulation
içe_aktar hal::rng
// Random in range [min, max]
fonksiyon random_range(min: sayı, max: sayı) -> sayı yap
değişken range = max - min + 1
değişken rand = rng.get_random()
// Avoid modulo bias using rejection sampling
değişken limit = 0xFFFF_FFFF - (0xFFFF_FFFF % range)
döngü yap
eğer rand < limit yap
dön min + (rand % range)
son
rand = rng.get_random()
son
son
fonksiyon dice_roll() -> sayı yap
dön random_range(1, 6)
son
fonksiyon test_distribution() yap
değişken histogram: Dizi<sayı> = Dizi.yeni(6, 0)
sabit ROLLS: sayı = 10000
için i içinde 0..ROLLS yap
değişken roll = dice_roll()
histogram[roll - 1] = histogram[roll - 1] + 1
son
io.yazdir_satır("Dice roll distribution (" + ROLLS.metne() + " rolls):")
için i içinde 0..6 yap
değişken face = i + 1
değişken count = histogram[i]
değişken percent = (count kayıt kesir / ROLLS kayıt kesir) * 100.0
io.yazdir_satır(" [" + face.metne() + "]: " + count.metne() +
" (" + percent.metne() + "%)")
son
son
fonksiyon ana() yap
rng.init()
test_distribution()
son
Sonuç: Uniform distribution ~16.67% her yüz için (ideal: 16.666...%).
📚 API Referansı
Temel Fonksiyonlar
// RNG initialization and control
fonksiyon init()
fonksiyon deinit()
fonksiyon enable()
fonksiyon disable()
// Random number generation
fonksiyon get_random() -> sayı // Blocking read
fonksiyon get_random_async() -> Seçenek<sayı> // Non-blocking
// Status and error checking
fonksiyon is_ready() -> mantık
fonksiyon get_flag(flag: Flag) -> mantık
fonksiyon clear_flag(flag: Flag)
// Interrupt handling
fonksiyon interrupt_enable(it: Interrupt)
fonksiyon interrupt_disable(it: Interrupt)
⚠️ Önemli Notlar:
- Clock Required: RNG için 48 MHz clock gerekli (PLL'den)
- Error Handling: CECS/SECS flagleri kontrol edilmeli
- First Read: İlk random değer için ~40 cycle bekleme
- Modulo Bias: Range işlemlerinde rejection sampling kullan
🖥️ Platform Desteği
| 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 için RNG kullan
- ✅ Key generation: Crypto keyler için 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
🔗 İlgili Modüller
- hal::crypto - AES/DES encryption with random keys
- hal::clock - 48 MHz clock configuration
- math - Statistical distribution functions