Repository navigation
Releases: cabelo/libzupt
Release list
v1.0.14
What's Changed
libzupt 1.0.14
This release strengthens authentication, encrypted record validation, secure key handling, packaging, and build integration. Thank you @cristiancmoises
Highlights
- Improved encrypted record authentication and validation, rejecting malformed, reordered, repeated, oversized, or tampered records.
- Empty messages are now represented by authenticated records.
- Hardened POSIX private-key writes and fixed
SecureBuffercleanup during move operations. - Improved CMake package support for both shared and static consumers.
- Unified runtime and CMake version reporting.
- Strengthened release validation with tag/version checks, pinned GitHub Actions, read-only permissions, and measured test reporting.
- Source packages now generate level-9 solid
.zuptarchives with extraction verification and SHA-256 checksums. - Added English and Brazilian Portuguese documentation.
Validation
All 8 library tests passed with GCC 14 in Release mode and Clang 22 with UBSan. Shared and static consumer tests also passed after installation relocation.
Known Limitation
Removing complete trailing encrypted blocks may still leave a valid authenticated prefix because the current format does not authenticate the total message length or provide an authenticated end marker. Existing zero-byte ciphertexts are rejected and should be re-encrypted.
v1.0.13
Go example
- Added Go examples integrating libzupt’s C API through cgo.
- Included memory and file encryption/decryption, hybrid key management, random byte generation, and hashing.
- Added SecureBuffer examples for handling and zeroizing sensitive data.
- Added a build script and a single executable supporting all examples or individual runs.
- Documented prerequisites, build instructions, usage, and API reference.
v1.0.12
Integration with New C# Examples
libzupt now includes C# examples for .NET 8, demonstrating integration with its native library through the C API and P/Invoke. This addition simplifies the adoption of hybrid post-quantum cryptography in .NET applications, covering file and in-memory encryption and decryption, key generation and management, cryptographically secure random bytes, and hash computation.
The examples also demonstrate SecureBuffer for securely wiping sensitive data from memory and include build and execution instructions.
v1.0.11
What's Changed
Rust Support
This release introduces Rust support for libzupt, allowing Rust applications to use libzupt's cryptographic features through safe and ergonomic Rust APIs.
The integration uses libzupt's existing C/C++ API through FFI, with bindings automatically generated at build time using bindgen.
Highlights
- Added Rust bindings for the libzupt C/C++ API
- Added a safe Rust wrapper with
Result<T, ZuptError>error handling - Automatic FFI binding generation using
bindgen - Support for both shared (
libzupt.so) and static (libzupt_static.a) linking - Added automated build script for libzupt + Rust examples
- Added complete Rust examples demonstrating the main cryptographic operations
Cryptographic Features Available from Rust
Rust applications can now access:
- Hybrid ML-KEM + X25519 key management
- Hybrid public/private key generation
- Public key extraction
- Key pair save/load operations
- In-memory encryption and decryption
- File encryption and decryption
- Cryptographically secure random byte generation
- SHA-256 hashing
- SHA3-512 hashing
- Secure memory wiping
- Secure buffers with automatic memory zeroization
SecureBuffer
A new Rust SecureBuffer abstraction provides safer handling of sensitive information in memory.
Sensitive data can be manually zeroized and is also automatically wiped when the buffer is dropped, helping reduce the risk of cryptographic material remaining in process memory.
New Rust Examples
Five complete examples are now available:
example_basic— in-memory encryption/decryption and wrong-key rejectionexample_file— file encryption and decryptionexample_keygen— key generation, persistence, loading, and public-key exportexample_random— secure random generation, SHA-256, SHA3-512, and key derivationexample_secure_buffer— secure handling and automatic zeroization of sensitive memory
Build
Rust examples can be built with:
cd examples_rust
./build.shor directly with Cargo:
cargo build --releaseIndividual examples can be executed with:
cargo run --release --example example_basic🚀 Why It Matters
libzupt can now be integrated directly into the growing Rust ecosystem while preserving the existing high-performance cryptographic implementation.
This makes it easier to build applications, services, security tools, edge software, and infrastructure in Rust using libzupt's hybrid post-quantum cryptography.
Rust + Post-Quantum Cryptography + libzupt.
v1.0.10
What's Changed
Add PHP FFI examples for libzupt
This release is in honor of my friend @galvao.
- Add a reusable PHP FFI wrapper for the libzupt C ABI
- Add examples for in-memory encryption, file encryption, key management, random byte generation, hashing, and secure buffers
- Add automatic shared library path detection with support for
LIBZUPT_PATH - Add a script to run all PHP examples
- Add English documentation with build, configuration, usage, security, and platform notes
- Document the current hybrid key and encryption header sizes
- Prevent execution on Windows until the ABI exposes a portable memory-release function
Full Changelog: v1.0.9...v1.0.10
v1.0.9
What's Changed
v1.0.9
New example
- Added Node.js examples demonstrating the use of the main libzupt functionalities, making it easier to understand, validate, and integrate the library into new projects.
Security fixes: (Thank you all fixes @cristiancmoises )
-
Stop staging keys in predictable /tmp paths. The in-memory encrypt/decrypt path wrote the public key (and, worse, the private key) to /tmp/zupt_{pub,priv}_ just to hand a path to the file-based init functions. That was a symlink-attack vector and it defeated the library's own mlock protection by leaving private key material on disk. Added zupt_hybrid_encrypt_init_mem / zupt_hybrid_decrypt_init_mem, which parse the key straight from the caller's buffer; the C wrapper now uses them and never touches disk.
-
Create private key files with 0600 instead of the umask default. Applied to both the C path (zupt_hybrid_keygen, via open+fdopen) and the C++ path (KeyGenerator::saveKeyPair, via open+fchmod before the ofstream), so a freshly generated key is never briefly world-readable.
-
Fix sign-extension/UB when parsing the per-block payload length on decrypt. Each byte promoted to int, so
byte << 24is undefined and sign-extends when the top bit is set, yielding a bogus huge block_len. Cast each byte to size_t before shifting.
Cleanup:
- Remove dead, incorrect zupt_hybrid_derive_keys (it ignored the X25519 shared secret and the ml_pk argument, so it produced keys the decrypt side could never reproduce) and the unused zupt_hybrid_decrypt_derive_keys.
Refactored the file-based init functions to share an encaps/decaps core with the new in-memory variants, so there is no duplicated KDF logic. Build is clean (no warnings) and all five test suites pass.
v1.0.8
v1.0.7
v1.0.6
v1.0.5
Update zuptcore
- Resolved high-severity vulnerabilities by removing TOCTOU filesystem races via fd-first open()/fstat() patterns and enforcing non-optimizable secure memory zeroization for cryptographic material.
- TOCTOU in get_device_size() (lines 87, 115): Replaced stat(path) → open(path) with open(path) first → fstat(fd). The fd is bound to the inode at open time and can't be swapped by an attacker.
- Dead-store memset in zupt_x25519() (line 318): Replaced memset(e, 0, 32) with a volatile pointer loop (volatile uint8_t *ve = e; for(...) ve[i] = 0;). The compiler must emit these stores because volatile reads/writes have observable side effects.
- TOCTOU in zupt_disk_restore() (line 601): Replaced stat(target_path) → open(target_path) with open() first → fstat(fd) → fcntl(fd, F_SETFL, O_SYNC) for block devices. Same open-then-classify pattern as the get_device_size fix.
- Verified: 78/78 tests (70 core + 8 disk), ASAN clean, from-scratch tarball build + 100MB ext4 LZHP+PQ roundtrip byte-exact, e2fsck clean
- Shared write_enc_header() eliminates format mismatches across all encryption paths.
- Solid compression now fully supports PQ encryption.
- Disk restore rewritten with block device O_SYNC I/O.
- LZHP disk backups now correctly apply prediction encoding to prevent silent data corruption.
- LZHP Prediction Encoding in Disk Backup
- Fixed zupt_disk_backup() skipping the zupt_predict_encode() step for byte-prediction (pred_active=1).
- Ensures correct prediction encoding before compression to prevent corruption on restore.
- Allocates temporary buffer for prediction-encoded data and frees it after compression.
- Disk backup archives no longer incorrectly set ZUPT_FLAG_SOLID.
- Each block archive is independent, avoiding extraction issues.
- Shared Encryption Header
- write_enc_header() extracted as shared function used by: `zupt_compress_fiprediction encoding to prevent silent data corruption.
- LZHP Prediction Encoding in Disk Backup
- Fixed zupt_disk_backup() skipping the zupt_predict_encode() step for byte-prediction (pred_active=1).
- Ensures correct prediction encoding before compression to prevent corruption on restore.
- Allocates temporary buffer for prediction-encoded data and frees it after compression.
- Spurious SOLID Flag on Disk Archives
- Disk backup archives no longer incorrectly set ZUPT_FLAG_SOLID.
- Each block archive is independent, avoiding extraction issues.
- Shared Encryption Header
- write_enc_header() extracted as shared function used by: zupt_compress_files() zupt_compress_solid() zupt_disk_backup()
- Eliminates mismatches between different encryption paths.
- Block Device Restore I/O
- Uses POSIX raw I/O (open() + write() loop) with O_SYNC, fsync() + sync() for reliable block writes.
- Build Fixes for Termux/Android
- Improved architecture detection using $(CC) -dumpmachine with fallback to uname -m.
- Public API Adjustments
- zupt_w8(), zupt_w16le(), zupt_w64le() now non-static for shared usage.