Skip to main content

Crate dstu_core

Crate dstu_core 

Source
Expand description

Rust implementations of Ukrainian DSTU cryptographic standards (Kalyna, Kupyna, Strumok).

Pre-release and provisional — not independently audited. Kalyna and Kupyna are dual-oracle-verified against official test vectors. The Kalyna-alone mode of operation (hazmat::kalyna_ccm, hazmat::kalyna_gcm, and everything built on them) rests on an adopted assumption, not a confirmation against the primary DSTU 7624:2014 text (docs/DECISIONS.md D-05). Strumok is UAPKI-attributed only, not confirmed against the primary DSTU 8845:2019 text (docs/DECISIONS.md D-15). This crate makes no claim of side-channel (SPA/DPA) resistance. See docs/SECURITY.md and docs/DECISIONS.md in the project repository for the full threat model, citations, and per-construction status.

Modules§

crypto_auth
crypto_auth/crypto_onetimeauth equivalent (docs/dstu-crypto-project.md “Mapping onto the libsodium API”, docs/TASKS.md T-105, roadmap Step 3 item 2 - docs/DECISIONS.md D-66) - a thin libsodium-ergonomics wrapper over crate::hazmat::kupyna_kmac::Kupyna256Kmac.
crypto_box
crypto_box equivalent (docs/dstu-crypto-project.md “Mapping onto the libsodium API”, docs/TASKS.md T-178) - public-key encryption over hazmat::dstu9041 (l(p)=256, E256/1 only, T-177).
crypto_box512
crypto_box equivalent at l(p)=512 (E512/1, docs/TASKS.md T-193) - direct sibling of crate::crypto_box (l(p)=256, T-178) at this curve size’s own widths. Matches this project’s established per-curve-size sibling-module precedent (hazmat::dstu9041::curve512 etc., D-181), not a generic-over-width merge.
crypto_generichash
crypto_generichash equivalent (docs/dstu-crypto-project.md “Mapping onto the libsodium API”, docs/TASKS.md T-105, roadmap Step 3 item 2 - docs/DECISIONS.md D-66) - a bare re-export of crate::hazmat::kupyna’s one-shot and streaming API under this crate’s top-level crypto_* namespace, for naming parity with crypto_sign/crypto_secretbox/crypto_pwhash rather than a new wrapper.
crypto_kdf
crypto_kdf equivalent (docs/dstu-crypto-project.md “Mapping onto the libsodium API”, docs/TASKS.md T-105, roadmap Step 3 item 2 - docs/DECISIONS.md D-66) - a thin libsodium-ergonomics wrapper over Kupyna256Kdf, matching crate::crypto_auth’s reasoning exactly: only the 256-bit variant is exposed here (D-47’s “delete the knob”, same as crypto_auth’s choice among Kupyna{256,384,512}Kmac; the other two sizes stay available at hazmat::kupyna_kdf), and the master key is an opaque, Zeroize-on-drop MasterKey type rather than a raw [u8; 32].
crypto_pwhash
crypto_pwhash equivalent (docs/dstu-crypto-project.md “Mapping onto the libsodium API”, docs/TASKS.md T-71, docs/DECISIONS.md D-03/D-49/D-50) - plain Argon2id, the one deliberately non-DSTU component (no Ukrainian standard covers password hashing). Wraps the argon2 crate (RustCrypto/password-hashes, vetted in D-49) with libsodium’s own crypto_pwhash_str/ crypto_pwhash_str_verify shape: a self-describing PHC string that embeds algorithm, version, salt, and parameters, so verify_password needs nothing but the password and that string back.
crypto_secretbox
crypto_secretbox equivalent (docs/dstu-crypto-project.md “Mapping onto the libsodium API”, docs/TASKS.md T-37, docs/DECISIONS.md D-51) - a single fixed hazmat::kalyna_gcm::Kalyna256_256Gcm construction (D-47’s tie-breaker rule: no algorithm knob when one safe default exists) with an internally-generated nonce (never caller-supplied, extending the pattern uacrypt kalyna-ccm encrypt’s CLI layer already used, D-40/T-82) and a combined nonce || ciphertext || tag wire format, matching libsodium’s own crypto_secretbox_easy ergonomics.
crypto_secretstream
crypto_secretstream equivalent (docs/dstu-crypto-project.md “Mapping onto the libsodium API”, docs/TASKS.md T-40/T-70, roadmap Step 5 item 1 - docs/DECISIONS.md D-68) - a chunked/streaming AEAD construction so a large message never needs to fit in memory all at once, unlike crate::crypto_secretbox (whose underlying AEAD tag needs the whole plaintext/ciphertext up front).
crypto_sign
crypto_sign equivalent (docs/dstu-crypto-project.md “Mapping onto the libsodium API”, docs/TASKS.md T-48) - a libsodium-ergonomics wrapper over hazmat::dstu4145::signature. The first module in the high-level layer D-09 planned but never built (docs/release-readiness.md step 4) - this session’s shape for it: SigningKey/VerifyingKey/Signature, ed25519-dalek-style naming (docs/DECISIONS.md D-04’s addendum cites that crate’s convention).
crypto_sign257
crypto_sign equivalent for DSTU 4145’s m=257 curve - additive sibling of crate::crypto_sign, mirroring its shape exactly (SigningKey/VerifyingKey/Signature, deterministic nonce derivation, sign/sign_digest/verify/verify_digest), built on hazmat::dstu4145::{gf2m257, curve257, scalar257, signature257} instead of the m=163 modules. docs/TASKS.md T-199, docs/DECISIONS.md D-185/D-186.
crypto_stream
crypto_stream equivalent (docs/dstu-crypto-project.md “Mapping onto the libsodium API”, docs/TASKS.md roadmap Step 3 item 3, docs/DECISIONS.md D-67) - a libsodium-ergonomics wrapper over hazmat::strumok::Strumok256.
hazmat
Low-level (“hazardous material”) primitives: direct DSTU algorithm implementations with no forced RNG dependency and no safety rails — callers manage keys/nonces/IVs explicitly where an algorithm needs them. Available in no_std builds.
randombytes
randombytes equivalent (docs/dstu-crypto-project.md “Mapping onto the libsodium API”, docs/TASKS.md T-72, docs/DECISIONS.md D-48) - not a DSTU primitive. Wraps the OS CSPRNG (getrandom), same as libsodium’s own randombytes_buf does.
selftest
Runtime known-answer self-test (docs/TASKS.md T-161, docs/DECISIONS.md D-117): re-runs one official vector per primitive against the live compiled implementation, so a caller can verify their exact installed build produces correct output on their exact platform before trusting it with real data - the same “don’t just trust it compiled” instinct this project already applies to itself via dual-oracle verification (docs/SECURITY.md, “Crypto engineering hard constraints”). This is a small, fast, embedded-in-the-binary spot check - one vector per primitive, not the full corpus cargo test already runs against tests/vectors/; it is not a substitute for that suite.