A minimal PHP extension wrapping liboqs KEM and signature
APIs into a namespaced API suitable for the SecuDoc stack. The runtime namespace, configure flag,
and module name are OQS (extension: oqs.so).
Note on naming: NIST standardized Kyber as ML-KEM (FIPS 203). liboqs exposes both names (
Kyber{512,768,1024}andML-KEM-{512,768,1024}) depending on build options. This extension accepts whatever your liboqs provides.
Once PHP natively supports PQC, this wrapper will likely be deprecated.
OQS\KEM exposes post-quantum key encapsulation:
OQS\KEM::algorithms(): string[]— list enabled KEM identifiers.OQS\KEM::keypair(string $algorithm): array{publicKey: string, secretKey: string}OQS\KEM::keypairDerand(string $algorithm, string $seed): array{publicKey: string, secretKey: string}— deterministic keygen from seedOQS\KEM::encapsulate(string $algorithm, string $publicKey): array{ciphertext: string, sharedSecret: string}OQS\KEM::encapsulateDerand(string $algorithm, string $publicKey, string $seed): array{ciphertext: string, sharedSecret: string}— deterministic encaps from seedOQS\KEM::decapsulate(string $algorithm, string $ciphertext, string $secretKey): string
All algorithm identifiers surfaced by liboqs are also available as class constants, e.g.
OQS\KEM::ALG_KYBER768 and/or OQS\KEM::ALG_ML_KEM_768 (depending on your liboqs build).
Binary outputs: All keys, ciphertexts, and shared secrets are raw binary strings. Base64-encode if you need printable or JSON-safe values.
Secret handling: temporary native buffers are wiped with
OQS_MEM_cleanse, but returned PHP strings remain managed by the Zend engine and are not guaranteed to be securely erased later. Treat secret keys and shared secrets as sensitive application data.
OQS\Signature wraps stateless PQ signatures:
OQS\Signature::algorithms(): string[]OQS\Signature::keypair(string $algorithm): array{publicKey: string, secretKey: string}OQS\Signature::keypairDerand(string $algorithm, string $seed): array{publicKey: string, secretKey: string}— deterministic keypair from seed (ML-DSA: 32 bytes)OQS\Signature::sign(string $algorithm, string $message, string $secretKey): stringOQS\Signature::signWithContext(string $algorithm, string $message, string $context, string $secretKey): string— context-bound signingOQS\Signature::verify(string $algorithm, string $message, string $signature, string $publicKey): boolOQS\Signature::verifyWithContext(string $algorithm, string $message, string $signature, string $context, string $publicKey): bool— context-bound verification
Signature identifiers are also class constants, e.g. OQS\Signature::ALG_DILITHIUM_3.
Global namespace constants (e.g. OQS\VERSION_TEXT) mirror liboqs build info.
<?phpuseOQS\KEM;
// Pick an algorithm supported by your liboqs build:$alg = defined('OQS\\KEM::ALG_ML_KEM_768') ? OQS\KEM::ALG_ML_KEM_768 : OQS\KEM::ALG_KYBER768;
[$pk, $sk] = KEM::keypair($alg);
[$ct, $ss1] = KEM::encapsulate($alg, $pk);
$ss2 = KEM::decapsulate($alg, $ct, $sk);
assert(hash_equals($ss1, $ss2));
// If you need text-safe values:echobase64_encode($ct), "\n", base64_encode($ss1), "\n";Before building this PHP extension, you need the liboqs C library and headers installed on your system.
You can either build it from source or install it via a package manager if available.
git clone https://github.com/open-quantum-safe/liboqs.git
cd liboqs
mkdir build &&cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DOQS_BUILD_ONLY_LIB=ON ..
make -j$(nproc)
sudo make installThis installs liboqs.so to /usr/local/lib and headers to /usr/local/include/oqs.
pkg-config --modversion liboqs
# should report 0.14.0 or newerThen proceed with the build steps below.
- PHP dev tools (
phpize,php-config, headers) liboqs0.14.0 or newer (headers underinclude/oqs, libs underlib)- A compiler toolchain (gcc/clang, make, autoconf)
Check your liboqs version:
pkg-config --modversion liboqs
# or:
grep -E 'OQS_VERSION_(TEXT|MAJOR|MINOR|PATCH)' /usr/local/include/oqs/oqsconfig.hRetrieve the pie.phar from https://github.com/php/pie and install the extension as follows:
sudo pie install secudoc/php-liboqsMake sure you have liboqs already installed.
/php/bin/phpize
./configure --with-php-config=/php/bin/php-config --with-oqs
make -j$(nproc)
sudo make install
echo"extension=oqs.so"| sudo tee /etc/php/<ver>/mods-available/oqs.ini
sudo phpenmod oqs
php -m | grep oqsIf liboqs isn’t in pkg-config, pass the prefix that contains include/oqs and lib/:
/php/php-8.5/bin/phpize
./configure --with-php-config=/php/php-8.5/bin/php-config --with-oqs=/usr/local
make -j$(nproc)&& sudo make installliboqs 0.14.0 or newer is required
Ensure pkg-config finds liboqs ≥ 0.14.0 (pkg-config --modversion liboqs) or your--with-oqsprefix points to headers withoqs/oqsconfig.hreporting ≥ 0.14.0.oqs.h not found
Your--with-oqs=/prefixmust contain/prefix/include/oqs/oqs.hand/prefix/lib/liboqs.*.Runtime loader can’t find
liboqs.so
Either install liboqs to a standard location (e.g./usr/local) or set:export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH# Linuxexport DYLD_LIBRARY_PATH=/usr/local/lib:$DYLD_LIBRARY_PATH# macOS (disable SIP for non-system paths)
Which algorithms are enabled?
print_r(OQS\KEM::algorithms()); print_r(OQS\Signature::algorithms());
- Algorithms and sizes are defined by liboqs at build time. If an identifier isn’t present in
OQS\KEM::algorithms(), your liboqs was built without it. - Thread safety: the extension itself is stateless; use a thread-safe PHP build (ZTS) if your SAPI requires it.
This extension is provided as-is without any warranty. It is intended for experimentation, prototyping, and research purposes only. Do not use this software in production environments that require certified or audited cryptographic implementations. The liboqs library itself is not a FIPS-validated module, and the PHP wrapper has not been security reviewed. Use entirely at your own risk.