CluPilotCloud/app/Services/Wireguard/Keypair.php

38 lines
1.2 KiB
PHP

<?php
namespace App\Services\Wireguard;
/**
* A WireGuard keypair. Generated in PHP via libsodium rather than by shelling
* out to `wg genkey`: the console runs in the web container, which has no
* wg0 interface, and this keeps key generation testable.
*
* WireGuard keys are Curve25519. The private key is 32 random bytes with the
* standard clamping applied; the public key is its scalar multiplication with
* the curve base point — exactly what `wg pubkey` computes.
*/
final readonly class Keypair
{
public function __construct(public string $privateKey, public string $publicKey) {}
public static function generate(): self
{
$bytes = random_bytes(32);
$bytes[0] = chr(ord($bytes[0]) & 248);
$bytes[31] = chr((ord($bytes[31]) & 127) | 64);
return new self(
privateKey: base64_encode($bytes),
publicKey: base64_encode(sodium_crypto_scalarmult_base($bytes)),
);
}
/** A base64-encoded 32-byte key, the only shape WireGuard accepts. */
public static function isValidKey(string $key): bool
{
$raw = base64_decode($key, true);
return $raw !== false && strlen($raw) === 32 && base64_encode($raw) === $key;
}
}