// kit 01
PQC Toolkit
Cripto post-cuántica lista para producción. Elige stack, elige primitiva, copia el código.
$ pqc_kem.php
L3
1 <?php 2 // Requires liboqs FFI binding (see downloads/pqc-kit-php). 3 // PHP has no pure-PHP ML-KEM yet; this wraps liboqs via FFI. 4 declare(strict_types=1); 5 6 final class PqcKem 7 { 8 private \FFI $oqs; 9 10 public function __construct(string $libPath = '/usr/local/lib/liboqs.so') 11 { 12 $hdr = <<<H 13 typedef struct OQS_KEM OQS_KEM; 14 OQS_KEM* OQS_KEM_new(const char* method_name); 15 int OQS_KEM_keypair(OQS_KEM* kem, uint8_t* public_key, uint8_t* secret_key); 16 int OQS_KEM_encaps(OQS_KEM* kem, uint8_t* ciphertext, uint8_t* shared_secret, const uint8_t* public_key); 17 int OQS_KEM_decaps(OQS_KEM* kem, uint8_t* shared_secret, const uint8_t* ciphertext, const uint8_t* secret_key); 18 void OQS_KEM_free(OQS_KEM* kem); 19 H; 20 $this->oqs = \FFI::cdef($hdr, $libPath); 21 } 22 23 public function keygen(): array 24 { 25 $kem = $this->oqs->OQS_KEM_new('ML-KEM-768'); 26 $pub = \FFI::new('uint8_t[1184]'); 27 $sec = \FFI::new('uint8_t[2400]'); 28 $this->oqs->OQS_KEM_keypair($kem, $pub, $sec); 29 return ['pub' => \FFI::string($pub, 1184), 'sec' => \FFI::string($sec, 2400)]; 30 } 31 32 public function encaps(string $pub): array 33 { 34 $kem = $this->oqs->OQS_KEM_new('ML-KEM-768'); 35 $ct = \FFI::new('uint8_t[1088]'); 36 $ss = \FFI::new('uint8_t[32]'); 37 $this->oqs->OQS_KEM_encaps($kem, $ct, $ss, $pub); 38 return ['ct' => \FFI::string($ct, 1088), 'ss' => \FFI::string($ss, 32)]; 39 } 40 } 41 42 function pqc_combine(string $ss_pq, string $ss_x, string $transcript): string 43 { 44 return sodium_crypto_generichash($ss_x . $ss_pq . $transcript, '', 32); 45 }
TAMAÑO CLAVE
1184 B pub
FIRMA / CT
1088 B ct
NIVEL NIST
L3
NOTAS
PHP no tiene PQ nativo; el kit trae un binding FFI a liboqs.
- liboqs 0.10+ entrega ML-KEM con nombre viejo (Kyber) y nuevo (ML-KEM).
- FFI tiene overhead; haz pool de
OQS_KEM_newen hot paths. - Para hosting compartido sin liboqs, cae a sidecar vía socket Unix.