Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sodium Compat Laravel Package

paragonie/sodium_compat

Pure PHP polyfill for libsodium (Sodium crypto), transparently using the PHP extension when installed. Supports PHP 5.2.4+ and 32-bit integers in v1.x, with v2.x targeting PHP 8.1+.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • paragonie/sodium_compat is a pure-PHP polyfill for ext/sodium, not a framework-integrated library. Its design is transparent dispatch: if the native extension is loaded, every sodium_* call defers to it; if not, the library supplies a constant-time PHP implementation. It also exposes ParagonIE_Sodium_Compat::* for environments where the global functions aren't available.
  • In a Laravel 10/11 context (PHP 8.1+), ext/sodium has shipped as a core extension since PHP 7.2. So the polyfill's architectural role in a modern Laravel app is fallback insurance, not capability. The realistic value is: (a) unblocking packages that hard-require the sodium_* function surface in environments where the extension has been stripped (slim base images, some shared hosting, hardened php.ini), and (b) giving our own crypto service layer a single API that works across dev containers and production.
  • It is not a substitute for Laravel's own crypto stack. Illuminate\Encryption\Encrypter remains OpenSSL-based (AES-256-CBC/GCM); Hash:: remains bcrypt/argon2. Sodium Compat is relevant to targeted use cases we'd build ourselves: detached signatures for webhook/service-to-service auth, crypto_secretbox/crypto_box_seal for envelope-encrypted columns, crypto_generichash for keyed digests, crypto_kdf/crypto_kx for key derivation and session key exchange.
  • Strategic framing: the low composite score (32.87) with a higher opportunity score (59.11) is the signature of a utility dependency, not a feature bet. Treat this as dependency hygiene and risk control, not as a capability unlock.

Integration feasibility

  • Extremely low friction: composer require paragonie/sodium_compat, no service provider, no config, no migrations. The package registers an autoloader that conditionally defines the sodium_* functions only when missing.
  • The real integration work is not installation — it's the version/branch decision and the runtime assertion that we know which code path is executing.
  • Recommended Composer constraint differs by role, per the README: libraries/frameworks should use ">= 1"; applications should pin the specific version that matters to them. We are an application, so pin.

Technical risk

  • No independent, formal cryptographic audit. The README states this explicitly and offers to broker one for funded parties. For a security-sensitive deployment, this is the single largest risk item and needs an explicit, documented acceptance (or a decision to hard-require ext-sodium instead).
  • Silent performance degradation. If the extension is absent, the polyfill produces correct results — just far slower, especially for asymmetric operations. There is no error, no warning. This is the classic "successful but slow" production failure mode: latency creep and PHP-FPM worker saturation with no stack trace pointing at the cause.
  • Branch/version split is a live footgun. v1.x supports PHP 5.2.4–latest with 32-bit integers; v2.x (master) supports PHP 8.1+ only, no 32-bit, better performance and smaller footprint. A transitive package requiring ">= 1" will resolve to v2.x on our PHP 8.1+ hosts. If anything in the tree assumed 32-bit support or caps at <2, resolution or runtime behavior changes.
  • Public static mutable state. ParagonIE_Sodium_Compat::$fastMult is a process-global that toggles constant-time multiplication for speed. In a long-lived Laravel worker (Octane), any code that flips this affects all subsequent requests in that process. The README is explicit that this trades speed for security on processors without constant-time multiply. This should be banned by static analysis.
  • Data-quality caveat on the supplied metrics. "Dependents: 0" is almost certainly a measurement artifact — the README cites Joomla! and Magento as adopters. Verify actual footprint with composer why paragonie/sodium_compat against our real composer.lock before treating it as a leaf dependency.

Key questions

  1. Is ext-sodium compiled and enabled in every environment (local, CI, staging, prod FPM, queue workers, Octane workers, cron containers)? Verify with php -m | grep sodium and composer check-platform-reqs, not assumptions.
  2. Which existing dependencies already pull this in transitively, and at which resolved version? (composer why, composer depends, composer show paragonie/sodium_compat)
  3. Do we have any compliance/audit obligation (SOC 2, PCI, internal crypto standard) that mandates independently audited primitives? If yes, the polyfill is disallowed and the answer is "enforce the extension, add ext-sodium to require."
  4. Do we support 32-bit PHP anywhere? (Nearly certainly no — but confirm before excluding v1.x.)
  5. What is the latency budget for the specific operations we'd move to sodium, and will they run in the request path or on a queue?
  6. Which concrete use case justifies adoption at all? If we cannot name one, this should be classified as transitive-only and simply tracked.

Integration Approach

Stack fit

  • PHP 8.1+/Laravel 10/11: ext-sodium is a core extension, so a healthy deployment already has the native implementation. The polyfill degrades to a near no-op shim. This is the correct and preferred posture: the package provides compatibility headroom; the extension provides the performance.
  • Where we do write new crypto code, put it behind an application-owned boundary — e.g. App\Contracts\CryptoSigner / App\Support\SodiumGateway — rather than calling sodium_* or ParagonIE_Sodium_Compat::* inline in controllers or models. This makes the polyfill an implementation detail we can later remove.
  • Do not route this into Laravel's Crypt facade or Hash facade. Keep it as a separate, explicitly-named service for signing and sealed-box operations.

