|
SH2SC-EDT
Self-Healing Hardware and Software Complex for Encrypted Data Transmission
|
ChaCha20-based CSPRNG for SH2SC-EDT — Receiver Node B (ATmega328P). More...
#include <Arduino.h>#include <ChaCha.h>
Include dependency graph for csprng.h:
This graph shows which files directly or indirectly include this file:Go to the source code of this file.
Functions | |
| static void | s_fillKeystreamBlock () |
Produce the next 64-byte ChaCha20 keystream block into s_keystreamBuf. | |
| void | initCSPRNG (const uint8_t *hardwareSeed) |
| Seed the ChaCha20 CSPRNG with 256 bits of hardware entropy. | |
| uint32_t | getSecureRandom32 () |
| Return 32 bits of CSPRNG output (non-blocking). | |
Variables | |
| static const uint8_t | CSPRNG_BLOCK_BYTES = 64u |
| Size of one ChaCha20 keystream output block in bytes. | |
| static ChaCha | s_chacha |
| ChaCha20 cipher object (20-round configuration by default constructor). | |
| static uint8_t | s_keystreamBuf [CSPRNG_BLOCK_BYTES] |
One-block keystream cache. Refilled automatically when s_keystreamUsed >= CSPRNG_BLOCK_BYTES. | |
| static uint8_t | s_keystreamUsed = CSPRNG_BLOCK_BYTES |
Number of bytes consumed from s_keystreamBuf so far. | |
ChaCha20-based CSPRNG for SH2SC-EDT — Receiver Node B (ATmega328P).
Part of the SH2SC-EDT project. Implements the C2P-ARQ protocol.
This module wraps the ChaCha20 stream cipher as a Cryptographically
Secure Pseudo-Random Number Generator (CSPRNG) for the ATmega328P.
The cipher is seeded once with 256 bits of hardware entropy collected
by generateEntropyPool(), then used as an unlimited deterministic
keystream to produce session nonces.
Mathematical basis:
@code
C = P XOR KS -> C = 0x00..0 XOR KS = KS
@endcode
Encrypting an all-zeros plaintext yields the raw ChaCha20 keystream.
**Buffer design (AVR memory optimisation):**
ChaCha20 generates output in 64-byte blocks. Invoking the cipher for
every byte would be prohibitively expensive on an 8-bit MCU, so this
module maintains a 64-byte keystream cache. getSecureRandom32() draws
4 bytes per call; the block is refilled every 16 calls (~100 us at
16 MHz).
**Static SRAM budget (approximate):**
- s_chacha object: ~140 bytes (ChaCha20 key schedule + state)
- s_keystreamBuf: 64 bytes
- s_keystreamUsed: 1 byte
- Total: ~205 bytes of 2048 bytes available
**Requires:** Arduino Crypto library by Rhys Weatherley.
Library Manager: "Crypto" by Rhys Weatherley.
**Usage:**
1. Call initCSPRNG(seed) ONCE in setup() after generateEntropyPool().
2. Call getSecureRandom32() anywhere in the main loop for 32-bit random output.
Definition in file csprng.h.
| uint32_t getSecureRandom32 | ( | ) |
Return 32 bits of CSPRNG output (non-blocking).
Normal cost: O(1) — four byte reads and one counter increment. Amortised refill cost: ~100 us every 16 calls (once per 64-byte block).
Byte assembly uses explicit shifts to avoid type-punning undefined behaviour; casting uint8_t* to uint32_t* is UB under the AVR strict-aliasing ABI.
Definition at line 126 of file csprng.h.
References CSPRNG_BLOCK_BYTES, s_fillKeystreamBlock(), s_keystreamBuf, and s_keystreamUsed.
Here is the call graph for this function:| void initCSPRNG | ( | const uint8_t * | hardwareSeed | ) |
Seed the ChaCha20 CSPRNG with 256 bits of hardware entropy.
Key and nonce policy:
Pre-fills s_keystreamBuf so the very first getSecureRandom32() call returns immediately without an additional cipher invocation.
| hardwareSeed | Pointer to exactly 32 bytes produced by generateEntropyPool(). The pointer is read once; the caller is responsible for scrubbing the seed buffer after this call if desired. |
Definition at line 102 of file csprng.h.
References s_chacha, and s_fillKeystreamBlock().
Here is the call graph for this function:
|
static |
Produce the next 64-byte ChaCha20 keystream block into s_keystreamBuf.
Memory-efficient technique — zero the buffer in-place, then encrypt over it:
This avoids allocating a second 64-byte "zeros input" buffer in SRAM. ChaCha20's internal 64-bit block counter is advanced automatically by encrypt(), so successive calls produce entirely distinct blocks; the keystream never repeats within 2^64 blocks.
Definition at line 75 of file csprng.h.
References CSPRNG_BLOCK_BYTES, s_chacha, s_keystreamBuf, and s_keystreamUsed.
Referenced by getSecureRandom32(), and initCSPRNG().
Here is the caller graph for this function:
|
static |
Size of one ChaCha20 keystream output block in bytes.
Must be a multiple of 4 so that getSecureRandom32() never straddles a block boundary. One block = 64 bytes = 512 bits.
Definition at line 49 of file csprng.h.
Referenced by getSecureRandom32(), and s_fillKeystreamBlock().
|
static |
ChaCha20 cipher object (20-round configuration by default constructor).
Definition at line 52 of file csprng.h.
Referenced by initCSPRNG(), and s_fillKeystreamBlock().
|
static |
One-block keystream cache. Refilled automatically when s_keystreamUsed >= CSPRNG_BLOCK_BYTES.
Definition at line 55 of file csprng.h.
Referenced by getSecureRandom32(), and s_fillKeystreamBlock().
|
static |
Number of bytes consumed from s_keystreamBuf so far.
Initialised to CSPRNG_BLOCK_BYTES to trigger an immediate refill on the very first call to getSecureRandom32().
Definition at line 62 of file csprng.h.
Referenced by getSecureRandom32(), and s_fillKeystreamBlock().