fixed installers, readme and tests

This commit is contained in:
viraladmin 2026-07-25 13:53:41 -06:00
parent f4d4423a4a
commit de187b7f8f
4 changed files with 98 additions and 14 deletions

View File

@ -57,6 +57,10 @@ The installer copies both modules into the active PHP extension directory,
creates `contractless-crypto.ini`, enables it through `phpenmod`, and verifies creates `contractless-crypto.ini`, enables it through `phpenmod`, and verifies
that PHP can see both modules. that PHP can see both modules.
Do not add either module directly to `php.ini`. The installer manages both
module declarations through `contractless-crypto.ini`. Loading them through
both locations causes duplicate-module warnings.
Confirm the installation manually: Confirm the installation manually:
```bash ```bash
@ -147,6 +151,18 @@ php-config --version
swig -version swig -version
``` ```
Confirm that the runtime and development tools use the same PHP module API:
```bash
php -i | grep '^PHP API'
php-config --phpapi
phpize --version
```
The API numbers reported by all three commands must match. A module compiled
with PHP 8.4 development tools cannot be loaded by PHP 8.3, and the reverse is
also true. `build-linux.sh` stops with an error when it detects this mismatch.
### Build liboqs ### Build liboqs
Choose a working directory: Choose a working directory:
@ -238,13 +254,13 @@ sudo install -m 0755 \
"$(php-config --extension-dir)/skein.so" "$(php-config --extension-dir)/skein.so"
``` ```
Find the PHP configuration files: Find the PHP configuration directories:
```bash ```bash
php --ini php --ini
``` ```
Add these lines to the appropriate `php.ini` or extension configuration file: Create one dedicated extension configuration file containing:
```ini ```ini
extension=skein.so extension=skein.so
@ -253,7 +269,9 @@ extension=oqsphp.so
CLI PHP, Apache, and PHP-FPM can use different configuration directories. The CLI PHP, Apache, and PHP-FPM can use different configuration directories. The
modules must be enabled for every PHP runtime that uses modules must be enabled for every PHP runtime that uses
`php-contractless-rpc`. `php-contractless-rpc`. Enable or link this dedicated file in each required
runtime configuration directory. Do not also add these declarations directly
to `php.ini`.
Restart Apache or PHP-FPM after changing its configuration. Service names vary Restart Apache or PHP-FPM after changing its configuration. Service names vary
by distribution and installed PHP version. by distribution and installed PHP version.
@ -293,4 +311,3 @@ $digest = skein_hash($data, 256);
Direct Contractless Falcon handling requires the public-key SHAKE256 prefix and Direct Contractless Falcon handling requires the public-key SHAKE256 prefix and
raw-message marker. `php-contractless-rpc` applies that format automatically, raw-message marker. `php-contractless-rpc` applies that format automatically,
so application developers should use its `NativeCrypto` class. so application developers should use its `NativeCrypto` class.

View File