Migration path

  1. Inventory — composer why paragonie/sodium_compat and composer show to establish whether it's already present transitively and at what version. Confirm with composer.lock and an SBOM pass.
  2. Environment truth — add a CI and deploy-time assertion that extension_loaded('sodium') is true. This is the cheapest, highest-value control in the whole plan.
  3. Decide posture — either (a) hard-require the extension (add "ext-sodium": "*" to composer.json and pin base images / php.ini accordingly), letting sodium_compat remain a transitive-only compatibility artifact, or (b) accept the polyfill path for specific low-frequency, non-request-path jobs, gated by a runtime check.
  4. Wrap and canary — introduce the gateway class, migrate any existing ad-hoc crypto calls behind it, and ship behind a feature flag to one low-risk path before broad use.
  5. Decide on removal — if every environment has the extension and no dependency requires the polyfill's function-definition behavior, plan to drop it or leave it pinned and monitored rather than actively using it.

Compatibility

  • Prefer v2.x on PHP 8.1+ (smaller, faster, no 32-bit baggage) provided no dependency constrains < 2. If a transitive package caps at v1, stay on a pinned v1.x release rather than fighting resolution — v1.x is the actively maintained branch for broad PHP support.
  • For any package we publish internally, use ">= 1"; for our application, pin a concrete version.
  • Confirm ciphertext/key-format interop: anything encrypted or signed under the polyfill must decrypt/verify under native libsodium and vice versa. Add a CI round-trip test (polyfill-generated fixture verified by the extension, and the reverse) rather than trusting the claim.
  • Retain the ISC license text; permissive, minimal legal friction, but the notice must survive bundling.
  • Avoid the legacy PECL libsodium extension path entirely — it is superseded by core ext/sodium for PHP 7.2+.

Sequencing

  • Week 1 — discovery: dependency inventory, per-environment extension audit, compliance question answered, decision record drafted.
  • Week 2 — guardrails: CI/deploy assertion on extension_loaded('sodium'), composer check-platform-reqs in the pipeline, lint rule banning $fastMult assignment, base-image pinning.
  • Week 3–4 — narrow integration: gateway interface + one concrete use case (recommend detached signatures for webhook verification — low volume, easy to reason about, clear failure semantics).
  • Later — review: revisit whether any dependency still justifies keeping the polyfill as a direct requirement; otherwise demote to transitive-only.

Operational Impact

Maintenance

  • Maintained by Paragon Initiative Enterprises, a credible specialist PHP security vendor. ISC license, active releases (latest 2026-08-18), signed release tarballs and .phar with a published GPG key — good supply-chain hygiene.
  • Two live branches (v1.x maintenance for PHP 5.2–8.0 + 32-bit; master/v2.x for PHP 8.1+) means two tracks to monitor. Pin and subscribe to security advisories; do not float the constraint in production.
  • The README explicitly offers no guarantees of free support responsiveness for third-party integration questions, and directs enterprises to paid contracts. Budget accordingly if this becomes load-bearing.

Support

  • Community support via GitHub issues; security fixes are stated to be prioritized but there is no SLA. Commercial support contracts and libsodium commercial support vendors exist as escalation paths.
  • Internally, assign a named owner for cryptographic dependency review. The failure mode here isn't the package breaking — it's nobody noticing the extension went missing.

Scaling

  • With ext-sodium loaded: negligible overhead, C-speed primitives, no scaling concern.
  • On the polyfill path: pure-PHP arithmetic is orders of magnitude slower for asymmetric operations and AEAD. On a hot request path this consumes PHP-FPM workers proportional to concurrent crypto calls and manifests as throughput collapse, not as errors. Use ParagonIE_Sodium_Compat::polyfill_is_fast() as a runtime branch and defer crypto work to queues when it returns false, exactly as the README recommends.
  • Set a policy: polyfill-path crypto is permitted only in queued jobs, CLI commands, or batch processes — never in an HTTP request handler.

Failure modes

  • Silent polyfill engagement (extension absent) → correct output, severe latency, no exception. Primary risk. Mitigate with a startup/health-check assertion and a synthetic latency probe.
  • Partial function coverage — the README's API list is broad but not literally exhaustive of every libsodium entry point; a call to an uncovered function on the polyfill path throws rather than degrades. Test the specific functions we use, not the whole surface.
  • Global static contamination — $fastMult set anywhere affects the whole worker process, including Octane's long-lived state. Treat as a security-relevant lint violation.
  • Composer resolution drift — v1/v2 split, or a dependency requiring ">= 1" silently pulling a major we didn't test against.
  • Perceived as key management — it isn't. It provides primitives, not key storage, rotation, or HSM/KMS integration. Teams that adopt it without a key-management story typically end up with keys in .env and no rotation path. Pair adoption with an explicit key-handling decision.
  • Audit gap — if a customer security questionnaire asks "is your crypto library independently audited?", the answer today is no. Pre-answer this by relying on ext-sodium (libsodium itself is audited) and treating the polyfill purely as a dev/fallback path.

Ramp-up

  • Developer ramp-up is low. The API mirrors libsodium one-to-one (sodium_ → ParagonIE_Sodium_Compat::), and the README points to the Libsodium Quick Reference and Using Libsodium in PHP Projects. A competent PHP developer is productive in roughly a day.
  • The real ramp-up cost is primitive selection and key lifecycle judgment, not the library. Budget a review gate with someone who can answer "should this be crypto_sign_detached or crypto_auth?" and "where does this key live?"
  • Run a short spike on target production hardware benchmarking our intended operations both with and without the extension before committing. That single measurement resolves most of the open risk and gives the decision record a defensible number.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk