paragonie/pqcrypto_compat

Pure PHP implementation of pqcrypto; uses the PHP extension if it exists

Maintainers

Package info

github.com/paragonie/pqcrypto_compat

pkg:composer/paragonie/pqcrypto_compat

Statistics

Installs: 62

Dependents: 1

Suggesters: 0

Stars: 2

Open Issues: 1

v0.1.0 2026-04-08 21:10 UTC

This package is auto-updated.

Last update: 2026-04-08 21:12:30 UTC


README

Build Status Latest Stable Version License Downloads

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.