Releases: cryptopp-modern/cryptopp-modern
Release list
2026.8.1
2026.8.1 is a patch release fixing BLAKE3 multi-chunk hashing, malformed DEFLATE header handling, and cryptest shared-library compatibility.
Important: BLAKE3 digests of messages longer than 1024 bytes produced by releases from 2025.11.0 through 2026.8.0 may be incorrect. See the upgrade notes below.
- Fix three defects in BLAKE3 multi-chunk hashing: incorrect byte order during tree finalisation on big-endian targets, missing zero padding for partial final blocks, and an out-of-bounds read in the SSE4.1, AVX2, and AVX512 paths (#65).
- Reject invalid DEFLATE HLIT values before filling the dynamic code-length table, preventing an out-of-bounds write (#67; weidai11/cryptopp#1368 and weidai11/cryptopp#1371). Mirror upstream's follow-up hardening (#70).
- Fix
cryptestdynamic_castfailures against shared-library builds with hidden visibility, seen on FreeBSD with Clang and libc++ (#64).
Upgrade notes
Stored BLAKE3 digests should be recomputed when any of the following apply:
- On big-endian platforms, all messages longer than 1024 bytes hashed with releases from 2025.11.0 through 2026.8.0.
- On any platform, messages longer than 1024 bytes whose length is not a multiple of 64, hashed with releases from 2025.11.0 through 2026.8.0.
- On x86 builds using SSE4.1, AVX2, or AVX512, messages supplied through a single
Updatecall whose length is 4096, 8192, or a larger power of two, hashed with releases from 2025.12.0 through 2026.8.0.
Messages up to 1024 bytes and algorithms other than BLAKE3 are unaffected.
There are no API or ABI changes. The shared-library SONAME remains libcryptopp.so.9.
2026.8.0
2026.8.0 adds Unix shared-library builds, mixed-parameter HSS, a ChaCha SIMD counter-carry fix, and stricter input validation for BLAKE3, AEAD, and PBKDF.
- Fix ChaCha counter carry in the NEON, SSE2, and AltiVec backends. Multi-block requests could produce incorrect keystream when the 32-bit block counter overflowed (weidai11/cryptopp#1362, fixed upstream via weidai11/cryptopp#1363).
- Add Unix shared-library builds. The SONAME starts an independent ABI series at
libcryptopp.so.9(#48). - Add mixed-parameter HSS with per-level LMS and LM-OTS parameters,
HSS_SHA256_H10W4_H5W8_L2, and LM-OTS W1/W2/W4. Verify interoperability against RFC 8554 Appendix F Test Case 2 (#56). - Harden BLAKE3 public-input validation. Invalid keys, KDF contexts, digest sizes, and truncation sizes now throw; keyed-mode
MIN_KEYLENGTHcorrectly reports 32; andAlgorithmProviderno longer reports NEON on ARM (#57). - Reject zero-length AEAD authentication tags (#58; weidai11/cryptopp#1364).
- Reject zero PBKDF iterations without a positive time budget (#59; weidai11/cryptopp#1366).
- Fix MSVC MASM object paths under CMake and add Windows ARM64 CI coverage (#43).
- Restore the datatest diagnostic context on scope exit (#62).
- Fix variable collisions in
setenv-ios.sh.
Upgrade notes
- Users that instantiate
HSS_Params<LMS, OTS, LEVELS>directly must migrate to the new variadicHSS_Params<HSSLevel<...>, ...>form. TheLMSParametersandOTSParametersaliases were replaced byLMSParamsAt<I>andOTSParamsAt<I>. The namedHSS_*typedefs, wire formats, key encodings, and state files are unchanged. - BLAKE3 keyed mode now advertises and enforces its 32-byte key requirement;
MIN_KEYLENGTHwas previously reported as 0. Invalid keys, KDF contexts, digest sizes, and truncation sizes now throw in release builds. - Zero-length AEAD tags now throw during finalisation. The one-shot APIs may have written output before the exception, so callers must discard that output.
- This is the first release with Unix shared libraries. The SONAME ABI series is independent of the calendar version and starts at
libcryptopp.so.9.
2026.7.1
2026.7.1 is a packaging patch. No cryptographic code changed.
- Move CMake and pkg-config files under
${CMAKE_INSTALL_LIBDIR}(#47). - Restore
libcryptopp.pc; keepcryptopp-modern.pcas an alias (#51). - Add
.tar.gzreleases and normalise line endings (#49). - Publish the release-signing key and verification steps (#46).
Standard CMake and pkg-config discovery continues to work. Consumers using hard-coded paths under share/ must update them.
2026.7.0
2026.7.0
Minor release: SLH-DSA external interface and stateful-signing hardening.
SLH-DSA external interface (fixes #40)
SLH-DSA now signs and verifies with the FIPS 205 external pure interface.
This restores interoperability with OpenSSL, X.509, and CMS. The default context is empty. SLHDSA_MessageAccumulator now supports SetContext for explicit-context signing.
Compatibility: signatures produced by 2026.3.0 through 2026.6.0 used the internal message form and will not verify under 2026.7.0, or vice versa. Re-sign stored SLH-DSA signatures with 2026.7.0. LMS/HSS and other algorithms are unaffected.
Stateful-signing hardening
- LMS/HSS signing now fails closed on invalid state reservations.
- StateReservation is bound to its issuing store; cross-store use is rejected.
- Null state-store access throws SignerStateIntegrityFailure.
- FileStateStore validates state-file size on open and rejects zero-capacity stores.
- FileStateStore uses POSIX exclusive locking and retries interrupted I/O.
- HSS capacity helpers and public-header hygiene were fixed for C++11.
2026.6.0
2026.6.0 Release Notes
Release Date: 3 June 2026
Release Type: Minor release
Overview
cryptopp-modern 2026.6.0 adds LMS and HSS stateful hash-based signatures
following NIST SP 800-208 and RFC 8554.
This release includes:
- LMS single-tree signatures for H5 and H10 with Winternitz W=8
- HSS hierarchical signatures at L=2 and L=3 with uniform parameter sets
- a new stateful signing API, separate from
PK_Signer FileStateStore, a durable file-backed state store for signing indexes- ASN.1 public-key support using RFC 8708
id-alg-hss-lms-hashsig
There are no breaking API changes.
LMS and HSS
LMS and HSS are stateful hash-based signature schemes. Each signature consumes
a one-time signing index, and reusing an index breaks security.
The supported types are:
LMS_SHA256_H5_W8LMS_SHA256_H10_W8HSS_SHA256_H5_W8_L2HSS_SHA256_H10_W8_L2HSS_SHA256_H5_W8_L3
Public keys are encoded as X.509 SubjectPublicKeyInfo using the RFC 8708
OID. Private keys use a library-local PKCS#8 wrapper carrying SEED || I.
Signing progress is not serialised into the private key; it lives in the
state store.
Stateful signing API
This release adds:
PK_StatefulSignerSignerStateStoreStateReservationInsecureMemoryStateStoreFileStateStore
PK_StatefulSigner is deliberately not a subtype of PK_Signer. Stateful
signers have different safety rules, so keeping the API separate avoids
accidentally using a stateful signer through the stateless signer interface.
The core rule is simple: once a signing index has been reserved, it must not
be issued again. Safe failure may burn an unused index. Unsafe failure is
index reuse.
FileStateStore
FileStateStore is the durable reference backend for desktop and server use.
It reserves indexes ahead of signing using write-ahead persistence, with a
fixed-size on-disk record protected by HMAC-SHA256. On invalid state or
integrity failure, the store fails closed and poisons itself.
Platform support includes Win32 file handling, POSIX fsync, and macOS
F_FULLFSYNC.
FileStateStore does not claim to solve every rollback scenario. If an
application needs protection against backup restore, VM snapshot rollback, or
external file replacement, it should use a rollback-protected backing store or
provide its own SignerStateStore implementation.
Other changes
This release also includes:
- Save/Load round-trip tests for ML-KEM, ML-DSA, and SLH-DSA keys
- Android x86_64 and x86 build coverage in CI
- legacy compiler CI lanes for GCC 9-10 and Clang 11-14
- a sanitizer CI fix so
cryptest tvoutput is included in the checked log - a zero-length
memcpyguard inDL_DecryptorBase::Decryptfor UBSan hygiene - documentation updates for LMS/HSS
Validation
LMS and HSS coverage includes ACVP and RFC test vectors, malformed-signature
rejection, exhaustion handling, HSS subtree boundary handling, signer
reconstruction, and FileStateStore corruption and poisoning cases.
Validation is wired into ValidateAll.
Upgrade notes
No breaking changes.
Existing signers, verifiers, and serialisation paths are unaffected.
Users adopting LMS or HSS should review the SP 800-208 guidance on state
management before deploying. Each signature permanently consumes signer state.
FileStateStore is suitable as a reference backend for desktop and server
platforms. Embedded targets should implement SignerStateStore against a
rollback-protected backing store.
2026.5.2
2026.5.2 Release Notes
Release Date: 26 May 2026
Release Type: Patch release
Overview
cryptopp-modern 2026.5.2 hardens ASN.1 BER re-encoding and tightens Ed25519 verification behaviour.
This release adds:
- a recursion depth cap for
DERReencode - rejection of non-canonical Ed25519 signatures where
S >= L - strict-validation rejection of small-order Ed25519 public keys
There are no API changes in this release.
ASN.1 DERReencode depth cap
DERReencode walked nested constructed indefinite BER without a depth limit. A crafted chain of 0x30 0x80 sequences could recurse until the thread stack was exhausted. PKCS8PrivateKey import reaches this path through BERDecodeOptionalAttributes.
This release caps the recursion depth at 32 levels, matching OpenSSL's ASN1_MAX_CONSTRUCTED_NEST. Deeper inputs now throw BERDecodeError instead of recursing further.
This addresses upstream Crypto++ issue 1353. The reporter rated the issue CVSS 7.5 for availability impact.
Ed25519 signature scalar canonicality
The Ed25519 verifiers accepted non-canonical signatures where S >= L. The previous check only masked the top three bits of S, leaving the gap L <= S < 2^253. A valid signature changed from S' to S' + L could still verify because the verification equation holds modulo the subgroup order.
Both affected verification paths are now patched:
- the Donna verifier
- the NaCl C API verifier,
crypto_sign_openintweetnacl.cpp
Both now reject S >= L before continuing with verification.
This addresses the signature-scalar part of upstream Crypto++ issue 1352.
Severity: Low. This is a conformance fix, not a forgery. It matters for systems that key behaviour on raw signature bytes, such as replay caches, audit trails, deduplication, allowlists, and interoperability with stricter Ed25519 implementations.
Ed25519 small-order public key rejection
ed25519PublicKey::Validate now rejects small-order Ed25519 public keys when validation level is 2 or higher. The existing canonical encoding check still runs at all validation levels.
This addresses the small-order public key part of upstream Crypto++ issue 1352. Level 0 behaviour is unchanged.
Validation
New regression coverage was added for:
DERReencodedepth limits invalidat0.cpp- Ed25519 scalar canonicality in the Donna verifier path
- Ed25519 scalar canonicality in the NaCl verifier path
- Ed25519 small-order public key validation
Local validation passed with:
cryptest vcryptest tv all
References
- PR #35: Harden DERReencode and Ed25519 verification
- PR #36: Reject small-order Ed25519 public keys in Validate
- Upstream Crypto++ issue 1353
- Upstream Crypto++ issue 1352
- Upstream Crypto++ PR 1354
- Upstream Crypto++ PR 1355
- Upstream Crypto++ commit
4775a166, covering the small-order public key check on upstream master
Upgrade notes
No breaking changes.
Existing valid signatures and valid public keys continue to verify. The stricter checks only reject:
- non-canonical Ed25519 signatures where
S >= L - small-order Ed25519 public keys when
ed25519PublicKey::Validateis called at level 2 or higher
2026.5.1
2026.5.1 Release Notes
Release Date: May 2026
Release Type: Patch release
Overview
cryptopp-modern 2026.5.1 fixes a BLAKE3 correctness issue on AArch64, restores Android CMake builds, and extends CI coverage around the paths that were missed.
There are no API changes in this release.
BLAKE3 correctness fix on AArch64
This release fixes a bug where BLAKE3 produced incorrect hashes on AArch64 systems when the NEON path was used.
This affected BLAKE3 hashes generated by cryptopp-modern 2026.1.0 through 2026.5.0 on platforms such as Apple Silicon macOS, ARM64 Linux, and Android arm64-v8a.
Other architectures are not affected by this BLAKE3 output issue.
The fix removes the local single-block NEON compress path and uses the portable BLAKE3 path instead, matching the reference implementation.
ValidateBLAKE3() is now part of the default validation suite, so this is covered by CI going forward.
If you stored BLAKE3 hashes from the affected versions for pinning, allowlists, deduplication, or audit records, treat those values as suspect and recompute them with 2026.5.1 or later.
armv7 NEON build fix
This release also fixes an armv7 NEON build failure in rot8_neon.
The previous code used an AArch64-only NEON intrinsic, which broke Android armeabi-v7a builds. The replacement follows the BLAKE3 reference approach and works on both armv7 and AArch64.
Android CMake build fix
Android CMake builds now find cpu-features.h automatically.
The Android NDK keeps this file outside the normal sysroot, under sources/android/cpufeatures/. The CMake build now adds the required include path and source file when building for Android.
This removes the need for users to stage cpu-features.h manually.
CI updates
CI has also been extended to cover the paths that were missed:
- Android CMake build checks for
arm64-v8aandarmeabi-v7a - legacy GCC checks for GCC 9 and GCC 10
- legacy Clang checks for Clang 13 and Clang 14
actions/checkouthas been bumped from v4 to v5
References
Upgrade notes
No breaking API changes. No public API additions.
The important behavioural change is the BLAKE3 AArch64 correction. If you used BLAKE3 hashes generated by cryptopp-modern 2026.1.0 through 2026.5.0 on AArch64, treat those values as suspect and recompute them with 2026.5.1 or later.
2026.5.0
2026.5.0 Release Notes
Release Date: May 2026
Release Type: Minor Release (Security Hardening)
Overview
cryptopp-modern 2026.5.0 adds defence-in-depth hardening for the code paths behind CVE-2023-50980 and CVE-2023-50981. These are assessed as low severity because the published proof-of-concept inputs for both CVEs are already blocked from 2025.11.0 onward; this release tightens the same paths against malformed input that could previously progress too far before being rejected.
A version-metadata fix is also included so that CMake and cryptest.exe V report the correct release version (Issue #23).
Security Hardening
CVE-2023-50980: BERDecodeGF2NP
Component: F(2^m) curve parameter decoder
Issue: The DER decoder for F(2^m) curve parameters previously accepted invalid reduction polynomial exponents and allowed m values up to 2^32. That meant malformed input could reach PolynomialMod2::Trinomial or Pentanomial, where the runtime checks are deliberately relaxed for ECIES<EC2N> compatibility. Separately, m was unbounded and went straight into PolynomialMod2's bit-vector allocation.
Change: Validation moved to the DER boundary in BERDecodeGF2NP, requiring strict ordering (0 < t1 < m for trinomial, 0 < k1 < k2 < k3 < m for pentanomial) and capping the field degree at MAX_GF2N_FIELD_DEGREE = 4096. The cap covers B-571 with substantial headroom.
CVE-2023-50981: InvertibleRabinFunction::BERDecode
Component: Rabin private-key DER decoder
Issue: The Rabin private-key decoder checked m_p and m_q for primality with CRYPTOPP_ASSERT, which is compiled out in release builds. A non-prime m_p or m_q could then reach CalculateInverse, where ModularSquareRoot's Jacobi search loop can spin indefinitely on a non-prime modulus.
Change: The primality checks now throw BERDecodeError at runtime. CalculateInverse keeps its defensive CRYPTOPP_ASSERT as a double-check.
Cost: One additional IsPrime call per private-key load. In local testing this is approximately 500ms on a 2048-bit modulus. This is on a key-load path, not a hot one.
CVE-2023-50981: ModularSquareRoot iteration cap
Component: Tonelli-Shanks square root
Issue: ModularSquareRoot assumes a prime modulus. Its non-residue search and outer Tonelli-Shanks loop were both unbounded. On a non-prime p, either loop could spin indefinitely, while the CRYPTOPP_ASSERT(IsPrime(p)) guard is compiled out in release builds.
Change: Both loops are now capped at MAX_MODULAR_SQRT_ITERATIONS = 10000, throwing InvalidArgument when exceeded. For valid prime moduli this should not get close to the cap.
Other Fixes
Issue #23: Version metadata drift
CMakeLists.txt and include/cryptopp/config_ver.h had drifted from the released version. CMake reported v2025.12.0 and cryptest.exe V reported 2026.3.0. Both are now bumped to 2026.5.0. Release tooling has been updated so this should not recur.
References
Upgrade Notes
No breaking API changes.
Callers loading hand-rolled malformed F(2^m) parameters or non-prime Rabin private keys will now throw BERDecodeError where they previously loaded without error.
2026.4.0
2026.4.0 Release Notes
Release Date: April 2026
Release Type: Minor Release (Security Fix)
Overview
cryptopp-modern 2026.4.0 fixes Crypto++ Issue #1348, a canonicality bug in Ed25519 verification where public keys with y >= p were accepted.
Security Fix
Issue #1348: Ed25519 Accepts Non-Canonical Public Keys
Component: Ed25519 signature verification and public-key validation
Issue: ed25519PublicKey::Validate() returned true unconditionally, and the Donna verifiers unpacked public keys without checking canonicality. Per RFC 8032, the encoded y coordinate must be less than p = 2^255 - 19. Without this check, y = p + 1 and similar aliases were accepted as the identity point. Multiple byte encodings mapped to one group element.
Severity: Low. Conformance issue, no forgery risk. Matters where raw pubkey bytes are authoritative: pinning, allowlists, dedup, audit trails, interop with stricter verifiers.
Affected Versions: All versions prior to 2026.4.0
Changes
src/pubkey/xed25519.cpp:IsCanonicalYhelper;Validate()now
rejects y >= psrc/pubkey/donna_32.cpp/donna_64.cpp:ed25519_pubkey_is_canonical
helper; verify path rejects y >= p before unpackingsrc/test/validat9.cpp: regression test covering y = 1, y = p - 1
(canonical) and y = p, y = p + 1, y = 2^255 - 1 (non-canonical)
against the RFC 8032 witness signature
References
Upgrade Notes
ed25519PublicKey::Validate() is stricter. Code that relied on it always returning true will see false for non-canonical keys. Keys produced by compliant implementations are unaffected.
2026.3.0
cryptopp-modern 2026.3.0 Release Notes
Release Date: 1 March 2026
Start here:
- Announcement: #18
- Docs: https://cryptopp-modern.com/docs/
- ML-KEM API: https://cryptopp-modern.com/docs/api/pqc/mlkem/
- ML-DSA API: https://cryptopp-modern.com/docs/api/pqc/mldsa/
- SLH-DSA API: https://cryptopp-modern.com/docs/api/pqc/slhdsa/
- X-Wing API: https://cryptopp-modern.com/docs/api/pqc/xwing/
Post-Quantum Cryptography
- ML-KEM (FIPS 203) - Key encapsulation: ML-KEM-512, ML-KEM-768, ML-KEM-1024
- ML-DSA (FIPS 204) - Digital signatures: ML-DSA-44, ML-DSA-65, ML-DSA-87
- SLH-DSA (FIPS 205) - Stateless hash-based signatures: all 12 parameter sets (SHA2/SHAKE, 128/192/256, fast/small)
- X-Wing - Hybrid KEM combining X25519 and ML-KEM-768 (IETF draft-connolly-cfrg-xwing-kem)
Validation and integration:
- Known-answer tests (KATs) using published NIST ACVP test vectors and IETF KAT vectors (62 total)
- ASN.1/DER key encoding
- cryptest integration (validation and benchmarks)
Other Changes
- GNUmakefile - Added BUILD flag for release, debug, and relwithdebinfo modes
- Security hardening - Constant-time operations, stack zeroisation, and input validation across PQC and Argon2
Build System
Build system support added for all PQC algorithms:
- nmake, MSBuild, CMake, GNUmakefile, and Visual Studio filters
Migration
All new algorithms use the standard CryptoPP namespace. No breaking changes to existing APIs.