Zupt v2.1.1: fix cross-arch build issues, eliminate UB, improve Android/Termux support
- Removed all shipped .o files from tarball (fixes aarch64/Termux linker errors with x86_64 objects) - Added arch-safety guard in Makefile to auto-detect and remove incompatible .o files - Switched default compiler from gcc to cc (Termux uses clang) - Skipped -lpthread on Android (bionic provides pthreads) - Added Android detection via uname -o - Fixed Keccak UB: ROL64(x,0) no longer expands to undefined x >> 64 - Achieved zero UBSan/ASAN issues across all PQ crypto paths - Moved sys/syscall.h include to file scope with proper __linux__ guard Release stats: - 73 files, 159KB, zero .o artifacts - 70/70 tests passing - Fully clean under ASAN + UBSan Note: full-disk encryption (--disk) deferred to v2.2.0 (requires raw device I/O, sparse detection, and privilege handling)
This commit is contained in:
parent
79213bdc7b
commit
2b68548e93
7 changed files with 66 additions and 10 deletions
17
CHANGELOG.md
17
CHANGELOG.md
|
|
@ -5,6 +5,22 @@ Format follows [Keep a Changelog](https://keepachangelog.com/).
|
|||
|
||||
---
|
||||
|
||||
## [2.1.1] — 2026-04-06
|
||||
|
||||
### Fixed — Multi-Architecture Build
|
||||
- **Stale object files removed from distribution.** Previous tarballs shipped pre-compiled x86_64 `.o` files. On aarch64 (Termux, Raspberry Pi, etc.) the linker failed with `ld.lld: error: src/zupt_xxh.o is incompatible with aarch64linux`. All `.o` files now excluded from release tarballs.
|
||||
- **Arch-safety guard in Makefile.** Detects pre-compiled `.o` files from a different architecture via `file(1)` and auto-removes them before linking. Prevents silent link failures if stale objects are accidentally present.
|
||||
- **Termux/Android compatibility.** Default compiler changed from `gcc` to `cc` (Termux ships clang). `-lpthread` skipped on Android/Termux (bionic libc has pthreads built-in, detected via `uname -o`).
|
||||
- **`sys/syscall.h` include moved to file top** in `zupt_crypto.c`. Was inside function body (non-standard C, rejected by some compilers).
|
||||
|
||||
### Fixed — Undefined Behavior
|
||||
- **Keccak ROL64 shift-by-64 UB.** `ROL64(x, 0)` expanded to `(x >> 64)` which is undefined behavior in C. The Keccak rotation table has `KECCAK_ROT[0] = 0`, triggering this on every Keccak-f[1600] call (SHA3-256, SHA3-512, SHAKE-128, SHAKE-256, ML-KEM-768). Fix: `ROL64` now returns `x` unchanged when `n == 0`. Confirmed zero UBSan violations across all PQ paths.
|
||||
|
||||
### Tests
|
||||
- 70/70: 11 VV + 13 NIST + 22 regression + 14 MT + 10 PQ. ASAN + UBSan clean (zero violations).
|
||||
|
||||
---
|
||||
|
||||
## [2.1.0] — 2026-04-05
|
||||
|
||||
### Upgraded — VaptVupt 1.4.0 Codec
|
||||
|
|
@ -243,6 +259,7 @@ All 4 `.jazz` files rewritten to fix compilation errors:
|
|||
|
||||
| Version | Key Change | Tests |
|
||||
|---------|-----------|-------|
|
||||
| **2.1.1** | Termux/Android build fix, arch-safety guard, Keccak UB fix, no stale .o in tarballs | 70 PASS |
|
||||
| **2.1.0** | VaptVupt 1.4.0: cross-block dictionary, context prefetch, faster adaptive window, integration API | 70 PASS |
|
||||
| **2.0.0** | VaptVupt 1.1.0 codec, auto codec detection, all 5 Jasmin wired, AVX SIGILL fix, multi-arch, copy_match fix, litlen overflow fix | 70 PASS |
|
||||
| **1.5.5** | Man page install, V=1 verbose, LDFLAGS/PIE, rpmlint, multi-arch Makefile | 53+13 PASS |
|
||||
|
|
|
|||
38
Makefile
38
Makefile
|
|
@ -1,6 +1,7 @@
|
|||
# Zupt v2.0.0 — Makefile with VaptVupt codec + Jasmin integration
|
||||
# Zupt v2.1.1 — Makefile with VaptVupt codec + Jasmin integration
|
||||
#
|
||||
# Multi-architecture: builds on x86_64, aarch64, armhf, ppc64le, s390x, riscv64.
|
||||
# Tested on: Linux, macOS, Windows (MSYS2), Termux (Android aarch64).
|
||||
# Jasmin CT crypto: x86_64 only (C fallback on all other architectures).
|
||||
# AVX2 SIMD decode: x86_64 only (NEON on aarch64, scalar elsewhere).
|
||||
#
|
||||
|
|
@ -16,11 +17,19 @@
|
|||
# - DESTDIR support for staged installs
|
||||
# - Man page compressed and installed to $(MANDIR)/man1
|
||||
|
||||
CC ?= gcc
|
||||
CC ?= cc
|
||||
CFLAGS ?= -Wall -Wextra -O2 -std=c11
|
||||
CFLAGS += -Iinclude -Isrc
|
||||
LDFLAGS ?=
|
||||
LDLIBS ?= -lm -lpthread
|
||||
LDLIBS ?= -lm
|
||||
|
||||
# pthreads: link -lpthread on Linux/BSD, skip on Android/Termux (bionic built-in)
|
||||
ifeq ($(shell uname -o 2>/dev/null),Android)
|
||||
# Termux/Android: pthreads built into bionic libc
|
||||
else
|
||||
LDLIBS += -lpthread
|
||||
endif
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
BINDIR ?= $(PREFIX)/bin
|
||||
MANDIR ?= $(PREFIX)/share/man
|
||||
|
|
@ -103,6 +112,29 @@ VV_PLAIN_OBJS = src/vv_ans.o src/vv_huffman.o src/vaptvupt_api.o
|
|||
ZUPT_OBJS = $(patsubst %.c,%.o,$(ZUPT_SOURCES))
|
||||
ALL_OBJS = $(ZUPT_OBJS) $(VV_SIMD_OBJS) $(VV_PLAIN_OBJS)
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# ARCH-SAFETY GUARD
|
||||
#
|
||||
# If pre-compiled .o files from a different architecture are present
|
||||
# (e.g. x86_64 .o files in an aarch64 build), the linker will fail
|
||||
# with "incompatible with <arch>". Detect and remove stale objects.
|
||||
# This happens when tarballs accidentally include build artifacts.
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
STALE_OBJS := $(wildcard src/*.o jasmin/*.o)
|
||||
ifneq ($(STALE_OBJS),)
|
||||
# Check if any existing .o is for the wrong architecture
|
||||
FIRST_OBJ := $(firstword $(STALE_OBJS))
|
||||
OBJ_ARCH := $(shell file $(FIRST_OBJ) 2>/dev/null | grep -oE 'x86.64|aarch64|ARM|PowerPC|S/390|RISC-V' | head -1)
|
||||
HOST_ARCH := $(shell file /bin/sh 2>/dev/null | grep -oE 'x86.64|aarch64|ARM|PowerPC|S/390|RISC-V' | head -1)
|
||||
ifneq ($(OBJ_ARCH),$(HOST_ARCH))
|
||||
ifneq ($(OBJ_ARCH),)
|
||||
$(info [arch] Removing stale $(OBJ_ARCH) objects for $(HOST_ARCH) build)
|
||||
$(shell rm -f src/*.o jasmin/*.o)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# BUILD RULES
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
|
@ -290,8 +290,9 @@ All codecs are forward-compatible: archives created with any codec can be read b
|
|||
| v1.1–v1.4 | X25519 fix, NIST vectors, CPUID detection, Jasmin source files fixed |
|
||||
| v1.5 | Jasmin CT assembly linked (MAC verify + ML-KEM select active) |
|
||||
| v1.5.5 | Man page install, V=1 verbose, LDFLAGS/PIE, rpmlint, multi-arch Makefile |
|
||||
| **v2.1.1** | **Termux/Android build fix, arch-safety guard removes stale cross-arch .o, Keccak ROL64 UB fix, zero UBSan violations** |
|
||||
| v2.1 | VaptVupt 1.4.0: cross-block dictionary carry, context decode prefetch, faster adaptive window trial (2.6× encode), integration API |
|
||||
| v2.0 | VaptVupt 1.1.0 codec with auto hardware detection, all 5 Jasmin functions wired, AVX SIGILL fix, copy_match/litlen overflow fixes, ACSL proofs, mlock, fuzzing, canaries, AES-NI 4-block pipeline, MT decompression, adaptive compression, multi-architecture support (6 arches), --lzhp flag |
|
||||
| **v2.1** | **VaptVupt 1.4.0: cross-block dictionary carry, context decode prefetch, faster adaptive window trial (2.6× encode), integration API** |
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md) for detailed per-version changes.
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
| **v1.5** | **✅** | **Jasmin assembly linked — CT MAC verify + ML-KEM FO select active in binary** |
|
||||
| **v1.5.5** | **✅** | **Man page install, V=1 verbose, LDFLAGS/PIE, rpmlint, multi-arch Makefile** |
|
||||
| **v2.0** | **✅** | **VaptVupt 1.1.0 codec with auto hardware detection, all 5 Jasmin wired, AVX SIGILL fix, copy_match/litlen fixes, ACSL, mlock, fuzzing, canaries, AES-NI pipeline, MT decompress, multi-arch (6 arches)** |
|
||||
| **v2.1** | **✅ Current** | **VaptVupt 1.4.0: cross-block dictionary, context prefetch, faster adaptive window, integration API** |
|
||||
| **v2.1** | **✅** | **VaptVupt 1.4.0: cross-block dictionary, context prefetch, faster adaptive window, integration API** |
|
||||
| **v2.1.1** | **✅ Current** | **Termux/Android build fix, arch-safety guard, Keccak UB fix, no stale .o in tarballs** |
|
||||
|
||||
## Planned
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#define zupt_mkdir(p) mkdir(p, 0755)
|
||||
#endif
|
||||
|
||||
#define ZUPT_VERSION_STRING "2.1.0"
|
||||
#define ZUPT_VERSION_STRING "2.1.1"
|
||||
#define ZUPT_FORMAT_MAJOR 1
|
||||
#define ZUPT_FORMAT_MINOR 4
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#if defined(__linux__)
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════
|
||||
* RANDOM BYTES (OS-native CSPRNG — NO FALLBACK)
|
||||
|
|
@ -39,11 +43,12 @@ void zupt_random_bytes(uint8_t *buf, size_t len) {
|
|||
exit(1);
|
||||
#else
|
||||
/* Linux/macOS/BSD: try getrandom(2) first, then /dev/urandom */
|
||||
#if defined(__linux__) && defined(SYS_getrandom)
|
||||
#include <sys/syscall.h>
|
||||
#if defined(__linux__)
|
||||
#if defined(SYS_getrandom)
|
||||
ssize_t r = syscall(SYS_getrandom, buf, len, 0);
|
||||
if (r == (ssize_t)len) return;
|
||||
#endif
|
||||
#endif
|
||||
FILE *f = fopen("/dev/urandom", "rb");
|
||||
if (f) {
|
||||
size_t r = fread(buf, 1, len, f);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static const int KECCAK_PI[25] = {
|
|||
14, 24, 9, 19, 4
|
||||
};
|
||||
|
||||
#define ROL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
|
||||
#define ROL64(x, n) ((n) ? (((x) << (n)) | ((x) >> (64 - (n)))) : (x))
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════
|
||||
* KECCAK-f[1600] PERMUTATION (24 rounds)
|
||||
|
|
|
|||
Loading…
Reference in a new issue