Skip to content

feat(crypto): randomFillSync + subtle.encrypt/decrypt (AES-GCM) — unblock axios + jose#952

Merged
proggeramlug merged 1 commit into
mainfrom
worktree-agent-ac1a5f684e2e0d786
May 17, 2026
Merged

feat(crypto): randomFillSync + subtle.encrypt/decrypt (AES-GCM) — unblock axios + jose#952
proggeramlug merged 1 commit into
mainfrom
worktree-agent-ac1a5f684e2e0d786

Conversation

@proggeramlug
Copy link
Copy Markdown
Contributor

Summary

  • Adds crypto.randomFillSync(buffer, offset?, size?) to the manifest + runtime — required by axios (Uint32Array ID generation). Handles both BufferHeader (Buffer/Uint8Array) and TypedArrayHeader (Uint32Array etc) call shapes; optional offset/size are clamped to byte length per Node's lenient bounds.
  • Adds crypto.subtle.encrypt(...) / crypto.subtle.decrypt(...) — AES-GCM only this pass, the surface jose's gcmEncrypt/gcmDecrypt reach for. importKey extended to accept either the object form { name: "AES-GCM" } or the string shorthand "AES-GCM" (jose passes the shorthand at importKey time).
  • AES-CBC, AES-CTR, AES-KW, RSA-OAEP encrypt/decrypt and subtle.generateKey/wrapKey/unwrapKey/deriveKey remain 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 -- --check clean
  • cargo build --release clean
  • cargo 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 pass
  • test-files/test_crypto_randomFillSync.tsUint8Array(16) + Uint32Array(8) both fill correctly; returned buffer is identity-equal
  • test-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)
  • axios smoke (import axios from "axios" with perry.compilePackages: ["axios"]) — was: Error: crypto.randomFillSync is not implemented — now advances past, stops at zlib.constants (separate gap)
  • jose smoke (import * as jose from "jose" with perry.compilePackages: ["jose"]) — was: Error: crypto.subtle.encrypt is not implemented — now advances past, stops at crypto.subtle.generateKey (out of scope per Web Crypto: implement crypto.subtle.digest / importKey / sign (HMAC-SHA-256, SHA-256) #561)

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).
@proggeramlug proggeramlug force-pushed the worktree-agent-ac1a5f684e2e0d786 branch from 2349127 to a2048c4 Compare May 17, 2026 19:51
@proggeramlug proggeramlug merged commit be7a772 into main May 17, 2026
5 of 9 checks passed
@proggeramlug proggeramlug deleted the worktree-agent-ac1a5f684e2e0d786 branch May 17, 2026 19:51
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant