feat(crypto): randomFillSync + subtle.encrypt/decrypt (AES-GCM) — unblock axios + jose#952
Merged
Merged
Conversation
Adds the three missing crypto manifest entries needed for axios +
jose to compile under perry.compilePackages:
- crypto.randomFillSync(buffer, offset?, size?) — required by axios.
Handles Buffer / Uint8Array (NaN-boxed POINTER_TAG form) AND
TypedArrayHeader (raw heap pointer in low 48 bits) so Uint32Array
is filled correctly. Optional offset/size accept undefined and are
clamped to byte length per Node's behavior.
- crypto.subtle.encrypt({ name: "AES-GCM", iv, additionalData? }, key, data)
- crypto.subtle.decrypt(...)
AES-GCM only this pass; AES-CBC / AES-CTR / RSA-OAEP follow-up.
importKey extended to recognize "AES-GCM" (string shorthand) and
{ name: "AES-GCM" } (object form jose uses at encrypt time).
192-bit AES-GCM intentionally rejected (not in aes-gcm 0.10 type set).
Adds two regression tests + four unit tests in webcrypto::tests.
Regenerates docs/api/perry.d.ts and docs/src/api/reference.md.
Validation: axios advances past `crypto.randomFillSync` (now stops at
`zlib.constants`), jose advances past `crypto.subtle.encrypt` (now
stops at `crypto.subtle.generateKey`, out of scope per #561).
2349127 to
a2048c4
Compare
This was referenced May 17, 2026
proggeramlug
added a commit
that referenced
this pull request
May 18, 2026
…e-success (#958) PR #952 added AES-GCM (and AES-CBC routing) support to crypto.subtle.encrypt, but the matching test in crates/perry-hir/tests/unimplemented_api_check.rs still asserted rejection. The test was failing on every PR rebased onto main since #952 landed. Inverts the assertion: the test now exercises the modern compile-success path so a regression in the lowering would still surface.
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
crypto.randomFillSync(buffer, offset?, size?)to the manifest + runtime — required by axios (Uint32ArrayID generation). Handles bothBufferHeader(Buffer/Uint8Array) andTypedArrayHeader(Uint32Array etc) call shapes; optionaloffset/sizeare clamped to byte length per Node's lenient bounds.crypto.subtle.encrypt(...)/crypto.subtle.decrypt(...)— AES-GCM only this pass, the surface jose'sgcmEncrypt/gcmDecryptreach for.importKeyextended to accept either the object form{ name: "AES-GCM" }or the string shorthand"AES-GCM"(jose passes the shorthand at importKey time).subtle.generateKey/wrapKey/unwrapKey/deriveKeyremain TODO follow-ups tracked alongside Web Crypto: implement crypto.subtle.digest / importKey / sign (HMAC-SHA-256, SHA-256) #561. The diagnostic message names the supported surface so callers see exactly what's missing.Test plan
cargo fmt --all -- --checkcleancargo build --releasecleancargo test --release -p perry-stdlib --lib webcrypto— 9/9 pass (4 new AES-GCM unit tests + 5 existing)cargo test --release -p perry-codegen --test manifest_consistency— 4/4 passtest-files/test_crypto_randomFillSync.ts—Uint8Array(16)+Uint32Array(8)both fill correctly; returned buffer is identity-equaltest-files/test_crypto_subtle_encrypt_decrypt.ts— AES-GCM-128 round-trip recovers plaintext byte-for-byte; ciphertext is 16 bytes longer than plaintext (the appended tag)import axios from "axios"withperry.compilePackages: ["axios"]) — was:Error: crypto.randomFillSync is not implemented— now advances past, stops atzlib.constants(separate gap)import * as jose from "jose"withperry.compilePackages: ["jose"]) — was:Error: crypto.subtle.encrypt is not implemented— now advances past, stops atcrypto.subtle.generateKey(out of scope per Web Crypto: implement crypto.subtle.digest / importKey / sign (HMAC-SHA-256, SHA-256) #561)