paragonie / pqcrypto_compat
Pure PHP implementation of pqcrypto; uses the PHP extension if it exists
Requires
- php: ^8.1
- php-64bit: *
- paragonie/sodium_compat: ^2
Requires (Dev)
- c2sp/wycheproof: dev-main
- giorgiosironi/eris: ^1
- phpunit/phpunit: ^10|^11|^12|^13
- trailofbits/wycheproof: ^0|^1
Suggests
- ext-pqcrypto: Better performance, higher assurance
This package is auto-updated.
Last update: 2026-04-08 21:12:30 UTC
README
pqcrypto_compat defers to the pqcrypto extension if it's available, and provides a polyfill for environments where it is not available, ensuring the PHP ecosystem can effectively migrate to use post-quantum secure cryptographic algorithms.
Warning
This code has never been independently audited. Use at your own risk.
Installing
composer require paragonie/pqcrypto_compat
Optional, but recommended: Install the pqcrypto extension.
Usage
The recommended way to use this polyfill library is the Compat class.
X-Wing Example
X-Wing is a hybrid KEM combining X25519 and ML-KEM-768. The X25519 implementation is provided by sodium_compat.
<?php declare(strict_types=1); use ParagonIE\PQCrypto\Compat; // Key generation [$decapsKey, $encapsKey] = Compat::xwing_keygen(); // Encapsulation ['sharedKey' => $ss, 'ciphertext' => $ct] = Compat::xwing_encaps($encapsKey); // Decapsulation $sharedKey = Compat::xwing_decaps($decapsKey, $ct); var_dump(hash_equals($ss, $sharedKey)); // bool(true)
ML-KEM-768 Example
<?php declare(strict_types=1); use ParagonIE\PQCrypto\Compat; // Key generation [$decapsKey, $encapsKey] = Compat::mlkem768_keygen(); $decapsKeyBytes = $decapsKey->bytes(); $encapsKeyBytes = $encapsKey->bytes(); // Encapsulation ['sharedKey' => $ss, 'ciphertext' => $ct] = Compat::mlkem768_encaps($encapsKey); // Send $ct to recipient that possesses $decapsKey $sharedKey = Compat::mlkem768_decaps($decapsKey, $ct); var_dump(hash_equals($ss, $sharedKey)); // bool(true)
ML-KEM-1024 Example
<?php declare(strict_types=1); use ParagonIE\PQCrypto\Compat; // Key generation [$decapsKey, $encapsKey] = Compat::mlkem1024_keygen(); $decapsKeyBytes = $decapsKey->bytes(); $encapsKeyBytes = $encapsKey->bytes(); // Encapsulation ['sharedKey' => $ss, 'ciphertext' => $ct] = Compat::mlkem1024_encaps($encapsKey); // Send $ct to recipient that possesses $decapsKey $sharedKey = Compat::mlkem768_decaps($decapsKey, $ct); var_dump(hash_equals($ss, $sharedKey)); // bool(true)
ML-DSA-44 Example
<?php declare(strict_types=1); use ParagonIE\PQCrypto\Compat; // Key generation ['signingKey' => $sk, 'verificationKey' => $vk] = Compat::mldsa44_keygen(); // Signing $message = 'message'; $signature = Compat::mldsa44_sign($sk, $message); $valid = Compat::mldsa44_verify($vk, $signature, $message); var_dump($valid); // bool(true)
ML-DSA-65 Example
<?php declare(strict_types=1); use ParagonIE\PQCrypto\Compat; // Key generation ['signingKey' => $sk, 'verificationKey' => $vk] = Compat::mldsa65_keygen(); // Signing $message = 'message'; $signature = Compat::mldsa65_sign($sk, $message); $valid = Compat::mldsa65_verify($vk, $signature, $message); var_dump($valid); // bool(true)
ML-DSA-87 Example
<?php declare(strict_types=1); use ParagonIE\PQCrypto\Compat; // Key generation ['signingKey' => $sk, 'verificationKey' => $vk] = Compat::mldsa87_keygen(); // Signing $message = 'message'; $signature = Compat::mldsa87_sign($sk, $message); $valid = Compat::mldsa87_verify($vk, $signature, $message); var_dump($valid); // bool(true)
Other Algorithms
We also include ML-KEM-512 for completeness, but do not recommend its usage.