@ -6,6 +6,25 @@ root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
third_party="$root/native/third-party" third_party="$root/native/third-party"
mkdir -p "$third_party" mkdir -p "$third_party"
runtime_api="$(php -i | sed -n 's/^PHP API => //p' | head -n 1)"
config_api="$(php-config --phpapi)"
phpize_api="$(phpize --version | sed -n 's/^PHP Api Version:[[:space:]]*//p' | head -n 1)"
if [[ -z "$runtime_api" || -z "$config_api" || -z "$phpize_api" \
|| "$runtime_api" != "$config_api" || "$runtime_api" != "$phpize_api" ]]; then
cat >&2 <<EOF
PHP build tools do not match the active PHP runtime.
php API: ${runtime_api:-unknown}
php-config API: ${config_api:-unknown}
phpize API: ${phpize_api:-unknown}
Install the development package matching the active PHP version and select its
phpize and php-config commands before building.
EOF
exit 1
fi
if [[ ! -d "$third_party/liboqs/.git" ]]; then if [[ ! -d "$third_party/liboqs/.git" ]]; then
git clone --depth 1 https://github.com/open-quantum-safe/liboqs.git \ git clone --depth 1 https://github.com/open-quantum-safe/liboqs.git \
"$third_party/liboqs" "$third_party/liboqs"
@ -40,6 +59,7 @@ fi
( (
cd "$third_party/php-skein" cd "$third_party/php-skein"
phpize --clean >/dev/null 2>&1 || true
phpize phpize
./configure ./configure
make make
@ -51,7 +71,6 @@ Native extensions built:
$third_party/liboqs-php/build/oqsphp.so $third_party/liboqs-php/build/oqsphp.so
$third_party/php-skein/modules/skein.so $third_party/php-skein/modules/skein.so
Add both absolute paths to php.ini: Do not add these paths directly to php.ini.
extension=$third_party/liboqs-php/build/oqsphp.so Run sudo ./install-linux.sh to install and enable both modules.
extension=$third_party/php-skein/modules/skein.so
EOF EOF

View File

@ -6,13 +6,22 @@ root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
oqs_module="$root/native/third-party/liboqs-php/build/oqsphp.so" oqs_module="$root/native/third-party/liboqs-php/build/oqsphp.so"
skein_module="$root/native/third-party/php-skein/modules/skein.so" skein_module="$root/native/third-party/php-skein/modules/skein.so"
runtime_api="$(php -i | sed -n 's/^PHP API => //p' | head -n 1)"
config_api="$(php-config --phpapi)"
if [[ -z "$runtime_api" || "$runtime_api" != "$config_api" ]]; then
echo "Active PHP and php-config use different module APIs." >&2
echo "php API: ${runtime_api:-unknown}" >&2
echo "php-config API: ${config_api:-unknown}" >&2
exit 1
fi
if [[ ! -f "$oqs_module" || ! -f "$skein_module" ]]; then if [[ ! -f "$oqs_module" || ! -f "$skein_module" ]]; then
echo "The modules have not been built. Run ./build-linux.sh first." >&2 echo "The modules have not been built. Run ./build-linux.sh first." >&2
exit 1 exit 1
fi fi
extension_dir="$(php-config --extension-dir)" extension_dir="$(php-config --extension-dir)"
php_version="$(php -r 'echo PHP_MAJOR_VERSION . \".\" . PHP_MINOR_VERSION;')" php_version="$(php -r 'echo PHP_MAJOR_VERSION, ".", PHP_MINOR_VERSION;')"
ini_dir="/etc/php/$php_version/mods-available" ini_dir="/etc/php/$php_version/mods-available"
install -m 0755 "$oqs_module" "$extension_dir/oqsphp.so" install -m 0755 "$oqs_module" "$extension_dir/oqsphp.so"
@ -25,5 +34,33 @@ if command -v phpenmod >/dev/null 2>&1; then
phpenmod contractless-crypto phpenmod contractless-crypto
fi fi
php -m | grep -E '^(skein|oqsphp)$' module_output="$(php -m 2>&1)"
if grep -q 'already loaded' <<<"$module_output"; then
cat >&2 <<EOF
The modules were installed, but PHP is loading them more than once.
Do not add oqsphp.so or skein.so directly to php.ini. Keep only the managed
contractless-crypto.ini configuration enabled by this installer.
Find duplicate declarations with:
grep -RniE 'extension[[:space:]]*=.*(skein|oqsphp)' /etc/php
EOF
exit 1
fi
if ! grep -qx 'skein' <<<"$module_output" || ! grep -qx 'oqsphp' <<<"$module_output"; then
echo "PHP could not load both Contractless crypto modules." >&2
exit 1
fi
php -r '
if (!function_exists("skein_hash")
|| !function_exists("contractless_shake256")
|| !class_exists("OQS_SIGNATURE")
) {
fwrite(STDERR, "Required Contractless crypto functions are unavailable.\n");
exit(1);
}
'
echo "Contractless PHP crypto modules installed and enabled for PHP $php_version." echo "Contractless PHP crypto modules installed and enabled for PHP $php_version."

View File

@ -3,17 +3,28 @@
declare(strict_types=1); declare(strict_types=1);
$fixtures = dirname(__DIR__) . '/interop/fixtures'; $fixtures = dirname(__DIR__) . '/interop/fixtures';
$fixtureFiles = [
'message.bin',
'public-key.bin',
'private-key.bin',
'rust-signature.bin',
'rust-skein256.bin',
];
foreach ($fixtureFiles as $fixtureFile) {
if (!is_file("$fixtures/$fixtureFile")) {
throw new RuntimeException(
'Interop fixtures are missing. Run cargo run --release inside interop first.',
);
}
}
$message = file_get_contents("$fixtures/message.bin"); $message = file_get_contents("$fixtures/message.bin");
$publicKey = file_get_contents("$fixtures/public-key.bin"); $publicKey = file_get_contents("$fixtures/public-key.bin");
$privateKey = file_get_contents("$fixtures/private-key.bin"); $privateKey = file_get_contents("$fixtures/private-key.bin");
$rustSignature = file_get_contents("$fixtures/rust-signature.bin"); $rustSignature = file_get_contents("$fixtures/rust-signature.bin");
$rustSkein = file_get_contents("$fixtures/rust-skein256.bin"); $rustSkein = file_get_contents("$fixtures/rust-skein256.bin");
if (in_array(false, [$message, $publicKey, $privateKey, $rustSignature, $rustSkein], true)) {
throw new RuntimeException(
'Interop fixtures are missing. Run cargo run --release inside interop first.',
);
}
if (!function_exists('skein_hash') || !function_exists('contractless_shake256')) { if (!function_exists('skein_hash') || !function_exists('contractless_shake256')) {
throw new RuntimeException('The Contractless PHP crypto modules are not loaded.'); throw new RuntimeException('The Contractless PHP crypto modules are not loaded.');
} }