Skip to content

feat: add raw key formats (raw-public, raw-private, raw-seed)#1034

Merged
boorad merged 4 commits into
mainfrom
feat/raw-key-formats
May 7, 2026
Merged

feat: add raw key formats (raw-public, raw-private, raw-seed)#1034
boorad merged 4 commits into
mainfrom
feat/raw-key-formats

Conversation

@boorad
Copy link
Copy Markdown
Collaborator

@boorad boorad commented May 7, 2026

Summary

Adds Node-compatible raw key formats — raw-public, raw-private, and raw-seed — across KeyObject.export, createPublicKey, createPrivateKey, generateKeyPair, and crypto.diffieHellman. Mirrors Node's lib/internal/crypto/keys.js flow.

Changes

  • Native (HybridKeyObjectHandle): 5 new export methods (exportRawPublic, exportRawPrivate, exportRawSeed, exportECPublicRaw, exportECPrivateRaw) and 3 init methods (initRawPublic, initRawPrivate, initRawSeed), with OpenSSL 3.5+ guards for PQC seed paths.
  • TypeScript API: Raw formats wired into KeyObject.export(), createPublicKey/createPrivateKey (raw imports require asymmetricKeyType + namedCurve for EC), generateKeyPair (CFRG, EC, SLH-DSA), and diffieHellman raw key inputs.
  • Type narrowing: Added KeyObjectKeyPair overloads to generateKeyPairSync so the no-encoding case returns typed PublicKeyObject/PrivateKeyObject. Widened KeyPairType to include PQCKeyPairType.
  • Buffer source: Raw exports return @craftzdog/react-native-buffer Buffer instances (matches RNQC's wider Buffer convention).
  • Defensive: DH/DSA/RSA explicitly reject raw formats with clear errors.
  • Tests: 8 new tests in example/src/tests/keys/raw_key_formats.ts covering X25519, Ed25519, EC P-256 (compressed + uncompressed), ML-DSA-44 seed export, and round-trip import/export.

Fixes #1010

Test plan

  • bun tsc clean across both packages
  • bun ios — example app keys.rawFormats suite passes
  • bun android — verify the same suite on Android

boorad added 4 commits May 6, 2026 20:50
…vateKey / generateKeyPair / diffieHellman (#1010)

Adds Node.js-compatible 'raw-public', 'raw-private', and 'raw-seed' key formats
across the asymmetric key surface:

- KeyObjectHandle native: exportRawPublic / exportRawPrivate / exportRawSeed,
  exportECPublicRaw(compressed), exportECPrivateRaw, plus initRawPublic /
  initRawPrivate / initRawSeed for raw imports keyed by asymmetricKeyType
  (with namedCurve for EC).
- KeyObject.export now accepts {format: 'raw-public' | 'raw-private' | 'raw-seed'}
  for EC, OKP (Ed25519/Ed448/X25519/X448), ML-DSA, ML-KEM and SLH-DSA keys.
  EC raw-public additionally accepts {type: 'compressed' | 'uncompressed'}.
- createPublicKey / createPrivateKey accept the matching raw input objects
  ({key, format, asymmetricKeyType, namedCurve?}).
- generateKeyPair / generateKeyPairSync accept raw output formats in
  publicKeyEncoding / privateKeyEncoding for EC, OKP, ML-DSA, ML-KEM and
  SLH-DSA. RSA / DSA / DH explicitly reject raw formats.
- Top-level diffieHellman({publicKey, privateKey}) now also accepts raw key
  inputs for EC and CFRG curves; DH KeyObjects throw a clear "not supported"
  error pending future work.
Runs `bun specs` so the generated HybridKeyObjectHandleSpec base class
declares the new exportRawPublic / exportRawPrivate / exportRawSeed /
exportECPublicRaw / exportECPrivateRaw / initRawPublic / initRawPrivate /
initRawSeed methods as virtual. Without this the iOS/Android build fails
with "only virtual member functions can be marked 'override'".
KeyObject.export({format:'raw-public'|'raw-private'|'raw-seed'}) now uses
the same Buffer class the package re-exports (@craftzdog/react-native-buffer)
instead of the 'buffer' polyfill — so consumers' `instanceof Buffer` checks
match. generateKeyPair / generateKeyPairSync raw outputs are now wrapped in
Buffer too, instead of returning bare ArrayBuffer, so callers don't need
Buffer.from() wrapping for comparison or Buffer-typed APIs.
- Narrow generateKeyPairSync return type with KeyObjectKeyPair overloads
- Widen KeyPairType to include PQCKeyPairType so PQC names typecheck
- Remove as unknown as casts in raw_key_formats tests
- Drop misleading isEcCurveName helper; rely on EC_KEY_new_by_curve_name
- Move (void)keyId into the OpenSSL <3.5 branch in supportsRawSeed
- Use ToNativeArrayBuffer(ptr,size) overload for raw exports
- Collapse numericFormat/numericType into coerceToNumeric
- Replace as KFormatType / as KeyEncoding casts with runtime narrowing
@boorad boorad self-assigned this May 7, 2026
@vercel
Copy link
Copy Markdown

vercel Bot commented May 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
react-native-quick-crypto Ready Ready Preview, Comment May 7, 2026 1:46am

Request Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

🤖 End-to-End Test Results - Android

Status: ✅ Passed
Platform: Android
Run: 25471306479

📸 Final Test Screenshot

Maestro Test Results - android

Screenshot automatically captured from End-to-End tests and will expire in 30 days


This comment is automatically updated on each test run.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

🤖 End-to-End Test Results - iOS

Status: ✅ Passed
Platform: iOS
Run: 25471306483

📸 Final Test Screenshot

Maestro Test Results - ios

Screenshot automatically captured from End-to-End tests and will expire in 30 days


This comment is automatically updated on each test run.

@boorad boorad merged commit 33906ca into main May 7, 2026
10 checks passed
@boorad boorad deleted the feat/raw-key-formats branch May 7, 2026 02:15
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.

Raw key formats across KeyObject / createPublicKey / createPrivateKey / generateKeyPair / diffieHellman

1 participant