Saltar al contenido principal
it/blog/kyber/el-saber-y-el-hacer/

Il sapere e il fare — La distanza del segreto — VI

Di Xscriptor — Óscar Preciado6 min di lettura
FilosofiaTecnologiaCrittografiaSaggiocrittografiapost-quantisticaKyberimplementazioneDartxkyber_cryptoepistemologiaAristoteleXscriptorÓscar Preciado
Il sapere e il fare — La distanza del segreto — VI

Conoscere non è fare. Fare non è assicurare.



Aristotele distinse tre forme di conoscenza. L'episteme è il sapere teorico — conoscere che qualcosa è vero —. La techne è il sapere produttivo — conoscere come fare qualcosa —. La phronesis è il sapere pratico — conoscere cosa fare in una situazione concreta —.

La crittografia le richiede tutte e tre. E la distanza tra di esse è lo spazio dove si verificano la maggior parte delle vulnerabilità.

Episteme: il paper

Kyber è un risultato dell'episteme. Il paper di Bos et al. (2018) descrive uno schema di incapsulamento di chiavi basato su Module-LWE, con dimostrazioni di sicurezza, parametri giustificati, analisi degli attacchi conosciuti. È conoscenza teorica nella sua forma più raffinata: definisce, dimostra, conclude.

Leggere il paper e comprenderlo produce la sensazione di aver catturato qualcosa di importante. La struttura è elegante: la matrice A è generata da un seed pubblico, il segreto s è campionato con distribuzione binomiale centrata, il ciphertext è compresso a 3 bit per coefficiente, il FO transform garantisce IND-CCA2. Ogni cosa incastra.

Ma l'episteme ha un limite: il paper dimostra che se i componenti vengono eseguiti correttamente, allora lo schema è sicuro. La proposizione condizionale è vera. Ma il mondo reale non valuta condizionali; esegue codice.

Episteme (il paper):  Se (NTT corretta ∧ tempo costante ∧ FO corretto)
                      allora lo schema è IND-CCA2 sicuro.

Techne (il codice):   NTT corretta? OK   Tempo costante? ?   FO corretto? OK
                      La variabile che non appare nella premessa
                      è quella che determina la sicurezza reale.

Techne: l'implementazione

Durante la mia fase di apprendimento ho implementato Kyber in Dart/Flutter — xkyber_crypto — seguendo FIPS 203 alla lettera. La techne di tradurre il paper in codice ha le sue esigenze: scegliere rappresentazioni dei dati, gestire la memoria, implementare SHAKE128 da zero, organizzare la moltiplicazione di polinomi nel dominio NTT.

Ogni decisione d'implementazione rivela qualcosa che il paper non dice:

Il paper scrive: "Sample s ← β_η^k"

L'implementazione scrive:

void cbd(Poly r, Uint8List buf) {
  for (int i = 0; i < KYBER_N ~/ 8; i++) {
    int t = buf[2 * i] | (buf[2 * i + 1] << 8);
    for (int j = 0; j < 8; j++) {
      int aj = (t >> j) & 1;
      int bj = (t >> (j + 8)) & 1;
      r.coeffs[8 * i + j] = aj - bj;
    }
  }
}

Il paper non specifica l'ordine dei bit. Non dice se il ciclo debba essere parallelizzabile. Non menziona che ogni accesso a r.coeffs[...] in Dart esegue un bounds check che la VM non può elidere, e che ogni bounds check è un'opportunità per far variare il tempo.

L'implementazione era funzionalmente corretta. Tutti i vettori di test passavano. Ma la techne ha rivelato qualcosa che l'episteme non poteva: il linguaggio conta. Dart non è stato progettato per crittografia ad alta sicurezza. Non c'è garanzia che la VM compili un ciclo senza ramificazioni dipendenti dai dati. Non c'è modo di assicurare che la riduzione di Montgomery sia costante in tempo quando ~/ 65536 può essere compilato come divisione o come shift a seconda della fase di ottimizzazione JIT.

