This repository is StormByte Crypto: hash, compress, encrypt, sign and key agreement for the StormByte C++ suite.
It depends on StormByte Base ≥ 2.0.0, StormByte Buffer ≥ 2.0.0 and StormByte System ≥ 2.0.0. Public headers live under StormByte/crypto/. Crypto++ stays in the private tree: installed headers never mention CryptoPP::. With a static Crypto++ link, consumers do not install it.
The suite is split on purpose. Base, Buffer, Config, Database, Logger, Multimedia, Network and System are other repositories. This one does not implement them.
Buffer::Consumer that yields the digest when the source closes.Secure::Password via PBKDF2-HMAC-SHA256 (600 000 iterations). Authenticated modes fail closed on a bad tag or a wrong password.Strategy::Native is one PK transform per blob. Strategy::Hybrid wraps a random AES-256-GCM session key. Decrypt auto-detects the envelope.Secure::Password, not a std::string.StormByte::Safe::String (Base64 SPKI); private key stays in a Secure::Password. Handles are StormByte::Safe::Clonable with Safe::Shared (KeyPair::Generic::PointerType).StormByte::Crypto::Secure. Last owner zeros the bytes. Vault is movable, not copyable. Password::Size() is StormByte::ByteSize. A missing Vault::Get is StormByte.Crypto.Secure.Vault: ….std::span<const std::byte> → Buffer::WriteOnly for blocks; Buffer::Consumer in / out for pipelines (Network, Multimedia). Octet payloads are StormByte::BinaryData. Abstract counts use StormByte::Size; octet lengths use StormByte::ByteSize. Non-secret public text is ingested as std::string_view.| Module | Role | API |
|---|---|---|
| Base | Exceptions, Expected, serialization, UUID, concepts, CString / WCString / Size / ByteSize | /StormByte |
| Buffer | FIFO, SharedFIFO, Ring, Producer/Consumer and multi-stage pipelines | /StormByte-Buffer |
| Config | Human-readable text and versioned binary documents (groups, lists, raw bytes) | /StormByte-Config |
| Crypto | This repository | /StormByte-Crypto |
| Database | One API over SQLite, PostgreSQL and MariaDB | /StormByte-Database |
| Logger | Stream logger with levels, headers, hierarchical components and Scope | /StormByte-Logger |
| Multimedia | Decode, encode and containers without raw FFmpeg types; codecs enabled only if present | /StormByte-Multimedia |
| Network | Framed packets, Client/Server, IPv4/IPv6 TCP and Buffer pipelines (compress/encrypt) | /StormByte-Network |
| System | Processes, pipes and environment variables across Linux, Windows and macOS | /StormByte-System |
Needs a C++26 compiler, CMake 3.28 or newer, StormByte Base ≥ 2.0.0, StormByte Buffer ≥ 2.0.0 and StormByte System ≥ 2.0.0. Crypto++ and libbzip2 are build dependencies. Prefer a static Crypto++ link when you redistribute.
Shared vs static follows CMake BUILD_SHARED_LIBS (declared in lib/, default ON). A plain configure builds the shared library. -DBUILD_SHARED_LIBS=OFF builds a static archive; on Windows the headers then do not use dllimport. Vendored StormByte dependencies follow the same mode. Prefer a static Crypto++ link when you redistribute; that is independent of whether StormByte-Crypto itself is shared or static.
A shared build keeps this library as its own .so / .dll. Under the LGPL that is usually the simpler way to ship: the user can replace that file. A static archive is folded into your binary. The LGPL still applies to this code; you must give the recipient a way to relink your product with a different build of this library. If that does not fit how you distribute the final product, a commercial license is available from the copyright holder (see License).
Link StormByte-Crypto (and Buffer / String / System / Base). Include path: the public install prefix, headers as #include <StormByte/crypto/….hxx>.
Headers are #include <StormByte/crypto/….hxx>. Namespace root is StormByte::Crypto. Wiped secrets live in StormByte::Crypto::Secure.
Nothing in the public tree includes Crypto++. Private headers are not installed.
Public handles are Clonable + MakePointer / Shared. KeyPair, Signer, Crypter and Secret take KeyPair::Generic::PointerType, not std::shared_ptr. Exceptions use Path{"Crypto"}; child offices add their own segment. what() is StormByte.Crypto or StormByte.Crypto.<Child>: message. Secure uses StormByte.Crypto.Secure / StormByte.Crypto.Secure.Vault.
Concrete types (Crypter::AES_GCM, KeyPair::X25519, Signer::ED25519, …) construct the same way without going through Create.
Secure::Password is the only public container for secret bytes (passphrases, private key DER, shared secrets). Copies share the buffer; the last owner wipes it. Size() is StormByte::ByteSize.
Ingest is deliberately not std::string_view and not std::string by value.
std::string by value or by move across a DLL is unsafe: the buffer was allocated on the caller's heap. Destroying it inside this library can free the wrong CRT.std::string&. The constructor copies into wiped storage owned by this module and then overwrites and clears the argument. After return the only remaining copy is the one Password holds.explicit Password(const char*). They are copied; the source is not wiped (it lives in read-only storage). Use that form for tests and placeholders, not for production secrets kept in source.const void* + ByteSize) are copied and not wiped; the caller owns the source.Vault is movable, not copyable. A move leaves the source empty. Names are std::string_view. A missing name is Secure::VaultException.
Password → random salt + PBKDF2-HMAC-SHA256 → key. AES-GCM and ChaCha20-Poly1305 authenticate; a wrong password or a flipped bit returns false.
CBC siblings (AES, Camellia, Serpent, Twofish) use the same Encrypt / Decrypt names.
Native is one PK operation per blob (small messages). Hybrid is a random AES-256-GCM key wrapped with the recipient public key. Decrypt reads the header and picks the path.
ECC (Crypter::ECC + KeyPair::ECC) is the same API.
| Format | Meaning |
|---|---|
PEM | OpenSSL text (BEGIN / Base64). Default. |
DER | Raw ASN.1. Same family as many .cer / .crt blobs. |
Wrong or missing wrap password fails closed. Type comes from the OID (RSA, DSA, EC, Ed25519, X25519). Generate → Save → Load stays usable for encrypt, sign and share. X25519 also understands raw 32-byte library form. PublicKey() is const StormByte::Safe::String&; convert with std::string{std::string_view{kp->PublicKey()}} if you need a std::string.
Streaming: signer->Sign(consumer) / signer->Verify(consumer, signature).
Share takes std::string_view (a String converts). The result is std::optional<Secure::Password>. ECDH is the same with KeyPair::ECDH::Generate(256|384|521) and Secret::Type::ECDH.
Compressor decompresses as much as the stream decodes to; a small malicious input can expand to a very large output ("decompression bomb"). If you decompress data from an untrusted source, bound it yourself: check the expected/maximum size before decompressing, or stop draining the streaming Consumer once your own limit is hit.KeyPair::Save/SavePrivate are created owner-only (0600 on POSIX) and refuse to write through a pre-existing symlink at the destination path. Public key files are unaffected by either restriction.std::string of a production password after Password construction. Cede the buffer so it can be wiped. Do not pass secrets as string_view into Password.Issues only on this repository. Fork and open a pull request against master.
From 2.0.0, original StormByte-Crypto source is dual-licensed:
Neither license covers other StormByte modules or third-party material shipped under thirdparty/ (including Crypto++, bundled libbzip2, and vendored StormByte trees). Those keep their own licenses. Neither license grants patent rights.
StormByte is developed in spare time. Sponsorship is optional and does not buy features, priority or support.