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
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:
```bash
@ -147,6 +151,18 @@ php-config --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
Choose a working directory:
@ -238,13 +254,13 @@ sudo install -m 0755 \
"$(php-config --extension-dir)/skein.so"
```
Find the PHP configuration files:
Find the PHP configuration directories:
```bash
php --ini
```
Add these lines to the appropriate `php.ini` or extension configuration file:
Create one dedicated extension configuration file containing:
```ini
extension=skein.so
@ -253,7 +269,9 @@ extension=oqsphp.so
CLI PHP, Apache, and PHP-FPM can use different configuration directories. The
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
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
raw-message marker. `php-contractless-rpc` applies that format automatically,
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"
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
git clone --depth 1 https://github.com/open-quantum-safe/liboqs.git \
"$third_party/liboqs"
@ -40,6 +59,7 @@ fi
(
cd "$third_party/php-skein"
phpize --clean >/dev/null 2>&1 || true
phpize
./configure
make
@ -51,7 +71,6 @@ Native extensions built:
$third_party/liboqs-php/build/oqsphp.so
$third_party/php-skein/modules/skein.so
Add both absolute paths to php.ini:
extension=$third_party/liboqs-php/build/oqsphp.so
extension=$third_party/php-skein/modules/skein.so
Do not add these paths directly to php.ini.
Run sudo ./install-linux.sh to install and enable both modules.
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"
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
echo "The modules have not been built. Run ./build-linux.sh first." >&2
exit 1
fi
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"
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
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."

View File

@ -3,17 +3,28 @@
declare(strict_types=1);
$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");
$publicKey = file_get_contents("$fixtures/public-key.bin");
$privateKey = file_get_contents("$fixtures/private-key.bin");
$rustSignature = file_get_contents("$fixtures/rust-signature.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')) {
throw new RuntimeException('The Contractless PHP crypto modules are not loaded.');
}