# Блок `crypto` — криптографический фундамент Весь крипто-фундамент протокола. Снаружи (из [`net`](../net)) видны только `SessionKeys`, `SessionAuth` и потоковый шифр `ChaChaCipher` — остальное детали. > Подробности — в rustdoc: `cargo doc --open -p netrunner-core`, модуль `crypto`. > Здесь — карта блока и ментальная модель, чтобы быстро сориентироваться. ## Файлы | Файл | Что внутри | |---------------|--------------------------------------------------------------------| | `ecdh.rs` | Эфемерный обмен ключами X25519 (Diffie-Hellman). | | `hkdf.rs` | Расширение общего секрета в набор ключей (HKDF-SHA256). | | `session.rs` | Оркестрация: соль → ECDH → HKDF → ключи; time-based auth-теги. | | `chacha.rs` | Потоковый AEAD ChaCha20-Poly1305 с раздельными nonce по направлениям. | | `aead.rs` | Трейт `AeadPacker` — абстракция шифра для кодека. | ## Жизненный цикл ключей ```text 1. SessionKeys::new(is_initiator) → эфемерный X25519 + локальная соль 2. <обмен ClientHello/ServerHello> → узнаём чужой pubkey и соль 3. SessionKeys::update_keys(...) → ECDH → HKDF → 2×(key+iv) + auth_key 4. ChaChaCipher::set_keys(...) → горячий путь: in-place шифр/дешифр 5. SessionAuth (auth_key) → TOTP-подобный тег в каждом кадре ``` ## Инварианты (НЕ ЛОМАТЬ) - **Forward secrecy** — приватный ключ X25519 эфемерный и расходуется ровно один раз (`ECDH::get_shared` забирает его через `take()`). - **Уникальность nonce** — `nonce = base_iv XOR counter`, счётчик у каждого направления свой; повтор nonce при одном ключе ломает шифр. - **Постоянное время** — `SessionAuth::verify_tag` всегда проходит всё окно кандидатов без раннего выхода (иначе утечёт тайминг подбора тега). ## Связи - Ключи извлекаются из TLS-расширений модуля [`tlseng`](../tlseng) (KeyShare `0x0033`). - Шифрование вызывается из кодека [`nrxp`](../nrxp) через трейт `AeadPacker`.