Repository navigation
enhancement: port CryptX cryptographic toolkit #1220
Description
Summary
Port the CPAN CryptX distribution to PerlOnJava so Perl code that depends on its cryptographic APIs can run without native XS code.
Motivation
CryptX is currently a major compatibility blocker for PerlOnJava applications using JWT, OAuth, OpenID Connect, SAML, XML signatures, ACME, encrypted credentials, and related protocols.
The immediate observed case is WebService::GoogleAPI::Client 0.27. Its dependency chain includes Mojo::JWT, which directly loads CryptX for JWT signing and verification. PerlOnJava's CPAN installer reports that CryptX contains XS/C code and cannot compile it. The resulting module load failure aborts all three upstream test programs before any subtests run.
CryptX also has a substantial reverse-dependency surface. Examples include Mojo::JWT, Crypt::JWT, XML::Sig, Net::SAML2, OIDC::Client, Net::ACME2, Net::SSH::Perl, KeePass::Reader, and encryption/database modules.
Proposed scope
Implement the Perl-facing CryptX API using Java-backed cryptography while preserving the upstream module names and behavior wherever practical.
At minimum, investigate and support the APIs required by Mojo::JWT:
Crypt::Miscbase64url helpers- HMAC signing and verification used by HS JWT algorithms
- RSA signing and verification used by RS JWT algorithms
- key and digest handling needed by the supported JWT algorithms
Then expand coverage to the rest of the distribution's public families as feasible:
Crypt::Digest::*Crypt::Mac::*Crypt::Cipher::*andCrypt::Mode::*Crypt::AuthEnc::*Crypt::PK::*Crypt::KeyDerivationCrypt::PRNGCrypt::MiscCrypt::ASN1
The implementation should use Java standard cryptography or existing project dependencies where they provide compatible primitives. It should not silently downgrade security or change algorithm semantics. Algorithms unavailable from the Java provider should fail explicitly and consistently with the Perl API.
Suggested approach
- Obtain and inspect the upstream
CryptXPerl and XS/C sources, preserving license and attribution. - Separate the pure-Perl wrappers and constants from the XS entry points.
- Implement the required XS-facing methods in Java, using existing PerlOnJava module registration patterns.
- Prefer standard Java cryptographic providers and well-defined encoding behavior.
- Add a bundled module test suite derived from the upstream tests, beginning with the JWT-required surface.
- Compare every new test with native system Perl before using it as a compatibility oracle.
- Verify both JVM and interpreter backends.
- Test downstream modules, especially
Mojo::JWT,Mojo::JWT::Google, andWebService::GoogleAPI::Client.
Acceptance criteria
use CryptX,use Crypt::Misc, and the JWT-required CryptX modules load under both PerlOnJava backends.Mojo::JWTcan create and verify representative HS256 tokens with matching system-Perl results.- Supported RSA JWT operations have matching system-Perl results, including invalid-signature rejection.
- Base64url encoding/decoding handles padding, empty values, binary data, and malformed input consistently.
- Upstream or focused bundled tests cover success cases, malformed inputs, wrong keys, wrong algorithms, and context-sensitive return values.
WebService::GoogleAPI::Clientno longer aborts at module load solely becauseCryptXis unavailable.- Unsupported algorithms are reported clearly rather than producing incorrect cryptographic results.
- No native XS compilation is required for the supported port.
Related evidence
The CPAN tester failure is the WebService::GoogleAPI::Client 0.27 failure observed on 2026-09-02. Native system Perl can load CryptX and Mojo::JWT when the XS distribution is installed, while the PerlOnJava CPAN build explicitly skips CryptX's XS/C compilation.
Activity
fglock commentedon Sep 4, 2026
Additional downstream evidence: Noise v0.0.2
CPAN tester run
20260904-185312-10032attemptedNoisev0.0.2. Thedistribution itself is pure Perl and built successfully, but its required
crypto modules resolve to
CryptXv0.091:Crypt::AuthEnc::ChaCha20Poly1305Crypt::AuthEnc::GCMCrypt::Mac::HMACCrypt::PK::X25519PerlOnJava configured and built the CryptX Perl wrapper files, but cannot load
the native XS backend when Noise tests start:
All four Noise test programs (
t/00_compile.t,t/01_handshake.t,t/02_stream.t, andt/99_vectors.t) abort during module loading before anysubtests run. This is additional downstream verification of the CryptX port
blocker, not a Noise-specific failure.
Current MetaCPAN reverse-dependency metadata lists 46 unique distributions
referencing CryptX, including 43 unique direct runtime requirements:
https://fastapi.metacpan.org/v1/reverse_dependencies/module/CryptX?page=1
fglock commentedon Oct 1, 2026
Implementation approach and preliminary effort
Retain upstream Perl wrappers and implement their XS entry points using the existing Bouncy Castle dependencies and PerlOnJava module registration patterns. Factor reusable RSA key parsing and signing helpers from Crypt::OpenSSL::RSA; reuse digest, cipher and random-byte infrastructure where semantics match.
Estimates assume one engineer familiar with PerlOnJava and include testing and integration. Inspection of CryptX 0.091 found 125 Perl modules, 50 XS include files, approximately 450 XS entry points and 164 upstream test files.
The main compatibility work concerns arguments, return values, padding defaults, key encodings, streaming, cloning and errors. The current SecureRandom-backed Crypt::PRNG wrapper does not reproduce each named generator's state.
Validate supported APIs against system Perl and both PerlOnJava backends, retaining upstream tests. Include wrong-key and invalid-signature/tag cases. Target Mojo::JWT for the first milestone and all 38 HTTP::Request::Webpush tests for the second.
HTTP::Request::Webpush 0.15 is a confirmed downstream acceptance target: in CPAN tester run
20261001-123047-11054, system Perl passed all three test programs (38/38 tests), while PerlOnJava aborted before subtests because CryptX 0.091 had no Java XS implementation.fglock commentedon Oct 30, 2026
Additional CPAN evidence: Text::Shift 1.00
CPAN tester run
20261029-123650-2402failedText::Shift1.00 att/1.twhile loading its requiredCrypt::Cipherdependency from CryptX 0.091:The archived system-Perl oracle installed the native dependency and passed the complete CryptX suite (164 files, 27,296 tests) and Text::Shift (1 file, 1 test). This confirms another downstream load failure attributable to the unsupported CryptX XS backend.
A refreshed targeted MetaCPAN lookup via
dev/tools/cpan_port_priorities.plfound 55 unique released distributions referencing CryptX. Inspecting released/latest metadata and counting onlyruntime.requiresgives 49 unique runtime dependants, of which 29 have release dates in the last three years (cutoff 2023-10-30). Examples include Mail-DKIM2, File-SOPS, AWS-Signature-V4, Crypt-Age, Web-Authn, XML-Sig, Mojo-JWT, and Crypt-JWT. The raw lookup is available at https://fastapi.metacpan.org/v1/reverse_dependencies/module/CryptX?page=1.fglock commentedon Oct 30, 2026
State: released
Agent/session: Codex-20261030-cryptx-java-bridge
Scope: #1220 phase 1: CryptX bootstrap, encoding helpers, functional digest APIs, and HMAC using existing JCA/Bouncy Castle providers.
Work: feature/cryptx-java-bridge, commit e7f9f78, draft PR #1929 (#1929)
Checkpoint: 2026-10-30 08:32 UTC; phase 1 committed and published; draft PR is open on master.
Evidence: native system Perl focused oracle 12/12;
nice -n 19 makepassed with 3,056 tests, 0 failures, 3 skipped;JPERL_TEST_FILTER=CryptX timeout 1800 nice -n 19 make test-bundled-modulespassed the CryptX module test;nice -n 19 make check-linksreported 0 errors. Remote branch commit and tree match local commit/tree.Blocked by: none
Next: review PR #1929; continue stateful digest/MAC and RSA APIs as the next issue phase.
feat: add initial CryptX functional API bridge (#1220) (#1929)