Il confronto dei ciphertext nel FO transform — il punto più critico — illustra l'abisso:

// È questo costante in tempo?
bool verify(Uint8List a, Uint8List b) {
  if (a.length != b.length) return false;
  int r = 0;
  for (int i = 0; i < a.length; i++) {
    r |= a[i] ^ b[i];
  }
  return r == 0;
}

In C, questa funzione viene compilata in istruzioni che un esperto può ispezionare e verificare. In Dart, il compilatore JIT può riordinare il ciclo, fondere iterazioni, applicare eliminazione di codice morto se deduce che r non viene usato, o inserire barriere di GC nelle scritture. Non esiste volatile. Non esiste __attribute__((const)). Non c'è modo di dire alla VM: "questo deve essere eseguito esattamente come scritto, senza ottimizzazioni, senza riordinamenti, senza sorprese".

La techne di implementare Kyber in Dart si è scontrata con un limite materiale: il linguaggio non fornisce gli strumenti che la crittografia esige.

Phronesis: l'archiviazione

Giunto a questo punto, la phronesis — il sapere pratico di cosa fare — impone una decisione. L'implementazione funziona. I test passano. Ma la sicurezza non si dimostra con test che passano: si dimostra con proprietà che si garantiscono.

Non c'era modo di garantire tempo costante nella Dart VM. Non c'era modo di ispezionare l'assembly generato dal compilatore AOT per verificare che i cicli rimanessero senza ramificazione. Non c'era modo di assicurarsi che il garbage collector non introducesse pause misurabili nel momento esatto del confronto del FO transform.

La decisione è stata archiviare il repository. Non per fallimento tecnico — l'implementazione era corretta — ma per onestà intellettuale:

La decisione di archiviare:

  Funziona?                    Sì. I test passano.
  È sicuro?                    Non si può dimostrare.
  Può diventare sicuro?        Non senza riscrivere in C/Rust e collegare via FFI.
  Ha valore come riferimento?  Sì, come esempio di quanto arriva
                               la techne senza l'infrastruttura adeguata.

Aristotele scrisse che la phronesis non è scienza né arte: è la capacità di deliberare bene su ciò che è buono o cattivo per l'essere umano. In crittografia, la phronesis è saper riconoscere quando un'implementazione è insicura, anche quando tutti i test dicono che è corretta.

Cosa insegna il fare

La serie "La distanza del segreto" ha esplorato cinque distanze:

  1. I: la distanza tra la congettura di LWE e la dimostrazione di sicurezza
  2. II: la distanza tra l'algoritmo e la sua implementazione costante in tempo
  3. III: la distanza tra la sicurezza computazionale e il limite fisico di Landauer
  4. IV: la distanza tra la protezione presente e la minaccia futura (harvest now)
  5. V: la distanza tra la fiducia istituzionale e la diversità matematica

VI aggiunge una distanza più fondamentale: la distanza tra sapere e fare.

Il paper di Kyber è conoscenza vera. L'implementazione in Dart è stata conoscenza produttiva. Ma la sicurezza reale — quella che resiste a un attacco reale, non a un test unitario — richiede qualcosa che nessuno dei due fornisce separatamente: la capacità di riconoscere che un sistema può essere funzionalmente corretto e crittograficamente insicuro allo stesso tempo.

Questo non si impara nel paper. Si impara implementando, fallendo, archiviando.


Con "Il sapere e il fare" si chiude il ciclo de "La distanza del segreto". L'esplorazione è iniziata chiedendo quando possiamo dire che qualcosa è sicuro. La risposta, dopo sei saggi, è: mai del tutto. Ma possiamo avvicinarci — combinando la teoria che dimostra, la pratica che costruisce e la saggezza che riconosce i limiti di entrambe.


Riferimenti incrociati con la ricerca: