The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

zucrypt 0.1.0

First release, and the first on CRAN. A focused set of cryptographic primitives over raw vectors, backed by a vendored, pinned crypto library, published to R and to C. The seven R functions are stable, and the static archive is frozen as ABI 1, after its first consumer – zuxlsx’s decryption of password-protected workbooks – was built and tested against it. The registered table is experimental (see “C interface” below).

R interface

Seven functions, and deliberately no more:

Failures are R conditions classed c(<specific>, "zucrypt_error", "error", "condition"), mapped from the C status by enumerator name rather than by number. Every condition carries algorithm and native_status fields; for AES, algorithm names the cipher ("aes-256-cbc"), or "aes-cbc" when the key is what is wrong. No message ever contains a key, an IV or plaintext.

Fixed before the tag, from the package review in #51:

Renamed before release (#56): the CBC pair was crypt_aes_cbc_encrypt() and crypt_aes_cbc_decrypt() during development. The _nopad suffix names the difference from openssl::aes_cbc_encrypt(), which pads, so that code moved from openssl by changing a prefix can never silently get the padding back as plaintext. The unsuffixed names are reserved for an openssl-compatible padded pair. The C interface (zuc_aes_*()) is unchanged.

C interface

Both shapes the zu* family consumes siblings by, at ZUCRYPT_ABI_VERSION 1, with different stability (?zucrypt_c_api):

Settled before the freeze, from the first consumer’s report (#43):

inst/include/zucrypt.h compiles standalone as C99 against <stddef.h> and <stdint.h>, and names no backend type: a consumer never has to reproduce this package’s build configuration.

Both shapes are exercised on Linux, macOS and Windows by consumer fixture packages, as a real consumer would use them: - the table through an Imports: + LinkingTo: package that calls every entry; - the archive through a LinkingTo-only package whose configure resolves libzucrypt.a.

The archive fixture’s checks cover: - linking through a library path that contains a space; - exporting no backend symbol from its own shared object; - running beside zucrypt in the same R session, in either load order; - running with zucrypt not installed at all.

Settled before any consumer linked the ABI (design revision 3):

Backend

Vendored TF-PSA-Crypto 1.1.1, an LTS release, trimmed to 113 files — the dependency closure of the sources that carry a symbol under this package’s configuration. Installation needs a C99 compiler and nothing else: no system cryptographic library, no CMake, no Python or Perl, and no network access.

AES runs on the CPU’s AES instructions — AES-NI on x86, the Cryptography Extension on 64-bit Arm — chosen at run time, and on a software fallback where the CPU has neither. The backend’s own security policy warns that the software fallback leaks key material through cache timing; crypt_info()$build_flags$aes_implementation reports which path a machine uses, and ?crypt_aes_cbc_nopad explains when that matters. Every path produces the same bytes. (Until the review in #51 hardware AES was off everywhere.)

Upstream symbols are hidden. The installed shared object exports exactly one symbol, R_init_zucrypt, so an independently vendored copy of the same library in another package cannot bind to this one, and no OpenSSL-ABI name is exported beside the libcrypto other packages link.

Supported platforms

Checked on every push: Linux, macOS (ARM64) and Windows; R release, oldrel-1 and 4.1; CRAN’s clang-23 and GCC-16 containers; the no-Suggests flavour; LTO; rchk and gctorture; ASan, UBSan, valgrind and GCC’s -fanalyzer. Weekly: i386, musl and aarch64 builds that run the test suite and fail on a WARNING, and a sweep that fails each allocation the crypt_*() calls make, one run per allocation — about 250 of them, of which some 77 land in zucrypt’s own code — checking that each surfaces as an error rather than a crash or a wrong answer.

Correctness is checked against published vectors — FIPS 180-2, RFC 2202, RFC 4231, RFC 6234 and NIST SP 800-38A, including the one-million-byte messages and HMAC keys longer than the block — every one of which is also recomputed with OpenSSL, an implementation sharing no code with the vendored backend. Inputs up to 4 MiB are compared with OpenSSL directly, and the iterated hash Office agile encryption uses is checked against msoffcrypto-tool.

Not in this release

Deliberate omissions, each waiting on a concrete consumer rather than on effort: authenticated encryption, password-based key derivation (PBKDF2, HKDF, Argon2), random byte generation, signatures, key serialization, file hashing and connection wrappers. There is no encrypt_file(password = ), and there will not be one without a specified authenticated format, a nonce policy and a key derivation step.

Office/Excel decryption is not here either. It belongs to zuxlsx, which consumes this package.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.