...

Enigma e la “bomba” di Turing Una storia contemporanea di

by user

on
Category: Documents
24

views

Report

Comments

Transcript

Enigma e la “bomba” di Turing Una storia contemporanea di
Enigma e la “bomba” di Turing
Una storia contemporanea di crittografia
e crittoanalisi
Francesco Burato
1
2
Indice
1
2
3
3.1
3.2
4
4.1
4.2
4.3
5
5.1
5.2
Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Enigma: la prima macchina per cifrare elettromeccanica. . . . . .
Enigma: versione informatica della macchina. . . . . . . . . . . .
Scelte strategiche di realizzazione. . . . . . . . . . . . . . . . . .
Specifiche di oggetti e metodi . . . . . . . . . . . . . . . . . . . .
3.2.1 Interfaccia Rotore . . . . . . . . . . . . . . . . . . . . . .
3.2.2 Classe Scambiatore . . . . . . . . . . . . . . . . . . . . . .
3.2.3 Classe Riflessore . . . . . . . . . . . . . . . . . . . . . . .
3.2.4 Classe ClickEvent ed interfaccia ClickListener. . . . . . .
3.2.5 Classe PannelloPrese . . . . . . . . . . . . . . . . . . . . .
3.2.6 Classe Enigma . . . . . . . . . . . . . . . . . . . . . . . .
3.2.7 Classe EnigmaSimulator . . . . . . . . . . . . . . . . . . .
La “Bomba” di Turing . . . . . . . . . . . . . . . . . . . . . . . .
Sinossi del primo tentativo di crittoanalisi: la “bomba” di Rejewski
Bletchley park . . . . . . . . . . . . . . . . . . . . . . . . . . . .
La “bomba” di Turing . . . . . . . . . . . . . . . . . . . . . . . .
La “Bomba” di Turing: versione Informatica . . . . . . . . . . . .
Considerazioni sulla simulazione . . . . . . . . . . . . . . . . . .
Specifiche di oggetti e metodi . . . . . . . . . . . . . . . . . . . .
5.2.1 Classe EnigmaForAnalysis . . . . . . . . . . . . . . . . . .
5.2.2 Classe BadCribException . . . . . . . . . . . . . . . . . .
5.2.3 Classe CribNode . . . . . . . . . . . . . . . . . . . . . . .
5.2.4 Classe CribNodeList . . . . . . . . . . . . . . . . . . . . .
5.2.5 Classe CribTree . . . . . . . . . . . . . . . . . . . . . . . .
5.2.6 Classe Bomb . . . . . . . . . . . . . . . . . . . . . . . . .
5.2.7 Classe BombRunner . . . . . . . . . . . . . . . . . . . . .
5.2.8 Classe AlanTuringBombs . . . . . . . . . . . . . . . . . .
5.2.9 Classe AlanTuringBombSimulator . . . . . . . . . . . . .
3
3
11
11
12
12
12
14
14
15
16
17
19
19
21
22
28
28
29
29
30
30
31
31
32
33
33
34
1 Introduzione
1
3
Introduzione
Per migliaia di anni, re, regine e generali hanno avuto bisogno di comunicazioni
efficienti per governare i loro paesi e comandare i loro eserciti. Nel contempo,
essi compresero quali conseguenze avrebbe avuto la caduta dei loro messaggi in
mani ostili: informazioni preziose sarebbero state a disposizione delle nazioni
rivali e degli eserciti nemici. Fu il pericolo dell’intercettazione da parte degli
avversari a promuovere lo sviluppo di codici e cifre, tecniche di alterazione del
messaggio destinate a renderlo comprensibile solo alle persone autorizzate.
Il bisogno di segretezza ha indotto le nazioni a creare segreterie alle cifre e
dipartimenti di crittografia. È stato loro compito garantire la sicurezza delle
comunicazioni, escogitando e impiegando i migliori sistemi di scrittura segreta.
Nello stesso tempo, i decrittatori, o crittoanalisti, hanno tentato di far breccia
in quei sistemi e carpire i dati che custodivano. Crittografi e decrittatori sono
cercatori di significati, alchimisti votati alla trasmutazione di astruse serie di
segni in parole dotate di senso. La storia dei codici è la storia dell’antica,
secolare battaglia tra inventori e solutori di scritture segrete; una corsa agli
armamenti intellettuale il cui impatto sulle vicende umane e sulla tecnologia è
stato profondo.
La lunga battaglia tra inventori e solutori di codici ha prodotto importanti progressi scientifici. Gl’inventori hanno creato codici sempre più resistenti
mentre i solutori, per farvi breccia, hanno escogitato metodi sempre più sofisticati. Nello sforzo di tutelare e, rispettivamente, violare la segretezza, gli opposti
schieramenti hanno attinto a un’ampia gamma di scienze e specializzazioni, dalla
matematica alla linguistica, dalla teoria dell’informazione alla fisica quantistica.
A loro volta, inventori e solutori di codici hanno arricchito queste discipline, e
il loro lavoro ha accelerato il progresso tecnologico, come è dimostrato nel caso
dei calcolatori.
Sebbene la storia sia ricca di circostanze in cui la decifrazione di un messaggio (o la resistenza del codice usato per cifrarlo) ha deciso l’esito di una battaglia
o il destino di una testa coronata, l’esempio lampante di come la crittografia e la
crittoanalisi abbiano determinato le sorti dell’umanità intera si ha nel XX secolo
con le vicende legate alla macchina Enigma, la famigerata cifratrice meccanica
in dotazione all’esercito tedesco durante la Seconda Guerra Mondiale. La violazione dei codici prodotti da Enigma è stato un passo fondamentale affinché la
guerra terminasse con la vittoria degli Alleati in quanto l’intelligence prodotta
dai crittoanalisti inglesi ha determinato le sorti di battaglie fondamentalti come
quella dell’Atlantico.
2
Enigma: la prima macchina per cifrare elettromeccanica.
Nel 1918 l’inventore tedesco Arthur Scherbius e il fidato amico Richard Ritter fondarono la Scherbius & Ritter, una società innovativa che non disdegnava di occuparsi dei prodotti più diversi, dalle turbine ai guanciali riscaldati.
Scherbius si era riservato la ricerca e lo sviluppo, ed era sempre a caccia di
nuove opportunità. Uno dei suoi progetti era rivoluzionare l’antiquato modus
operandi della crittografia mandando in pensione carta e penna, e sostituendole con quanto di meglio la tecnica del ventesimo secolo avesse da offrire.
2 Enigma: la prima macchina per cifrare elettromeccanica.
4
Avendo studiato ingegneria elettrica
ad Hannover e Monaco, egli mise appunto un dispositivo crittografico che
in sostanza era una versione elettromeccanica del disco cifrante di Leon
Battista Alberti, famoso per essre stato la prima macchina per cifrare mai
realizzata. La sua invenzione, che fu
chiamata Enigma, sarebbe passata alla storia come uno fra i più temibili
sistemi crittografici mai realizzati.
La macchina di Scherbius consisteva di diversi ingegnosi elementi da
lui combinati in un potente e sofisticato dispositivo per la produzione di
scritture segrete. Tuttavia, se smontiamo concettualmente la macchina e
la ricostruiamo un elemento per volta,
i principi del suo funzionamento ap- Fig. 1: Esempio di disco cifrante di Leon
pariranno evidenti. La versione base
Battista Alberti
del congegno di Scherbius consisteva
in tre componenti collegati da fili elettrici: una tastiera per immettere le lettere
del testo chiaro; un’unità scambiatrice che cifra la lettera trasformandola nel
corrispondente elelmento del crittogramma; e un visore con varie lampadine,
che accendendosi indicano la lettera da inserire nel crittogramma. In figura 2
è riportato uno schema semplificato del congegno, basato per semplicità su un
alfabeto di sole sei lettere. Per generare il crittogramma, l’operatore preme il
tasto corrispondente alla lettera da crittare; l’impulso elettrico raggiunge l’unità scambiatrice, e dopo esser stato elaborato va ad illuminare il visore in modo
corrispondente alla lettera crittata.
Fig. 2: Versione semplificata della macchina Enigma con un alfabeto cifrate di
sei lettere. L’elemento più importante di enigma è lo scambiatore. Digitando b sulla sinistra, la corrente entra nello scambiatore, segure il
percorso dei fili elettrici ed emerge in modo da illuminare la lettera A.
In breve, b è crittata come A. La tabella a destra riassume il modo in
ciascuna lettera è cifrata.
Lo scambiatore, uno spesso disco di gomma attraversato da una complessa
rete di fili, è la parte più importante della macchina. I fili elettrici provenienti
dalla tastiera entrano nello scambiatore in sei punti, seguono un percorso carat-
2 Enigma: la prima macchina per cifrare elettromeccanica.
5
terizzato da vari gomiti, e infine emergono dalla parte opposta in altri sei punti.
I circuiti interni dello scambiatore determinano il modo in cui un elemento del
testo chiaro è crittato. Con lo schema di base indicato in figura 2 nella tabella
di conversione è possibile realizzare in sostanza una semplice cifratura per sostituzione monoalfabetica ovvero una cifratura in cui ciascuna lettera è sostituita
con un’altra.
Il passo successivo dell’idea di Scherbius consiste nel far ruotare automaticamente il disco scambiatore di un sesto di giro (o di un ventiseiesimo di giro
nel caso di un alfabeto completo di 26 lettere) dopo la cifratura di ogni lettera.
In figura 3 è riportato un esempio di come lo scambiatore di figura 2, girato di
un sesto di giro ad ogni uso dello scambiatore, produca testi cifrati diversi.
Fig. 3: Ogni volta che una lettera è digitata tramite la tastiera e crittata, lo
scambiatore ruota di un posto. In (a) lo scambiatore critta b come A,
ma in (b) il nuovo orientamento fa si che b sia crittata come C. In (c),
essendo ruotato di un altro posto, lo scambiatore cifra b come E. Dopo
la sostituzione di altre 4 lettere, e dopo aver ruotato di altri 4 posti, lo
scambiatore riprende la configurazione iniziale.
Lo scambiatore rotante è la caratteristica più importante del progetto di
Scherbius. Tuttavia, così com’è il congegno ha un punto debole evidente: dopo
sei pressioni consecutive di qualunque tasto, il disco torna alla posizione iniziale,
e se si continuasse a premere lo stesso tasto, lo schema di cifratura si ripeterebbe
tale e quale. In generale, i crittografi temono ogni forma di ripetizione, perché
ripetizione significa regolarità e struttura del crittogramma, sinonimo di cifra-
2 Enigma: la prima macchina per cifrare elettromeccanica.
6
tura debole. Il problema può essere corretto in misura notevole introducendo
un nuovo scambiatore.
Nella figura 4(a) il primo disco è sul punto di far avanzare il secondo. Dopo
aver battuto sulla tastiera e crittato una lettera, passiamo alla figura 4(b), in
cui il primo disco è avanzato di un posto e il secondo, spinto dal precedente, è
anch’esso avanzato di un posto. Battuta e crittata un’altra lettera, passiamo alla
figura 4(c) in cui di nuovo il primo disco è avanzato di un posto; questa volta però
il secondo è rimasto fermo; tornerà ad avanzare quando il primo avrà completato
un giro, dopo aver crittato quindi altre 5 lettere. Risulta quindi evidente che
il meccanismo illustrato è lo stesso che viene attuato nei contachilometri: con
il passaggio del disco delle unità dalla cifra 9 alla cifra 0 il disco delle decine
avanza di un posto, e lo stesso avviene anche per tutti gli altri dischi.
L’aggiunta del secondo scambiatore comporta il vantaggio che lo schema di
cifratura non si ripete finchè il secondo scambiatore non è tornato al punto
di partenza, il che richiede sei giri completi del primo scambiatore ovvero la
cifratura di 6x6 lettere. In altre parole, due dischi con sei posizioni ciascuno
equivalgono ad una sostituzione monoalfabetica del tipo descritto in precedenza
che prevede l’uso di 36 diversi alfabeti cifranti detta, per questo motivo, cifratura
polialfabetica, dello stesso tipo di quella che veniva realizzata con il disco di
Alberti. Se invece del nostro alfabeto semplificato fosse adoperato un alfabeto
completo di 26 lettere, l’unità cifratrice commuterebbe in tutto 26x26, cioè 676,
alfabeti cifranti.
A questo punto dovrebbe essere chiaro che combinando i dischi scambiatori, detti anche rotori, è possibile costruire una macchina per cifrare molto
sofisticata, capace di utilizzare un enorme numero di alfabeti cifranti passando
continuamente da uno ad un altro di essi. L’operatore batte una lettera particolare e, in conformità con l’assetto dei rotori, la lettera è crittata in base a una
delle centinaia di alfabeti cifranti disponibili. Subito dopo l’assetto dei rotori
cambia, cosicché la lettera successiva sarà crittata in base ad un altro alfabeto cifrante. Oltretutto, ogni passo è eseguito con estrema precisione e rapidità,
grazie ai moviementi automatici dei rotori e alla velocità della corrente elettrica.
Prima di esporre nei particolari in che modo Scherbius pensava che la sua
macchina sarebbe stata usata, ci sono altri due elementi molto importanti riprodotti in figura 5. Innanzittutto, per una sicurezza ancora maggiore, il modello
di base della sua macchina impiegava un terzo rotore. Poiché Enigma utilizzava
alfabeti completi di 26 caratteri, essa disponeva di 26x26x26 = 17.576 procedure
di sostituzione diverse. Inoltre, l’inventore aggiunse un riflessore. Il riflessore era
simile allo scambiatore, consistendo in un disco di gomma con circuiti interni,
ma era diverso sia perché non ruotava, sia perché i fili che entravano da un lato
uscivano dallo stesso lato. Col riflessore installato, quando l’operatore digitava
una lettera il segnale elettrico attraversava i tre scambiatori, raggiungeva il riflessore ed era rimandato indietro. Perciò passava di nuovo dagli scambiatori,
ma lungo un percorso differente. Per esempio, in base all’assetto mostrato in
figura 5 la pressione del tasto b avrebbe inviato un impulso elettrico attraverso i
rotori fino al riflessore. Da qui, l’impulso sarebbe tornato indietro lungo i collegamenti e avrebbe raggiunto la lettera D. Naturalmente il segnale non sarebbe
emerso dalla tastiera, come potrebbe sembrare dalla figura 5, ma avrebbe raggiunto le lampadine del visore. A prima vista il riflessore sembra un’aggiunta
inutile poiché, essendo statico, non fa aumentare il numero di alfabeti cifranti.
2 Enigma: la prima macchina per cifrare elettromeccanica.
7
Fig. 4: Aggiungendo un altro scambiatore, lo schema di cifratura non si ripete
prima che siano sostituite 36 lettere; allora, e solo allora, entrambi gli
scambiatori saranno tornati alla posizione iniziale. Per semplificare la
figura, gli scambiatori sono rappresentati in forma bidimensionale; invece
di ruotare di un posto i collegamenti si spostano verso il basso di un posto.
Quando il filo elettrico sembra comparire in fondo allo scambiatore, lo si
potrà ritrovare subito sotto l’estremità superiore della figura. In (a), b
è crittata come D. Dopo la cifratura, il primo scambiatore ruota di un
posto, facendo ruotare di un posto anche il secondo scambiatore - ciò si
verifica una volta sola durante la rivoluzione del primo rotore. Il nuovo
assetto è mostrato in (b) dove b è crittata come F. Dopo la cifratura,
il primo scambiatore ruota di un posto, ma in questo caso il secondo
scambiatore mantiene il suo orientamento. Il nuovo assetto è mostrato
in (c), dove b è crittata come B.
2 Enigma: la prima macchina per cifrare elettromeccanica.
8
Fig. 5: Il progetto di scherbius del modello base di Enigma includeva una quarto
rotore detto riflessore, che costringeva l’impulso elettrico ad attraversare
di nuovo gli scambiatori.
Ma osservando come la macchina veniva usata per cifrare e decifrare i messaggi,
i vantaggi risultano evidenti.
Supponiamo che un operatore volesse inviare una comunicazione cifrata. Prima di cominciare egli doveva regolare gli scambiatori, in modo che assumessero
la posizione iniziale voluta. Le posizioni possibili erano, come si è spiegato,
17.576; quella prescelta determinava il modo in cui un particolare messaggio sarebbe stato crittato. La macchina Enigma era paragonabile ad un procedimento
crittografico generale, cioè ad un algoritmo crittografico. In tal caso, l’assetto
iniziale di Enigma forniva ulteriori precisazioni necessarie alla cifratura, ossia
equivaleva ad una chiave. Di solito la posizione iniziale era contenuta in un
cifrario, che elencava le chiavi da usare di giorno in giorno ed era a disposizione
di tutti gli operatori della rete. La distribuzione del cifrario richiedeva tempo
e fatica, ma dato che era necessaria solo una chiave al giorno, era sufficiente
l’invio di un cifrario contenente 28 chiavi ogni 4 settimane. Una volta regolati i
rotori come richiesto dal cifrario, l’operatore poteva iniziare la codifica del messaggio: premeva il tasto corrispondente alla prima lettera, osservava la prima
lampadina che si illuminava sullo schermo, e ne prendeva nota. Poi, dopo che il
primo rotore era automaticamente passato alla posizione successiva, l’operatore
batteva la seconda lettera in cifra e così via. Completato il crittogramma lo
progeva al marconista, che lo inviava al destinatario.
Per decifrare il crittogramma, il destinatario doveva possedere un’altra macchina Enigma, e un cifrario con l’assetto dei rotori da utilizzare giorno per giorno.
Egli regolava la macchina come spiegato dal cifrario, batteva il crittogramma
lettera dopo lettera, e annotava i caratteri del testo chiaro, indicati dall’accensione delle lampadine sul visore. In altre parole, mentre il mittenete digitava il
testo chiaro per generare il crittogramma, il destinatario digitava il crittogramma per ripristinare il testo chiaro; cifratura e decifrazione comportavano dunque
le stesse operazioni.
La comodità della decifrazione era merito del riflessore. Nella figura 5 si vede
che premendo il tasto b e seguendo il percorso della corrente elettrica, andiamo
a D. In modo analogo, premendo il tasto d e seguendo il percorso torniamo
a B. La macchina trasforma un carattere in chiaro in un carattere cifrato, e,
purché sia nel medesimo assetto, è in grado di trasformare il carattere cifrato
2 Enigma: la prima macchina per cifrare elettromeccanica.
9
nell’originario carattere chiaro.
Non si poteva certo escludere che uno o più esemplari di Enigma cadessero
in mani ostili, ma in mancanza dei dati sull’assetto iniziale sarebbe stato estremamente difficile violare i crittogrammi generati dal congegno. Senza il cifrario,
i crittoanalisti nemici avrebbero dovuto controllare ogni giorno tutte le 17.576
chiavi possibili. Se avessero posseduto uno o più esemplari di Enigma, il loro
compito sarebbe stato un po’ più facile: avrebbero dovuto selezionare una assetto, provare a decifrare un frammento di crittogramma e se il risultato fosse stato
privo di senso, passare all’assetto successivo. Ammesso di poter controllare un
assetto al minuto, e di continuare la prova di giorno e di notte senza interruzione, vagliarli tutti avrebbe richiesto due settimane. Era un discreto livello di
sciurezza, ma se il nemico avesse deciso di impiegare dozzine di persone solo a
questo scopo, si sarebbero potuti controllare tutti gli assetti in un solo giorno, e
in casi fortunati la chiave avrebbe potuto essere scoperta in qualche ora. Perciò
Scherbius decise di accrescere l’affidabilità della sua invenzione aumentando il
numero di assetti, cioè di chiavi possibili.
Naturalmente avrebbe potuto aggiungere un altro rotore, aumentando le
chiavi di 26 volte; preferì invece inserire due nuove caratteristiche. Innanzitutto,
rese i rotori removibili e sostituibili. Per esempio, il primo e il terzo rotore
potevano scambiarsi i posti. Siccome i rotori erano diversi, e diversi erano i
movimenti che compivano durante la cifratura, quet’ultima era influenzata dalla
posizione reciproca dei rotori. Dati tre elementi intercambiabili, essi possono
essere combinati in sei modi differenti; perciò questo accorgimento aumentava
il numero di chiavi di un fattore pari a 6.
La seconda caratteristica era l’inserimento di un pannello a prese multiple
tra la tastiera ed il primo rotore. Il pannello permetteva al mittente di inserire
alcuni cavi muniti di spinotti, che avevano l’effetto di scambiare due lettere
prima della loro immissione nel rotore. Per esempio un cavo poteva essere usato
per collegare le prese b e a del pannello, cosicché quando il crittografo avesse
deciso di crittare b, giunto ai rotori il segnale elettrico avrebbe seguito il percorso
proprio della a, e viceversa. L’operatore di Enigma disponeva di sei cavi, che
gli davano la possibilità di scambiare sei coppie di lettere. Le altre quattordici
lettere restavano non collegate e non scambiate. La figura 6 mostra lo schema
della macchina con il pannello a prese multiple in funzione. Poiché il diagramma
si riferisce ad un alfabeto semplificato di 6 lettere, sono state scambiate la b e
la a.
C’è un’altra caratteristica del progetto di Scherbius, il cosiddetto anello che
che ancora non è stata menzionato. Anche se l’anello ha una certa influenza sulla
cifratura, è l’aspetto meno significativo della cifratrice, e si è ritenuto di poterlo
ignorare, in questa discussione così come anche nel progetto di simulazione.
Ora che gli elementi principali del dispositivo di Scherbius sono stati descritti, è possibile calcolare il numero di chiavi che esso poteva impiegare. Tale
numero disponeva dalle caratteristiche del pannello, dei singoli rotori, e dell’unità cifratrice formata da tre rotori. La lista qui sotto elenca le variabili del
dispositivo e il numero di possibilità create da ogni variabile.
Scambiatori (detti anche rotori): ognuno dei tre dischi rotanti poteva orientarsi
in 26 modi nel piano perpendicolare al suo asse di rotazione. Di
conseguenza, erano ammesse 26 x 26 x 26 = 17.576 combinazioni di
orientamenti.
2 Enigma: la prima macchina per cifrare elettromeccanica.
10
Fig. 6: Il pannello a prese multiple era interposto tra la tastiera e gli scambiatori.
Inserendo gli appositi cavetti era possibile scambiare due lettere. Così,
in questo caso, lo scambio riguarda b e a. Durante la cifratura di b,
la corrente segue il percorso che normalmente caratterizza la cifratura
di a. Nel caso di una macchina Enigma reale, a 26 lettere, l’operatore
disponeva di almeno sei cavi e poteva scambiare almeno sei coppie di
lettere simultaneamente.
Unità-cifratrice: i tre scambiatori (1,2 e 3) potevano essere inseriti nell’unità centrale in diverse posizioni reciproche, così riassumibili: 123,
132, 213, 231 , 312, 321. Erano quindi ammesse 6 diverse posizioni
reciproche dei rotori (permutazioni).
Pannello-a-prese-multiple: i possibili abbinamenti di 12 (6 x 2) sono moltissimi,
per l’esattezza 100.391.791.500.
Il numero totale di chiavi si ottiene moltiplicando le suddette possibilità: 17.576
x 6 x 100.391.791.500 = 10.586.916.764.424.000 in lettere circa 10 milioni di
miliardi.
Una volta presi accordi sui collegamenti del pannello, sull’anello, sull’ordine
dei rotori e sul loro orientamento (cioè sui fattori che specificano la chiave),
mittente e destinatario potevano crittare e decrittare i messaggi con facilità.
D’altra parte l’intercettatore nemico, se fosse ricorso ad una strategia a prova
di errore, avrebbe dovuto controllare 10 milioni di miliardi di combinazioni dei
fattori di chiave. Un crittoanalista così rapido da controllare una combinazione al minuto, e così instancabile da lavorare giorno e notte sena interruzione,
avrebbe impiegato un tempo superiore all’età dell’universo. (In effetti, questa
valutazione eccede di ottimismo, perché nei calcoli precedenti non si è tenuto
conto dell’anello. Se lo si fosse fatto, si sarebbe constatato che le combinazioni
possibili erano molto più numerose.
L’esercito tedesco decise dunque di adottare Enigma come cifratrice ufficiale
delle proprie comunicazioni, in quanto considerato generatore di codici cifrati inviolabili. All’alba della Seconda Guerra Mondiale però decisero di incrementare ulteriormente il livello di sicurezza del dispositivo introducendo nuove
caratteristiche:
1. Il numero di rotori possibili passò da 3 a 5. Pertanto ogni operatore
Enigma aveva a disposizione 5 rotori tra i quali sceglierne 3 da dispor-
3 Enigma: versione informatica della macchina.
11
re in tutti modi possibili. Le combinazioni possibili dell’unità cifratrice
passavano dunque da 6 a 60.
2. Il numero di cavetti a disposizione dell’operatore passarono da 6 a 10
determinando la possibilità di scambiare fino a 20 lettere nel pannello
a prese multiple incrementando enormemente il numero di combinazioni
possibili.
Il numero di assetti possibili passava dunque da 10 milioni a circa 159 miliardi
di miliardi, convincendo la maggior parte dei militari al fatto che Enigma fosse
inviolabile.
3
Enigma: versione informatica della macchina.
La realizzazione di Enigma informatica ha richiesto la considerazione di tutti
gli aspetti descritti nella parte precedente. Il funzionamento di Enigma deve
ovviamente essere virtualizzato con gli strumenti messi a disposizione dai linguaggi di alto livello più diffusi, oltre che ha dover prevedere il maggior grado
di ottimizzazione possibile del codice.
3.1
Scelte strategiche di realizzazione.
Per la realizzazione del programma di simulazione si è deciso di adottare il
linguaggio ad oggetti Java Standard Edition. Le motivazioni di tale scelta sono
state molteplici:
• Il paradigma ad oggetti consente di realizzare delle strutture dati astratte
dotate di particolari funzioni, applicabili separatamente a ciascuno di essi.
Ciò ha permesso di ottenere una perfetta trasposizione dei componenti della macchina in ambiente virtuale. Sono infatti stati realizzati tanti oggetti
quanti sono i componenti analizzati nella parte precedente e pertanto:
– Scambiatore;
– Riflessore;
– Pannello a prese multiple;
– Enigma (l’oggetto che rappresenta la cifratrice nel complesso e che
istanzia ciascuno dei componenti necessari).
• Essendo il Java un linguaggio interpretato multipiattaforma si è ritenuto,
data l’attuale diffusione di OS diversi e l’evidente mancanza di un ambiente
predominante come era stato Windows in passato, che l’uso di tale linguaggio fosse la scelta ideale. Non trattandosi poi di un programma necessitante ingenti capacità di calcolo, l’interpretazione anziché la compilazione
non compromette in maniera eccessiva l’esperienza dell’utente.
• L’ambiente di lavoro integrato (IDE) utilizzato per realizzare i vari componenti del programma, ovvero NetBeans 6.5, ha consentito un efficace
organizzazione del progetto, considerate sia le peculiarità dell’editor (autocompletamento, ricerca ed organizzazione gerarchica dei file e degli oggeti creati) sia la comprensione nel pacchetto di strumenti per la creazione
di GUI orientate agli eventi.
3 Enigma: versione informatica della macchina.
3.2
Specifiche di oggetti e metodi
3.2.1
Interfaccia Rotore
12
L’interfaccia Rotore rappresenta il punto di partenza per la creazione di oggetti
capaci di eseguire la codifica secondo il modo di funzionamento di Enigma.
I due metodi pubblici previsti, ossia forwardEncoding e backwardEncoding,
dovranno essere implementati dalle sottoclassi di Rotore in maniera da consentire l’esecuzione della cifratura in avanti (ovvero dalla tastiera verso il riflessore)
ed indietro (ovvero dal riflessore verso il visore).
3.2.2
Classe Scambiatore
La classe Scabiatore implementa due interfacce: Rotore e ClickListener.
L’implementazione di Rotore consente la realizzazione della cifratura in avanti ed indietro con i metodi ereditati dall’interfaccia Rotore mentre l’implementazione di ClickListener prevede l’implementazione del metodo clickArrived ovvero
un metodo che consente la gestione di eventi di tipo ClickEvent (che verranno
descritti in seguito).
Il cuore del funzionamento dell’oggetto Scambiatore risiede nei due array di
interi previsti nel codice ovvero forwardArray e backwardArray oltre che negli
interi initialOffset e actualOffset. Il loro utilizzo è il seguente:
• forwardArray: rappresenta come una lettera viene crittata se transitante
dalla tastiera verso il riflessore. Immaginando di associare alla lettera a il
valore 0, alla b il valore 1 e via dicendo è possibile realizzare la cifratura
prelevando il valore memorizzato in forwardArray nella posizione ottenuta
applicando la conversione precedentemente descritta. L’array dovrà contenere a sua volta valori compresi tra 0 e 25 esattamente quante sono le
lettere dell’alfabeto considerato, per consentire la realizzazione di una corrispondenza biunivoca tra indice dell’array e contenuto. Se, ad esempio,
i primi elementi dell’array fossero {24, 5, 6, ...} ne conseguirebbe che la
a, applicando la conversione indicata in precedenza, sarà trasmutata nella
lettera corrispondente al numero memorizzato alla posizione 0 dell’array,
nel caso in esempio 24, e quindi nella lettera y.
• backwardArray: rappresenta come una lettera viene crittata se transitante dal riflessore verso l’array. La conversione fra numeri e lettere è la stessa
descritta in precedenza. Tuttavia l’array in esame deve essere costruito in
maniera accorta. Essendo, nella più generale delle ipotesi, forwardArray
un vettore di interi contenente valori compresi tra 0 e 25 che non seguono alcuna logica, backwardArray dovrà essere costruito nella seguente
maniera: ad ogni indice del vettore deve essere associato un numero che
rappresenta la posizione che ha l’indice considerato in forwardArray. Se,
ad esempio, un forwardArray contenesse i valori {13, 5, ..., 0, 1}, backwardArray dovrà avere in posizione 0 il numero 24 perché il numero 0
occupa, in forwardArray la posizione numero 24 e, per la stessa ragione,
dovrà avere in posizione 1 il numero 25.
• initialOffset: rappresenta la configurazione iniziale dello scambiatore considerato.
3 Enigma: versione informatica della macchina.
13
• actualOffset: rappresenta il numero di “scatti” o di cifrature eseguite dal
momento in cui l’oggetto viene istanziato.
• l: rappresenta la lista degli oggetti ascoltatori agli eventi generati dallo
scambiatore corrente.
La modalità con cui i singoli caratteri vengono cifrati e decifrati, contenuti
nei metodi pubblici ereditati forwardEncoding e backwardEncoding, sfruttano
proprio la combinazione tra la rappresentazione dati utilizzata per realizzare i
due array e gli indici specificati in precedenza. Se infatti si osserva la riga di
codice necessaria per la cifratura in avanti
r e t u r n { . . . } t h i s . forwardArray [ ( c + t h i s . i n i t i a l O f f s e t +
this . actualOffset ) % this . size ] { . . . } ;
e quella all’indietro
r e t u r n { . . . } ( t h i s . backwardArray [ c ]− t h i s . a c t u a l O f f s e t −
t h i s . i n i t i a l O f f s e t +2∗ t h i s . s i z e )%t h i s . s i z e { . . . } ;
è evidente che non è possibile ottenere un risultato migliore (computazionalmente parlando).
Un alternativa al gioco di indici e valori usati nei codici precedenti sarebbe
stata rappresentata dalla realizzazione dell’avanzamento o posizionamento dello scambiatore, facendo avanzare fisicamente i valori memorizzati in ciascuno
degli array in gioco. Se ad esempio si avesse avuto forwardArray caricato con
{24, 5, 6, ..., 0, 1} per far avanzare di uno “scatto” lo scambiatore (e quindi
simulare lo scatto che subivano gli scambiatori di Enigma ad ogni cifratura),
sarebbe stato necessario ricostruire l’array come {5, 6, ..., 0, 1, 24}, un lavoro
decisamente troppo gravoso per essere effettuato ad ogni chiamata del metodo
di avanzamento.
A seguito la specificazione della funzione dei metodi rimanenti:
• Costruttori: accettano come parametri vettori di char, vettori di int o
stringhe per realizzare forwardArray dopo aver verificato che i valori inseriti rispettino i vincoli dettati dalla rappresentazione dati adottata. Ciascuno costruttore prevede la chiamata del metodo privato makeBackward
che non fa altro che popolare backwardArray secondo i valori immagazzinati in forwardArray (si tratta di un’operazione che deve essere effettuata solo una volta in quanto l’uso degli indici specificato in precedenza
consente di evitare di dover ripopolare backwardArray ad ogni cifratura).
• forwardEncoding e backwardEncoding: eseguono la cifratura verso il riflessore e verso il visore secondo lo schema di conversione accennato in
precedenza (infatti sono passati come argomento interi e non caratteri).
• goNext: incrementa actualOffset della quantità how, specificata come argomento. Si noterà che il metodo goNext esegue automaticamente le operazioni di verifica del termine del giro dello scambiatori: se la somma di
initialOffset e actualOffset supera 26 (è come se un rotore di un contachilometri stesse passando dalla posizione 9 alla posizione 0) allora si generano
gli eventi per lista di ascoltatori al fine di comunicare l’avvenuto termine
del giro. La motivazione per l’uso di una gestione dei giri con eventi verrà
chiarita nelle parti successiva.
3 Enigma: versione informatica della macchina.
14
• clickArrived: necessari per l’implementazione della classe ClickListener,
eseguono come operazione l’avanzamento dello Scambiatore virtuale chiamante di una quantità specificata dall’evento passato come argomento,
mediante la chiamata al metodo goNext specificato pocanzi.
• ClickListnerList (classe privata): struttura dati a lista in cui verranno
inseriti tutti gli ascoltatori di eventi generati dalla variabile oggetto che
istanzia la classe in esame.
I metodi rimanenti non richiedono particolari spiegazioni in quanto semplicemente modificanti dati appartenenti all’oggetto chiamante, in alcuni casi dopo
aver effettuato un semplice controllo sull’input, o in alternativa restituenti i
valori dei dati privati dell’oggetto.
3.2.3
Classe Riflessore
La classe Riflessore implementa l’interfaccia Rotore.
Come dovrebbe risultare chiaro dalla spiegazione del funzionamento di Enigma specificata nella parte 2, il riflessore risulta a tutti gli effetti un Rotore
in quanto effettua la codifica dei valori numerici inseriti secondo lo schema di
conversione specificato in precedenza.
I metodi ereditati (forwardEncoding e backwardEncoding) sono necessari
a mantenere la compatibilità con l’interfaccia Rotore sebbene, in effetti, eseguano le stesse operazioni. Potrebbe dunque risultare non chiaro il legame di
ereditarietà tra Riflessore e Rotore ma la motivazione di questa scelta deriva
da considerazioni strategiche precise. In effetti la generalizzazione degli oggetti
mediante il meccanismo dell’ereditarietà, consente di poter costruire macchine virtuali Enigma aventi un grado di complessità decisamente maggiore del
dispositivo inventato da Scherbius. Nulla impedirebbe ad un programmatore di realizzare una versione di Enigma dotata di un numero ragguardevole di
Scambiatori e diversi meccanismi di riflessione, mediante gli oggetti che sono
specificati attraverso il progetto che si sta descrivendo. La gestione di Riflessore
diventa quindi maggiormente malleabile se considerato come una sottoclasse di
Rotore ed è proprio questo il motivo dell’apparente forzatura realizzata.
Il costruttore non prevede argomenti in quanto il riflessore viene realizzato
direttamente dal programma. Dato infatti che esso non aumenta la complessità
della cifratura ed avendo un ruolo pressoché passivo durante la codifica, si è
ritenuto sufficiente mantenere uno schema riflessivo adeguato, che quindi realizzi la corrispondenza biunivoca tra 2 contenuti dell’array di elaborazione e i
corrispettivi indici, per consentire una più semplice gestione dei dati da parte
dell’utente e del programmatore.
3.2.4
Classe ClickEvent ed interfaccia ClickListener.
La classe ClickEvent e l’interfaccia ClickListener sono necessari per la realizzazione degli “scatti” realizzati dalla macchina Enigma nel momento in cui
un rotore ultima il proprio giro rendendo necessario l’avanzamento del Rotore
successivo.
In pratica la generazione di un evento di tipo ClickEvent, come si può notare
dalla specificazione del clickArrived nella classe Scambiatore, simula appunto un
3 Enigma: versione informatica della macchina.
15
“click” ovvero uno scatto dello scambiatore corrente mediante l’applicazione del
metodo goNext.
La gestione di tale avvenimento mediante eventi consente di ottenere dei
vantaggi importanti:
• Innanzittutto automatizza il processo di verifica dell’avvenuto giro completo dello Scambiatore, in quanto i metodi coinvolti, ed in particolare
goNext, prevedono la verifica costante di che punto dell’avanzamento si
sia raggiunto.
• Secondariamente c’è anche da dire che nonostante (come risulterà chiaro
con la specificazione della classe Enigma) in questo progetto si sia deciso
di adottare una strategia di avanzamento semplice (uguale al contachilometri) nulla vieta che altri programmatori, aventi altri fini diversi dalla
simulazione puntuale di Enigma come si intende fare in questo progetto, decidano di adottare una modalità di avanzamento significativamente
differente. Se ad esempio si volesse che ad ogni lettera cifrata il primo
scambiatore avanzasse di 1 e il terzo di 2, allora la gestione ad eventi
consente di facilitare tale compito perché la chiamata dei metodi previsti dalla classe interna di Scambiatore (ossia ClickListenerList) effettua in
automatico tutte le operazioni necessarie. L’unica condizione per applicare tali regole è aggiungere in maniera oculata alla lista degli ascoltatori
degli eventi di un singolo Scambiatore, gli ascoltatori corretti per attuare
la strategia di avanzamento desiderata.
3.2.5
Classe PannelloPrese
La classe PannelloPrese è la trasposizione virtuale del pannello a prese multiple
di Enigma descritto nella sezione 2. Esso utilizza, allo stesso modo degli oggetti
di tipo Scambiatore, un array di andata ed uno di ritorno per la cifratura dei
caratteri ovviamente per le stesse ragioni specificate nelle sezioni precedenti.
Si potrà notare tuttavia che i costruttori di PannelloPrese, sono decisamente
più articolati dei costruttori della classe Scambiatore che si limitavano a controllare la correttezza degli input inseriti. La motivazione di tale complicazione
risiede nel fatto che l’inserimento di una sequenza che rispetti le regole specificate
per gli scambiatori non è più sufficiente per assicurare il corretto funzionamento
del pannello.
I controlli effettuati sono necessari infatti per verificare che nel momento
in cui si specifica una lettera (o un numero) in una determinata posizione nel
vettore, allora all’indice del vettore passato come argomento relativo alla posizione di tale lettera ci sia esattamente il valore relativo all’indice di tale lettera.
Per chiarire con un esempio si potrebbe dire che se nella posizione 0 del vettore è inserito il valore 3 (e quindi la lettera D), allora in posizione 3 dello
stesso vettore deve essere collocato il valore 0 (ovvero la A è trasformata in
D e la D è trasformata in A). Tale controllo è necessario proprio perché, in
caso tale corrispondenza non sia verificata, allora il pannello virtualizzato non
avrebbe più il funzionamento del pannello a prese multiple di Enigma, ma quello di una sostituzione monoalfabetica, già menzionata in precedenza in questa
documentazione.
I metodi hanno le seguenti specificazioni:
3 Enigma: versione informatica della macchina.
16
• makeBackward: esattamente come il metodo omonimo della classe Scambiatore, realizza l’array di ritorno backwardArray, una volta che è stato
correttamente inserito quello di andata forwardArray.
• forwardEncoding e backwardEncoding: realizzano la cifratura in avanti e
quella all’indietro passato un intero come argomento, allo stesso modo dei
metodi omonimi della classe Scambiatore.
I metodi rimanenti non necessitano di specificazioni ulteriori in quanto non
realizzanti operazioni da dover chiarire.
3.2.6
Classe Enigma
Si tratta della classe che esegue le operazioni di Enigma necessarie alla codifica
dei messaggi. In particolare si è deciso che, escludendo le operazioni di configurazione, che prevedono diversi metodi detinati a tali funzioni, l’unico ruolo attivo
degli oggetti della classe sarà attribuito ai metodi encodeChar e decodeChar.
Pertanto si tratta di un sistema di codifica char-by-char.
La classe Enigma si basa in particolare su 4 oggetti, che riproducono fedelmente i componenti utilizzati dalla versione reale della cifratrice: un pannello a
prese multiple istanziato come oggetto di tipo PannelloPrese con il nome panel,
un set di scambiatori possibili instanziato mediante un array di oggetti di tipo
Scambiatore con il nome di possible, un set di scambiatori effettivamente usati
nella codifica istanziato mediante un array di oggetti di tipo Scambiatore con il
nome di used, un riflessore istanziato come un oggetto di tipo Riflessore con il
nome di rif.
L’unico costruttore previsto, privo di argomenti, realizza il caricamento di
Enigma e l’istanziazione dell’array di Scambiatori possible. Tale caricamento
avviene mediante la lettura di un file contenuto nella posizione “/files/scambiatori.conf”. Tale file dovrà contenere: nella prima riga il numero di scambiatori
che si intendono specificare in seguito e nelle righe successive le stringhe contenenti lo schema di codifica degli scambiatori separate da una a-capo. In tale
maniera non si preclude la possibilità di estensione del progetto stesso: aumentando il numero di righe e quindi di scambiatori è possibile aumentare il
numero di combinazioni possibili degli scambiatori incrementando il grado di
complessità del simulatore realizzato.
A seguito la specificazione dei metodi realizzati:
• setPanel: due metodi di cui si eseguito l’overloading (uno accetta un oggetto di tipo String come argomento e l’altro un array di char) consentono
di istanziare la variabile panel richiamando il costruttore della classe PannelloPrese e passando come argomento la stringa o l’array argomento del
metodo in analisi.
• setTurningRules: metodo che fa si che il comportamento degli scambiatori
di Enigma sia quello a contachilometri. Infatti aggiungendo alla lista degli ascoltatori di ogni scambiatore lo scambiatore successivo, è sufficiente
far avanzare il primo per ottenere il comportamento sperato: applicando
infatti a tale scambiatore il metodo goNext, ogni volta che si esegue un
giro completo di ciascuno scambiatore questo genererà un evento di tipo
ClickEvent lanciato a tutti gli ascoltatori presenti nella propria lista di
ascoltatori, realizzando in maniera efficace il contachilometri desiderato.
3 Enigma: versione informatica della macchina.
17
• setUsed: istanzia la variabile used secondo l’ordine specificato dall’array
di interi passato come argomento. Si ritenuto di dover copiare gli Scambiatori nel vettore used da possible e non solo far riferimento (come è
noto le variabili oggetto sono puntatori ad oggetto nel linguaggio Java),
per evitare che ci fossero problemi di concorrenza dovuti al passaggio di
un vettore valido ma inconsistente da un punto di vista logico (il vettore
{0,0,0} è perfettamente valido in quanto tali elementi esistono nel vettore
possible). È tuttavia consigliabile evitare che si verifichino casi di ripetizione nel momento in cui si passa l’array di interi perché ciò implica una
riproduzione non fedele della cifratrice.
• setOffset: dopo aver effettuato i dovuti controlli, in corrispondena degli
indici dell’array passato come argomento, imposta il valore della varibile
initOffset degli scambiatori utilizzati.
• encodeChar: accetta un carattere alfabetico minuscolo, fa avanzare di una
posizione il primo scambiatore e restituisce il carattere maiuscolo relativo
alla lettera passata come argomento. Restituisce quindi il valore trasmutato del carattere di partenza passando quindi da testo chiaro a testo cifrato
(si è deciso di utilizzare la convenzione crittografica secondo la quale il
testo chiaro è minuscolo e quello cifrato maiuscolo). L’utility di cifratura
si compone, come si può notare delle seguenti fasi: la trasformazione del
carattere passato come argomento secondo le regole dell’oggetto panel; un
ciclo for in cui, ad ogni passo, ciascuno scambiatore utilizzato modifica il
risultato parziale della codifica dal primo verso l’ultimo; la trasformazione del carattere secondo le regole del riflessore; un ciclo for in cui viene
realizzata la cifratura da ciascuno scambiatore utilizzato modificando il risultato parziale fin qui ottenuto applicando il metodo backwardEncoding
(dall’ultimo verso il primo); un ultimo passaggio attraverso il pannello a
prese multiple per la trasformazione finale. Al termine della cifratura viene richiamato il metodo goNext per l’avanzamento del primo scambiatore
ed infine restituito il risultato.
• decodeChar: richiama il metodo encodeChar dopo aver modificato il testo
da decodificare in minuscolo in maniera che esso possa essere elaborato.
Tale facilità di utilizzo è dovuta, come dovrebbe essere noto, al riflessore
e pertanto il metodo in analisi si limita a modificare leggermente i dati
passati affinché essi vengano elaborati. Si noti che sia il metodo encodeChar che il metodo decodeChar elaborano solo caratteri alfabetici, ogni
altro carattere introdotto non viene mai elaborato e non comporta effetto
alcuno sulla cifratrice.
I metodi non descritti, come già avvenuto in questa documentazione, eseguono
delle operazioni tanto elementari da non meritare delucidazione alcuna.
3.2.7
Classe EnigmaSimulator
La classe EnigmaSimulator contiene le istruzioni per la realizzazione della GUI
simulante Enigma. Buona parte del codice è stata autogenerata da NetBeans
6.5 ma i metodi che non hanno nulla a che fare con l’estetica, e pertanto che
specificano il comportamento dei singoli componenti inseriti e la gestione della
cifratura/decifratura, sono stati realizzati dal programmatore.
3 Enigma: versione informatica della macchina.
18
Gli oggetti grafici principali sono:
• 3 Caselle Combinate: contengono gli scambiatori da utilizzare durante la
cifratura nell’ordine delle caselle stesse.
• 3 Spinner (istanziati da sorgente): contengono la disposizione attuale degli
scambiatori di Enigma (l’unità cifratrice).
• 1 Tabella: rappresenta il pannello a prese multiple. Nella prima colonna
le lettere di partenza, nella seconda quelle di arrivo.
• 1 Pulsante di conferma: richiama il metodo per verificare che le lettere
inserite nella seconda colonna della tabella del pannello rappresentino una
sequenza valida per il pannello a prese multiple e, in caso affermativo,
modifica con le disposizioni inserite il pannello a prese multiple di Enigma.
• 2 Aree di Testo: uno contiene il testo di partenza (cifrato o da decifrare)
e l’altro contiene il testo di arrivo (decifrato o da cifrare).
• 1 Gruppo di Radio-button: specificano se si intende cifrare o decifrare.
Questa specificazione è necessaria in quanto, come già ricordato in precedenza, esiste una convenzione precisa per i testi cifrati e una atrettanto
precisa per i testi chiari.
• 3 Pulsanti: per le operazioni di cifratura:
– Normalizza: richiama il metodo che elimina tutti i caratteri che non
verranno elaborati da enigma o modifica i caratteri che devono esserlo per essere elaborati (ad esempio le lettere accentate vengono
convertite in lettere non accentate).
– Avvia processo: richiama il metodo che esegue l’operazione specificata nel radio-button confermato.
– Inverti caselle: richiama il metodo che copia il contenuto della casella
di arrivo in quella di partenza per facilitare le operazioni di codificadecodifica in una sola macchina.
A seguito la specificazione dei metodi necessari alla gestione di eventi e del
funzionamento della cifratrice virtuale:
• SimpleTableModeListner (classe privata): classe necessaria alla gestione
delle modifiche della tabella che rappresenta il pannello a prese multiple. Il
codice con i controlli specificati esegue, in sostanza, le seguenti operazioni:
– Controlla che la prima colonna, che rappresenta la lettera di partenza
del pannello a prese multiple, non venga mai modificata.
– Controlla cha la seconda colonna, che rappresenta la lettera di arrivo
del pannello a prese multiple, vengano inseriti caratteri validi.
• prepare: istanzia tutte le varibili necessarie alla gestione della cifratura e
modifica i valori degli oggetti grafici specificati.
• setSpinnerChar: modifica i valori degli spinner a seconda del valore attuale
dell’offset di ciascuno scambiatore di Enigma.
4 La “Bomba” di Turing
19
• setCombos: carica il contenuto delle caselle combinate a seconda del numero di scambiatori presenti nell’oggetto Enigma istanziato e verifica che
non si verifichino ripetizioni tra i valori specificati.
Gli altri metodi presenti vengono richiamati nel momento in cui viene generato
l’evento relativo agli oggetti grafici specificati in precedenza. Pertanto la funzione di tali metodi è stata già descritta con la specificazione dei comportamenti
degli stessi oggetti grafici.
4
La “Bomba” di Turing
4.1
Sinossi del primo tentativo di crittoanalisi: la “bomba”
di Rejewski
Nel momento in cui Enigma venne adottata dall’esercito tedesco come cifratrice ufficiale delle comunicazioni della Germania, quasi tutti i paesi d’Europa
avevano rinunciato ad ogni tentativo di breccia nel crittosistema dei militari
tedeschi. Enigma era ritenuta praticamente impenetrabile e non vi era nessuna
tecnica sviluppata in precedenza che potesse aiutare nella crittoanalisi dei codici
prodotti dalla macchina.
Ciononostante il primo tentativo di attacco ad Enigma si tenne a partire dal
1931 al Biuro Szyfròw, l’ufficio di codici e cifre della Polonia. Qui un giovane statistico di nome Marian Rejewski, assoldato dopo che gli alti membri dell’esercito
si erano resi conto che per affrontare Enigma fosse necessaria una preparazione
tecnico-scientifica e non solo linguistica, trovò il primo enorme punto debole di
Enigma il quale gli consentì in appena un anno di trovare il modo di individuare
l’assetto dell’unità scambiatrice in poche ore.
Come è ben noto la chiave necessaria per impostare correttamente Enigma
era costituita da 3 informazioni: la disposizione degli scambiatori negli alloggiamenti, la posizione degli scambiatori e le lettere da sostituire nel pannello
a prese multiple. Anche se il grado di sicurezza garantito dal gran numero di
chiavi disponibili era decisamente alto, i tedeschi per aumentare ulteriormente
l’affidabilità del proprio sistema di codifica decisero di introdurre una nuova
variabile: la chiave di messaggio. La chiave di messaggio corrispondeva in pratica alla posizione degli scambiatori usata per cifrare il contenuto dell’intero
messaggio. L’assetto inserito nel cifrario era utilizzato solo ed esclusivamente
per cifrare la chiave di messaggio che veniva inviata 2 volte per evitare errori
durante la trasmissione. Un esempio di modus operandi poteva essere dunque
il seguente.
• L’operatore di Enigma X configurava la propria macchina inserendo i dati descritti nel proprio cifrario, ipotizziamo con un posizionamento degli
scambiatori di GTQ. Questo dato verrà d’ora in avanti chiamato chiave
giornaliera o quotidiana.
• X sceglieva la chiave che avrebbe usato per il proprio messaggio, poniamo
UJL. Questo dato è la chiave di messaggio.
• Con la propria Enigma configurata secondo la chiave quotidiana, X cifrava
la stringa UJLUJL, ottenendo, per esempio KIVBLE.
4 La “Bomba” di Turing
20
• X riconfigurava Enigma inserendo come assetto degli scambiatori UJL
anziché GTQ e cifrava il messaggio.
• L’insieme di KIVBLE ed il messaggio cifrato veniva infine consegnato
al marconista, il quale lo inviava all’operatore Enigma Y mediante codice
morse.
L’operatore Enigma Y che avesse voluto leggere il messaggio inviato da X
eseguiva quindi le seguenti operazioni:
• Y, con la propria macchina configurata secondo le indicazioni del cifrario,
riceveva il messaggio dal marconista.
• Prelevava le prime sei lettere, nel nostro esempio KIVBLE, e le decifrava con la propria macchina configurata con la chiave giornaliera GTQ
ottenendo la stringa UJLUJL.
• Saputo che la chiave di messaggio per quel particolare testo sarebbe stata
UJL, Y riposizionava gli scambiatori Enigma secondo l’ordine UJL e
decifrava il resto del messaggio ricevuto.
Il vantaggio di questo sistema di invio delle informazioni è evidente: la parte
di messaggio più a rischio perché cifrata secondo le informazioni del cifrario era
talmente ridotta che ogni tipo di strategia di analisi sarebbe stata inutile. Come
è noto, per eseguire anche solo l’analisi delle frequenze è necessario disporre di
un testo ragguardevole per riuscire ad ottenere dei risultati verosimili. Tuttavia
avendo scelto di cifrare per due volte di seguito lo stesso messaggio, i tedeschi
avevano dato la possibilità al crittoanalista polacco Rejewski di far breccia nei
codici generati da Enigma.
Il suo metodo crittoanalitico si pasava essenzialmente su di un unica considerazione: esisteva un legame molto forte tra la prima e la quarta lettera di
ogni messaggio, così come tra la seconda e la quinta, così come tra la terza e
la sesta, in quanto lettere uguali, e questo legame era determinato dalla chiave
quotidiana contenuta nel cifrario di Enigma.
Questa considerazione si rivelò praticolarmente proficua per Rejewski perché si accorse ben presto che il legame esistente tra queste coppie di lettere
era caratteristico della chiave quotidiana usata per quel particolare giorno e
soprattutto era indipendente dal pannello a prese multiple. Eliminato il pannello era dunque sufficiente verificare le caratteristiche dei legami esistenti tra
le coppie di lettere per individuare in poco tempo la chiave giornaliera per gli
assetti degli scambiatori, operazione che era effettuata meccanicamente tramite
l’uso di un dispositivo elettromeccanico chiamato “bomba”. La “bomba” rappresentava l’evoluzione delle tecniche crittoanalitiche in quanto, esattamente
come Enigma aveva rivoluzionato la crittografia introducendo procedure elettromeccaniche per la produzione di messaggi segreti, la bomba aveva introdotto
elementi elettromeccanici per far breccia nei codici nemici.
Grazie agli sforzi di Rejewski i polacchi furono in grado di decifrare praticamente tutte le comunicazioni segrete dei tedeschi dal 1931 fino all’alba dello
scoppio della seconda guerra mondiale nel 1938, anno in cui i tedeschi aggiornarono il proprio crittosistema secondo le indicazioni specificate in precedenza
nella presente documentazione (5 scambiatori da cui sceglierne 3 + 20 lettere da
4 La “Bomba” di Turing
21
poter sostituire nel pannello a prese multiple) oltre che riducendo ad una singola copia l’invio della chiave di messaggio (nell’esempio sopra descritto, anzichè
inviare UJLUJL l’operatore avrebbe inviato solo UJL).
4.2
Bletchley park
Dopo il successo dei crittoanalisti polacchi il mito dell’inviolabilità di Enigma
era stato sfatato definitivamente. I successi del Biuro Szyfròw si erano interrotti a causa dei nuovi scambiatori e dei nuovi cavetti per il pannello a prese
multiple; tuttavia, restava il fatto che Enigma non poteva essere più considerata
inattaccabile.
L’esempio dei polacchi fece inoltre capire agli alleati l’importanza di reclutare crittoanalisti anche tra i matematici. In Gran Bretagna, la Stanza 40, ovvero
l’ufficio di codici e cifre di Sua Maestà, era sempre stata appannaggio di linguisti
ed umanisti, ma da quel momento ci fu una sforzo concentrato per riequilibrare
la sua composizione, accogliendo matematici e scienziati. Il reclutamento avvenne in larga misura tramite amicizie: erano i membri dello staff che si mettevano
in contatto coi vecchi compagni di corso di Oxford e Cambridge, e ne sondavano
l’interesse per la crittografia professionale. C’era anche una rete che reclutava
donne con i diplomi di college prestigiosi, come il Newnham College e il Girton
College di Cambridge.
Le nuove reclute non venivano chiamate nella Stanza 40 di Londra, ma a
Bletchley Park, nel Buckinghamshire, sede della Government Code and Cypher
School (GC&CS), una nuova organizzazione cui la vecchia Stanza 40 passava
le consegne. Bletchley Park poteva ospitare un personale molto più numeroso,
fatto importante perché ci si aspettava che il conflitto avrebbe prodotto una valanga di intercettazioni crittate. Durante la prima guerra mondiale la Germania
aveva trasmesso due milioni di parole al mese, ma si prevedeva che i progressi
tecnologici nel campo delle radiotrasmissioni avrebbero fatto raggiungere i due
milioni di parole al giorno.
Nell’autunno 1939, scienziati e matematici presero confidenza col complesso
funzionamento di Enigma, e in tempo relativamente breve riuscirono a padroneggiare il metodo di analisi elaborato dai polacchi. Le risorse e il personale
dell’organizzazione inglese erano superiori a quelli del Biuro Szyfròw, perciò essa fu in grado di superare il problema dela maggior numero di scambiatori, e
in generale, della maggiore resistenza della nuova versione di Enigma. Ogni
ventiquattr’ore gli operatori tedeschi passavano simultaneamente ad una nuova chiave giornaliera, e i crittoanalisti britannici ingaggiavano una lotta contro
il tempo. Se riuscivano a scoprire l’assetto base di Enigma, potevano decifrare tutte le comunicazioni radio tedesche fino all’entrata in servizio della nuova
chiave, raccogliendo dati di enorme importanza militare.
Assimilata la strategia dei polacchi, i crittoanalisti di Bletchley cominciarono
a trovare nuove scorciatoie per scoprire le chiavi di Enigma. Per esempio, approfittarono del fatto che gli operatori tedeschi a volte sceglievano chiavi ovvie.
In teoria, essi avrebbero dovuto formare la chiave di messaggio con tre lettere rigorosamente casuali. Di fatto, anche per lo stress della situazione bellica, invece
di spremere le meningi e creare una sequenza casuale molti operatori premevano
tre lettere consecutive sulla tastiera, generando stringhe come QWE o BNM.
Queste banali, prevedibili chiavi di messaggio, vennero soprannominate cillies.
Un’altro tipo di cilly implicava l’uso ripetuto della stessa chiave di messaggio -
4 La “Bomba” di Turing
22
magari le iniziali della fidanzata dell’operatore; sembra che da una circostanza
del genere, connessa con la chiave CIL, sia derivato il soprannome che designò
l’intera categoria. Prima di lanciare contro Enigma un attacco in grande stile,
diventò abitudine dei crittoanalisti inglesi provare cillies, e a volte il trucco, con
l’aggiunta di un po’ di intuito, pagava.
I cillies non erano punti deboli di Enigma, ma del modo in cui veniva usata.
Anche errori umani commessi a un livello gerarchico più elevato compromisero
la sicurezza del sistema. I responsabili della compilazione dei cifrari dovevano
decidere quali scambiatori, e in quale posizione, sarebbero stati impiegati di
giorno in giorno. Essi tentarono di assicurare l’imprevedibilità delle posizioni
stabilendo che nessuno scambiatore potesse occuparne una per due giorni consecutivi. Così, indicando gli scambiatori con numero da 0 a 4, il primo giorno
poteva essere prescritta la disposizione 0-2-3, il secondo la disposizione 1-0-4,
ma non la 1-0-3, perché il terzo scambiatore sarebbe stato il medesimo e nella
stessa posizione. A prima vista questa regola parrebbe sensata, perché genera
disposizioni sempre diverse; ma introducendo un’importante limitazione ad ogni
disposizione tranne la prima, facilita molto il lavoro dei crittoanalisti. Dal punto
di vista matematico, in questo modo i compilatori dei cifrari ridussero di circa
il cinquanta per cento il numero di possibili disposizioni degli scambiatori.
I crittoanalisti di Bletchley compresero quello che stava accadendo, e ne
approfittarono. Una volta individuata la disposizione di un giorno, era possibile ridurre di circa la metà le possibili disposizioni del giorno successivo.
Naturalmente, anche il carico di lavoro in questo modo risultava dimezzato.
Una regola analoga a quella degli scambiatori stabiliva che dall’assetto del
pannello a prese multiple andassero esclusi i collegamenti con lettere contigue.
Così, S si poteva scambiare con qualsiasi lettera tranne R e T. L’idea era che
scambi così ovvi andassero evitati, ma ancora una volta ciò riduceva gravemente
il numero di chiavi possibili.
La ricerca di nuove scorciatoie era necessaria perché la macchina Enigma
continuò ad evolvere per tutta la durata del conflitto. I crittoanalisti furono
costretti a raffinare, modificare e perfino riprogettare le bombe derivate da Rejewski, e ad escogitare strategie originali. Una delle ragioni del loro successo fu lo
strano miscuglio di matematici, scienziati, liguisti, cultori di studi classici, maestri di scacchi e appassionati di cruciverba che popolavano le «capanne», come
venivano chiamati i locali in cui risiedevano i vari crittoanalisti e dove svolgevano il loro lavoro. Un problema ostico passava da un decrittatore all’altro finché
cadeva sotto gli occhi di una persona con la mentalità adatta a risolverlo, o
almeno a semplificarlo prima di passarlo ad un collega. Per Bletchley passarono
molti grandi crittoanalisti, che fecero scoperte importanti; una descrizione particolareggiata di tutti i loro contributi richiederebbe diversi volumi. Tuttavia,
se c’è uno studioso che merita un posto a parte, questi è Alan Turing, colui che
è considerato il padre dell’informatica, che individuò il principale punto debole
di Enigma e lo sfruttò fino in fondo. Grazie a Turing fu possibile continuare a
tradurre messaggi Enigma anche nelle circostanze più difficili.
4.3
La “bomba” di Turing
Il sistema crittoanalitico di Rejewski si basava sul fatto che gli operatori Enigma inviavano 2 volte la chiave di messaggio, crittata con la chiave giornaliera,
prima di inviare il messaggio vero e proprio, crittato con la chiave di messaggio.
4 La “Bomba” di Turing
23
Una volta individuata la chiave giornaliera grazie ai collegamenti tra le coppie
di lettere e l’ausilio di tutte le “bombe” capaci di verificare tutte le possibili disposizioni degli scambiatori, per i crittoanalisti la maggior parte del lavoro era
fatto e il resto della giornata poteva essere trascorso decrittando tutti i messaggi
intercettati. Tuttavia se fosse mancato il duplice invio della chiave, così come
sarebbe accaduto nel giro di pochi anni, tutto il lavoro fatto dai polacchi sarebbe
stato inutile. Ecco perché il lavoro di Alan Turing venne finalizzato all’individuazione di una falla sistemica, indipendente dal modo in cui Enigma venisse
utilizzata dagli operatori e che coinvolgesse, al più, la conoscenza di parte del
testo chiaro.
Col passare del tempo, Turing constatò che a Bletchley si stava accumulando una patrimonio di messaggi decifrati, e notò che molti di essi rivelavano
una struttura piuttosto rigida. Pensò quindi che il contenuto dei crittogrammi nuovi si potesse spesso inferire, almeno in parte, in base ai crittogrammi
risolti, prestando attenzione a dati come la provenienza del messaggio e l’ora di
trasmissione. Per esempio, l’esperienza insegnava che tutti i giorni, poco dopo
le sei del mattino, i tedeschi trasmettevano brevi bollettini meteorologici cifrati. Perciò, un crittogramma captato alle 6.05 antimeridiane quasi certamente
conteneva la parola Wetter («tempo atmosferico» in tedesco). Il rigido modus
operandi delle organizzazioni militari implicava che simili comunicazioni fossero
stereotipate anche nello stile. Questo aumentava la probabilità che il crittogramma contenesse parole come wetter in posizioni fisse. L’esperienza poteva
quindi fornire indicazioni ancora più precise, per esempio che le prime sei lettere
della seconda riga di certi tipi di crittogrammi corrispodevano quasi sempre alla
parola wetter.
Quando un frammento di testo chiaro poteva essere interpretato in base a
considerazioni non crittoanalitiche, si parlava di crib («culla», o «copiatura»,
nel senso della ben nota scorrettezza scolastica).
Turing era sicuro di poter approfittare dei cribs per creare una procedimento
di soluzione dei crittogrammi Enigma diverso da quello di Rejewski. Disponendo del crittogramma e sapendo che una sua parte, per esempio ETJWPX,
corrispondeva a wetter, la sfida sarebbe consistita nell’individuare l’assetto di
Enigma che trasformava la seconda sequenza di lettere nella prima. Il metodo
più diretto, ma poco pratico, in cui un crittoanalista poteva affrontare il problema era prendere una replica di Enigma, digitare wetter e vedere se il risultato
era ETJWPX; se non lo era, cambiare a poco a poco, una per volta e con metodo, le regolazioni (cominciando dai cavetti, proseguendo con gli scambiatori,
e così via) fino ad ottenere la sequenza cercata.
Il guaio era ciò che in crittoanalisi rende spesso inutile il metodo per prova
di errore o a forza bruta (brute force): gli assetti possibili erano 159 miliardi
di miliardi, e la guerra sarebbe finita molto prima che il crittoanalista avesse
effettuato un’insignificante porzione dei controlli necessari.
Per semplificare il problema, Turing imitò la strategia di Rejewski di scomporre l’assetto di Enigma in parti che comportassero un numero più accettabile
di possibilità. In particolare, voleva separare il problema della disposizione degli
scambiatori (quali scambiatori usare, e in quali alloggiamenti) e del loro orientamento, dal problema dei collegamenti del pannello a prese multiple. Se per
esempio avesse potuto ricavare da un crib un indizio che non avesse nulla a
che fare col pannello, sarebbe forse riuscito a trovare il modo di controllare i
1.054.560 assetti (60 disposizioni x 17.576 orientamenti) degli scambiatori. Ri-
4 La “Bomba” di Turing
24
solto questo problema, quello del pannello a prese multiple si sarebbe potuto
affrontare per via deduttiva.
Alla fine, la sua attenzione si concentrò su un particolare crib, contenente
delle concatenazioni. Tali concatenazioni riguardavano le lettere del testo chiaro
e del testo crittato nell’ambito di un crib. Per esempio, il crib mostrato in figura
7 contiene una concatenazione:
Fig. 7: Uno dei cribs di Turing, con la concatenazione messa in evidenza
Non bisogna dimenticare che i crib sono solo ipotesi. Tuttavia, se questa
particolare ipotesi è corretta, possiamo collegare le lettere w→E, e→T, t→W,
in quanto appartenenti alla concatenazione. Anche se non sappiamo nulla degli
assetti della macchina Enigma, possiamo chiamare «a» il primo assetto, qualunque esso sia. Di questo assetto sappiamo solo che porta a cifrare w come E.
Dopo di che, il primo scambiatore avanza di una lettera, facendo assumere ad
Enigma l’assetto «a+1», e la lettera e è cifrata come T. Il primo scambiatore
avanza di un altro posto e cifra una lettera che non fa parte della concatenazione, ragion per cui ignoriamo questa cifratura. Avanza ancora di uno spazio,
e di nuovo ci imbattiamo in una lettera inclusa nella concatenazione: sappiamo
che nell’assetto «a+3», t è cifrata come W. Riassumendo, siamo sicuri che:
Nell’assetto«a» Enigma critta w come E
Nell’assetto«a+1» Enigma critta e come T
Nell’assetto«a+3» Enigma critta t come W
Per ora la concatenazione sembra solo una curiosità, ma Turing sviluppò tutte le
implicazioni dei rapporti all’interno del crib, e capì che rappresentavano proprio
il tipo di drastica scorciatoia che gli occorreva per far breccia in Enigma. Invece
di lavorare con una sola macchina per verificare ogni assetto egli cominciò ad
usarne tre: una per la cifratura di w come E, un’altra per la cifratura di e come
T, la terza per la cifratura di t come W. Le tre macchine avevano assetti identici,
se si eccettua il fatto che la seconda avrebbe avuto gli scambiatori orientati un
posto avanti rispetto alla prima (a+1), e la terza avrebbe avuto gli scambiatori
orientati di tre posti avanti rispetto alla prima (a+3). Stabilito ciò, Turing
si immaginò un trafelato crittoanalista che senza sosta inseriva e disinseriva
cavetti, mutava posto agli scambiatori e ne modificava l’orientamento, finché
ogni macchina avesse cifrato come suggerito dal crib.
Fin qui, Turing non sembra aver concluso molto. Il povero crittoanalista
ha ancora 159 miliardi di miliardi di assetti da controllare, e per di più deve
farlo non su una, ma su tre macchine Enigma contemporaneamente. Ma il
4 La “Bomba” di Turing
25
passo successivo del ragionamento di Turing trasforma la natura della sfida, e
la semplifica radicalmente.
Egli immaginò di collegare le tre cifratrici con cavi elettrici posti tra l’input
di una macchina e l’output della successiva, come mostrato in figura 8. In effetti,
la concatenazione ciclica del crib è riprodotta dal circuito elettrico. Il circuito si
chiuderebbe, permettendo alla corrente di percorrerlo, solo quando tutte e tre
le macchine avessero raggiunto un assetto che realizzasse la concatenazione. A
questo punto, se una lampadina facesse parte del circuito essa si accenderebbe,
segnalando che la ricerca ha avuto buon esito. Per ora, ogni macchina doveva
ancora controllare 159 miliardi di miliardi di combinazioni - il procedimento era
stato automatizzato, non semplificato. Ma i passi compiuti fin qui erano solo
preparatori in vista del vero colpo da maestro, che d’un tratto avrebbe reso il
controllo degli assetti cento milioni di milioni di volte più facile.
Turing aveva costruito il circuito in modo da annullare l’effetto del pannello a
prese multiple, e poter ignorare i miliardi di assetti possibili di questo elemento.
Osservando la figura 8 si constata che nella prima macchina Enigma la corrente
entra negli scambiatori ed emerge in corrispondenza di una lettera sconosciuta,
che chiameremo L1 . Poi la corrente attraversa il pannello e trasforma L1 in
E. Questa E è collegata tramite un filo elettrico alla e della seconda macchina
Enigma, e al passaggio della corrente attraverso il scondo pannello si trasforma
di nuovo in L1 . In altre parole, i due pannelli a prese multiple si annullano a
vicenda. In modo analogo, la corrente in uscita dagli scambiatori della seconda
macchina Enigma entra negli scambiatori in corrispondenza di L2 , prima di
essere trasformata in T. Questa T è collegata tramite un filo elettrico alla t
della terza Enigma, e col passaggio della corrente attraverso il terzo pannello si
trasforma di nuovo in L2 . In breve, i pannelli si annullano a vicenda in tutto il
circuito; perciò, si poteva prescindere completamente della loro esistenza.
Turing aveva solo bisogno di collegare l’output del primo gruppo di scambiatori in corrispondenza di L1 , all’input del secondo gruppo di scambiatori,
sempre in corrispondenza di L1 , e così via. Purtroppo egli non conosceva il
valore di L1 , perciò era costretto a collegare le 26 uscite del primo gruppo di
scambiatori ai 26 ingressi corrispondenti del secondo gruppo di scambiatori, e
così via. In questo modo si formavano 26 circuiti, ciascuno dei quali dotato di
una lampadina a segnalarne la chiusura. I tre gruppi di scambiatori potevano
così limitarsi a controllare i 17.576 orientamenti loro concessi, col secondo gruppo di scambiatori sempre un passo avanti del primo, e il terzo due passi avanti
il secondo. Alla fine, scoperto il giusto orientamento degli scambiatori, uno dei
circuiti si chiudeva causando l’accensione di una lampadina. Se gli scambiatori
avessero mutato orientamento ogni secondo, il controllo di tutti gli orientamenti
avrebbe richiesto solo 5 ore.
Restavano solo due difficoltà. Innanzitutto era possibile che le tre macchine
funzionassero con una disposizione errata degli scambiatori.
Poiché le cifratrici contenevano tre scambiatori su cinque, disposti in qualunque ordine, le disposizioni possibili erano sessanta. Quindi, controllati i 17.576
orientamenti, se la lampada non si fosse illuminata sarebbe stato necessario
cambiare disposizione, e ripetere il procedimento. Un’alternativa era munirsi di
un gran numero di repliche di Enigma (sessanta gruppi di tre) e farle lavorare
in parallelo.
La seconda difficoltà riguardava la determinazione del’assetto del pannello
a prese multiple, una volta risolti i problemi degli scambiatori. In questo caso,
4 La “Bomba” di Turing
26
Fig. 8: La concatenazione del crib può essere riprodotta sotto forma di concatenazione elettrica. Tre macchine Enigma sono regolate in modo identico,
se si eccettua il fatto che la seconda ha gli scambiatori orientati un poto
avanti rispetto alla prima (a+1), e la terza ha gli scambiatori orientati di
tre posti avanti rispetto alla prima (a+3). L’output di ciascuna Enigma
è poi collegato all’input della successiva. Durante il funzionamento, i tre
gruppi di scambiatori avanzano all’unisono finché il circuito si chiude e
la lampadina si accende. L’assetto raggiunto in quel momento è quello
cercato. Nel diagramma qui sopra il circuito è completo, cioè corrisponde
al giusto assetto degli scambiatori.
4 La “Bomba” di Turing
27
la soluzione era relativamente semplice. Usando una macchina Enigma con la
giusta disposizione e il giusto orientamento degli scambiatori, il crittoanalista
avrebbe digitato il testo cifrato e osservato il testo chiaro risultante. Una stringa
come tewwer avrebbe suggerito, per esempio, di collegare con un cavetto le
prese t e w del pannello. L’immissione di altri frammenti di crittogramma
avrebbe chiarito la posizione degli altri cavetti.
L’uso simultaneo di cribs, concatenazioni e cifratrici collegate elettricamente
portò a un risultato quasi miracoloso, che solo Turing, con la sua cultura matematica e la propensione a ragionare in termini di congegni immaginari, avrebbe
potuto conseguire. La macchina astratta universale di Turing era stata da lui
concepita per far luce su sottili questioni teoriche circa l’indecidibilità matematica; ma interessi puramente accademici l’avevano abituato ad uno stile di
ragionamento assai propizio all’ideazione di un’altra macchina: un apparecchiatura per la decifrazione automatica capace di influenzare eventi tragicamente
reali.
Le idee di Turing si concretizzarono nel 1940, quando egli terminò il progetto di quella che sarebbe passata alla storia come la “bomba” di Turing, così
chiamata per il ticchettio prodotto dagli scambiatori che avanzavano meccanicamente oltre che per fare onore all’ideatore dell’omonimo dispositivo creato da
Rejewski.
Fig. 9: La “bomba” di Turing. Ricostruzione al “Bletchley Park Museum”
Il primo prototipo di bomba, battezzata «Victory», arrivò a Bletchley Park
il 14 marzo 1940. Fu subito messa in funzione, ma i risultati iniziali non furono esattamente entusiasmanti. Il congegno, molto più lento di quanto ci si
aspettasse, impiegò una settimana per individuare una sola chiave. Fu fatto uno
sforzo collettivo per migliorare la sua efficienza, e un progetto modificato venne
consegnato poche settimane più tardi. Ma per disporre della nuova versione di
bomba ci vollero 4 mesi. Nel frattempo i crittoanalisti dovettero affrontare la
calamità da loro temuta. Il 10 maggio 1940 i tedeschi cambiarono la procedura
di comunicazione delle chiavi. La chiave di messaggio non venne più ripetuta e
le decifrazioni di crittogrammi Enigma crollarono di colpo. Il blackout durò fino
5 La “Bomba” di Turing: versione Informatica
28
all’8 agosto, quando arrivò la nuova bomba. Chiamata «Agnus Dei», o «Agnes»
per brevità, essa corrispondeva al dispositivo sognato da Turing.
Di li a otto mesi le bombe in funzione furono quindici: divoravano cribs,
controllavano assetti, rivelavano chiavi, ticchettavano come un esercito di nonne
intente a sferruzzare. Se tutto andava bene, una bomba era in grado di individuare una chiave Enigma in una sessantina di minuti al massimo. Una volta
stabiliti i collegamenti sul pannello e la disposizione degli scambiatori (cioè la
chiave di messaggio) per una intercettazione, dedurre la chiave giornaliera diventava un compito facile. Allora si potevano decifrare tutti i messaggi spediti
quello stesso giorno.
Anche se le bombe rappresentavano un progresso crittoanalitico di prima
grandezza, la decifrazione non era diventata una mera routine. C’erano molti
ostacoli da superare prima che uno di quei congegni potesse cercare una chiave. Per esempio, per funzionare la bomba aveva bisogno di crib. I solutori di
codici con più esperienza lo indicavano agli operatori, ma niente garantiva che
il suggerimento fosse giusto. E anche se era giusto, poteva non riferirsi al punto giusto del crittogramma; in altre parole, la parola o la frase che secondo il
crittoanalista si trovava nel messaggio in codice poteva davvero farne parte, ma
in una posizione diversa da quella da lui ipotizzata. In questo caso, però, un
semplice trucco permetteva di controllare se un crib si trovasse nella posizione
corretta. Nel crib seguente, il crittoanalista è sicuro che il testo chiaro faccia
parte del crittogramma, ma non è certo di dove collocarlo alle lettere giuste.
Una delle caratteristiche di Enigma, dovuta alla presenza del riflessore, era
l’impossibilità di cifrare una lettera con se stessa. Così, a può essere cifrata
in qualunque modo fuorché come A. Ne consegue che il crib dell’esempio dev’essere male allineato: infatti la prima e di wetter coincide con una E del
crittogramma. Per trovare l’allineamento giusto, conviene spostare il testo chiaro rispetto al crittogramma finché nessuna lettera è al di sopra di una lettera
uguale. Muovendo il testo chiaro di un posto verso sinistra, l’allineamento non
è ancora soddisfacente, questa volta perché la prima s di sechs è sopra un’altra
S. Invece, muovendo il testo chiaro di un posto verso destra, non si osservano sovrapposizioni inammissibili. Questo crib andrebbe quindi utilizzato per
effettuare la ricerca automatica della chiave giornaliera.
5
5.1
La “Bomba” di Turing: versione Informatica
Considerazioni sulla simulazione
La simulazione della “Bomba” di Turing necessita di alcune considerazioni introduttive. Se in effetti ci si limitasse all’imitazione pura e semplice dell’esatto
comportamento della macchina, allora il lavoro eseguito per la simulazione di
Enigma sarebbe più che sufficiente per realizzare la versione informatica. Tutta
la fase preliminare all’impostazione dell’assetto delle varie Enigma coinvolte nella Bomba consisterebbe in poche fasi, da eseguire tutte manualmente. La prima
5 La “Bomba” di Turing: versione Informatica
29
sarebbe l’individuazione della posizione da far assumere al crib all’interno del testo cifrato manualmente. La seconda sarebbe la configurazione di una adeguato
numero di Enigma secondo il numero di concatenazioni coinvolte nel crib, semplicemente attuabile mediante l’ausilio del metodo setOffset. La terza ultima
fase consisterebbe infine nella verifica dell’assetto che realizzi la concatenazione
per ciascuna delle 60 possibili disposizioni degli scambiatori negli alloggiamenti.
Tuttavia si ritiene che la previsione di funzioni aggiuntive come l’individuazione automatica delle concatenazioni del crib, possa essere un aspetto non
trascurabile. Nonostante il lavoro sia facilitato rispetto a come erano costretti a
lavorare gli operatori di Bletchley Park, tale funzione non compromette in maniera eccessiva la fedeltà al funzionamento del simulatore anche perché, in fin
dai conti, l’individuazione del posto ottimale in cui inserire il crib e il corrispettivo testo cifrato deve continuare ad essere fatto manualmente. Anche potendo
prevedere un programma in grado di individuare tutte le posizioni valide del
crib all’interno del testo cifrato, sarebbe sempre l’operatore umano a fornire alla macchina le informazioni aggiuntive per adottarne una in particolare (sempre
prendendo ad esempio il crib wetter descritto in precedenza, un programma potrebbe individuare una sua possibile collocazione alla fine del crittogramma; ma
ciò è ovviamente una semplice coincidenza in quanto i crittoanalsti saprebbero
bene che la parola deve comparire in certe posizioni ben definite).
Pertanto si è deciso di prevedere classi e funzioni con le seguenti funzioni:
• Individuazione dell’allineamento ideale di un crib all’interno di un frammento di crittogramma.
• Istanziazione automatica delle Enigma necessarie all’individuazione della
chiave di messaggio.
• Esecuzione della ricerca in parallelo di tutti gli assetti di scambiatori
risolventi il problema.
5.2
Specifiche di oggetti e metodi
5.2.1
Classe EnigmaForAnalysis
Si tratta di una sottoclasse della classe Enigma specificata in precedenza. Il
motivo dell’estensione e dell’utilizzo dell’ereditarietà è presto detto: è necessario
che la versione di Enigma per la crittoanalisi dei crittogrammi preveda delle
particolari funzioni aggiuntive ed in particolare i metodi getCurrentConfig e
addOffset.
getCurrentConfig è un metodo che restituisce la configurazione attuale degli
scambiatori di Enigma; questo metodo è necessario per facilitare il compito
degli altri programmi che si poggiano su oggetti del tipo EnigmaForAnalysis,
restituendo l’informazione sull’assetto attuale in una forma più gestibile come
la stringa piuttosto che l’array di char.
addOffset è un metodo che fa avanzare Enigma di un valore i passato come argomento; questo metodo è necessario per impostare la distanza che deve
esistere tra gli assetti delle varie Enigma che compongono la bomba e deve ovviamente essere fatta mediante il metodo goNext ereditato dalla superclasse per
consentire che si abbia l’avanzamento opportuno di tutti gli scambiatori nel caso
sia raggiunto il limite dell’assetto (passaggio da Z ad A in uno degli scambiatori).
5 La “Bomba” di Turing: versione Informatica
5.2.2
30
Classe BadCribException
Si tratta di una sottoclasse della classe Exception prevista dall’SDK Java che
consente di gestire in maniera specifica il caso in cui sia stato passata, alla classe
che si occupa dell’individuazione della posizione del crib nel crittogramma, una
stringa che non produce concatenazioni.
Vi è solo un costruttore che carica la variabile private msg con un valore
passato come argomento e l’override del metodo toString.
5.2.3
Classe CribNode
Si tratta della classe chiave per l’individuazione automatica delle concatenazioni.
In sostanza individua l’esistenza di un ciclo e memorizza in una struttura dati
ad albero tutte le possibili concatenazioni che si possono realizzare con il crib e
il crittogramma passati come argomento. Esso si compone, per quanto riguarda
i campi privati di:
• chiaro: rappresenta qual’è il carattere in chiaro di partenza
• cifra: rappresenta come il carattere in chiaro venga cifrato nel nodo corrente.
• end: si tratta di una variabile di controllo; vale true se uno dei nodi figli
del nodo corrente è raggiunto alla fine della ricerca ovvero se è riuscito a
chiudere la concatenazione tornando al carattere di partenza; vale false su
l’evetualità sopra descritta non si verifica.
• offset: rappresenta la distanza dell’allinemento in esame da quello di
partenza.
• sons: si tratta della struttura dati a lista che contiene tutte le possibili
concatenazioni che si possono realizzare a partire dall’allinemento corrente
(per esempio se si considera il crib e il testo cifrato wetter e ETJWPX,
risulta chiaro che se al primo ciclo la w viene crittata come E, al passaggio
successivo è necessario verificare se la prima e di wetter, in posizione
2 nella parola, o la seconda, in posizione 5 nella parola, producano una
concatenazione valida; è evidente che in questo caso solo la prima produrrà
una concatenazione).
• initChar: si tratta del carattere da cui si parte per generare le concatenazioni. È necessario per verificare, ad ogni generazione di figli, se si sia
conclusa la ricerca di una concatenazione.
Le specifiche dei metodi sono le seguenti:
• CribNode (costruttore): ricevuti in ingresso un array di char che rappresenta il crib ed un array di char che rappresenta il crib cifrato inizializza
cifra e chiaro secondo il valore di off passato come argomento e verifica,
per ogni occorrenza di cifra adattato in minuscolo, se tale valore compaia
nel crib passato come argomento. Se tale evenienza si verifica aggiunge
alla lista dei figli tale occorrenza. Al termine del popolamento della lista
dei figli inizializza il proprio campo di controllo end a seconda del fatto
che uno dei propri figli abbia o meno completato la concatenazione con il
crib passato e il corrispettivo ipotetico testo cifrato.
5 La “Bomba” di Turing: versione Informatica
31
• CribNode (costruttore): copia i valori del CribNode da copiare in quello
corrente rendendo opinabile la copiatura della lista dei figli.
Come già avvenuto nella presente documentazione si rimandano i restanti metodi alla lettura per la loro facilità di comprensione.
5.2.4
Classe CribNodeList
È la classe utilizzata dalla classe precedente per implementare la lista dei figli.
Prevede al suo interno una classe privata CribNodeListNode per memorizzare
ogni singolo nodo in un oggetto separato che punta all’elemento successivo della
lista.
Le specifiche dei metodi sono le seguenti:
• CribNodeList (costruttore): privo di argomenti, inizializza a null il valore
del nodo radice.
• CribNodeList (costruttore): avente come argomento un’altra CribNodeList, copia l’intero contenuto della lista passata nella lista corrente.
• addNode: aggiunge un nodo in fondo alla lista corrente.
• isClosedLoop: verifica se la lista corrente contiene dei nodi che chiudono la
concatenazione, ovvero se esiste almeno un CribNode nella lista corrente
che restituisca true quando gli viene applicato il metodo getEnd.
• getPossibleWays(statico): conta, passato come argomento un CribNode,
quante sono le concatenazioni chiuse che produce tale nodo. Per ogni
figlio del nodo applica ad esso getPossibleWays, sommando tutti i risultati
possibili. Se un nodo terminale (privo di figli) ha chiuso il cilo viene
ritornato un 1, in caso contrario uno 0.
• toCribNodeArray: converte la lista corrente in un array di CribNode.
• getValidLoop(statico): passato come argomento un CribNode, restituisce
una lista contenente la prima concatenazione di nodi producente un ciclo valido (quindi chiuso) a partire dal nodo passato come argomento ed
analizzando le caratteristiche dei figli.
Come già avvenuto nella presente documentazione si rimandano i restanti metodi alla lettura per la loro facilità di comprensione.
5.2.5
Classe CribTree
Rappresenta l’oggetto unico che raccoglie un’unico CribNode radice da cui dipartono tutti i figli in cui si verifica la concatenazione, costruendo una vera e
propria struttura ad albero n-ario variabile.
I metodi implementati consistono semplicemente nell’applicazione dei metodi
statici della classe CribNodeList al nodo radice.
5 La “Bomba” di Turing: versione Informatica
5.2.6
32
Classe Bomb
È una classe che rappresenta un unica bomba di Turing che verifica gli assetti
degli scambiatori realizzanti una concatenazione per una singola disposizione di
scambiatori.
Si compone di un certo numero di campi privati:
• crib: è il crib che si presume comparire nel testo cifrato codedCrib.
• codedCrib: è il testo cifrato in si presume si trovi la variabile crib.
• enigmas: è i vettore di EnigmaForAnalysis che saranno configurate secondo le concatenazioni possibili di crib in codedCrib individuate dalla
presente classe.
• vett: è il vettore di CribNode che contiene le configurazioni necessarie per
inizializzare l’array enigmas e per verificare di aver individuato l’assetto
corretto.
• offset: rappresenta la distanza del crib passato come argomento dall’inizio
del testo cifrato, da considerare nel momento in cui si produce l’elenco
degli assetti risolventi il crittogramma.
• scambUsed: contiene il vettore degli scambiatori utilizzati con corrispettivo codice.
• possibleRes: istanza della classe ArrayList prevista nello SDK per immagazzinare tutti gli assetti risolventi il crittogramma.
Per quanto riguarda i metodi previsti, ecco le loro specifiche:
• Bomb(costruttore): accetta come argomenti il crib di partenza, il testo
cifrato in cui si presume essere contenuto il crib, la disposizione degli
scambiatori e l’offset iniziale. Dopo aver inizializzato le variabili necessarie, richiama il metodo privato configure, per popolare vett con una
concatenazione valida (se presente nel codedCrib). In caso vett rimanga
pari a null (ovvero nel caso il crib nel codedCrib non produca alcuna concatenazione o nel caso siano state passate stringhe vuote) viene lanciata
un’eccezione BadCribException, in caso contrario si procede all’inizializzazione del vettore enigmas secondo le caratteristiche della concatenazione,
memorizzate in vett.
• configure: verifica se il crib corrente possa produrre concatenazioni in codedCrib. Nel caso i due vettori siano di lunghezza uguale allora viene
richiamato il metodo normalConfiguration. In caso contrario si tentano tutti gli allineamenti possibili di crib in codedCrib validi (che ovvero
non contengono lettere alfabetiche uguali in corrispondenza dei medesimi
indici) e per ciascuno si verifica la chiusura della concatenazione.
• normalConfiguration: accetta due array (il crib e il testo cifrato corrispondente) oltre che un intero, per sapere a che distanza collocare il crib, e
verifica se uno degli alberi generati a partire da ciascun allineamento produca un ciclo chiuso. In caso affermativo carica vett con tale ciclo chiuso
altrimenti lo lascia con valore null.
5 La “Bomba” di Turing: versione Informatica
33
• find: testa tutte i 17.576 possibili assetti al fine di verificare se uno di
essi realizzi la concatenazione che è memorizzata in ciascun nodo presente
in vett. Nel caso ne venga trovata una che chiuda il ciclo, il numero
dell’assetto corrente viene convertito nell’assetto in lettere dal metodo
numberToAlfaConversion e immagazzinato nell’ArrayList possibleRes.
• printSequence: restituisce una stringa in cui sono specificate l’indice di
partenza della concatenazione (ovvero quale lettera in codedCrib rappresenta l’inizio della concatenazione) e la sequenza di concatenazioni tra
lettere memorizzate in vett.
• getResults: viene restituito un array di stringhe in cui sono memorizzati
tutti gli assetti immagazzinati in possibleRes.
• getArray: restituisce la copia dell’array contenente l’assetto degli scambiatori analizzato dalla bomba corrente.
• alfaToNumberConversion(statico): converte una stringa di 3 caratteri alfabetici nell’indice corrispondente all’assetto di Enigma ad essa relativo.
È come se venisse fatta una conversione da un numero espresso in base 26
(in cui i simboli sono a,b, ..., z) in un numero in base 10.
• numberToAlfaConversion(statico): converte un numero nell’assetto corrispondente di Enigma ad esso relativo. Funzione inversa del metodo precedente, converte un numero espresso in base 10 in un numero espresso in
base 26 con i simboli specificati in precedenza.
• notEqualsCharArray(statico): restituisce true se i due array passati come
argomento contengono diversi valori alfabetici in corrispondenza dei medesimi indici, false se c’è almeno un indice in cui i valori alfabetici sono
uguali.
5.2.7
Classe BombRunner
Classe wrapper della classe Bomb per rendere possibile l’esecuzione in multithread del metodo find. Implementa l’interfaccia Runnable per rendere possibile
la parallelizzazione mediante oggetti di tipo Thread ed effettua l’unboxing dei
metodi contenuti nell’oggetto Bomb istanziato al suo interno.
5.2.8
Classe AlanTuringBombs
Rappresenta la realizzazione informatica di «Agnes» ovvero la bomba creata ed
immaginata da Turing che verifica tutte le disposizioni di Scambiatori possibili.
In sostanza una volta istanziato un oggetto di questa classe vengono create
tante variabili di tipo BombRunner quante sono le disposizioni possibili di 5
scambiatori in 3 alloggiamenti (60 in tutto), le quali poi, mediante il metodo
startThemAll, individueranno tutti gli assetti risolventi il crittogramma.
Le variabili private con le loro funzioni sono le seguenti:
• threads: l’array di BombRunner in cui verranno immagazzinate tutte le
bombe necessarie a verificare ciascuna disposizione.
• crib: la stringa che rappresenta il crib.
5 La “Bomba” di Turing: versione Informatica
34
• codedCrib: la stringa che rappresenta il testo cifrato in cui si presume
essere memorizzato il crib.
• initOffset: la distanza del codedCrib dall’inizio della cifratura di cui tenere
conto nel momento in cui si restituisce l’assetto risultante (operazione fatta
dalle singole Bomb).
Invece, i metodi sono i seguenti:
• AlanTuringBombs(costruttore): verifica se siano state passate stringhe
vuote per generare una BadCribException e solo una volta estinto tale
pericolo inizializza tutte le variabili precedentemente descritte usando il
metodo disposizioni per generare ciascuna disposizione di 3 elementi in un
set di 5.
• startThemAll: genera un Thread per ogni BombRunner inizializzato nel
costruttore e li fa partire in parallelo. Prima di terminare l’esecuzione applica il metodo join per assicurare che l’elaborazione abbia avuto
termine.
• getSolverResult: produce l’array di stringhe in cui sono memorizzati tutti
gli assetti risolventi il crittogramma relativamente all’i-esima Bomba.
• fact(statico): restituisce il fattoriale di un numero passato come argomento.
• disposizioni(statico): genera l’i-esima k-permutazione (disposizione n,k
con n pari alla dimensione di base) del vettore di array base.
• getSequence: restituisce il ciclo relativo alla prima BombRunner (equivalente a tutte le altre) secondo la semantica già descritta.
5.2.9
Classe AlanTuringBombSimulator
Interfaccia grafica in swing che realizza la simulazione della crittoanalisi dei
crittogrammi enigma inseriti.
L’interfaccia grafica si compone di:
• 2 Aree di testo(Crib in chiaro, Testo cifrato): per inserire il crib e il testo
cifrato che dovrebbe contenerlo.
• 1 Pulsante (Trova): che istanzia l’oggetto AlanTuringBombs con il crib e
il testo cifrato indicati nelle due aree di testo.
• 1 Casella Combinata (Scambiatori): rappresenta ciascuna delle possibili disposizioni che assumono gli scambiatori (essendo caricate alla stessa
maniera della Bomb è sufficiente utilizzarne l’indice relativo per sapere a
quale disposizione si sta facendo riferimento).
• 1 Campo di Testo (Assetti Validi): recherà la concatenazione individuata
dal programma rispetto al crib in chiaro e al testo cifrato inseriti.
• 1 Lista: indicherà ciascuno degli assetti risolventi il crittogramma.
5 La “Bomba” di Turing: versione Informatica
35
Il sorgente è abbastanza chiaro nelle sue funzioni (anche perché la semantica
di ciascun componente è già stata descritta). Tuttavia si ritiene necessario
chiarire ciò che è stato fatto per la gestione della pressione del pulsante Trova e
il cambiamento del valore memorizzato nella casella combinata Scambiatori.
• Trova: normalizza il contenuto delle due aree di testo secondo le regole
specificate in Enigma per il testo chiaro e quello cifrato, dopodiché istanzia
il campo privato theBomb di tipo AlanTuringBombs secondo il contenuto
aggiornato delle due aree di testo. Nel caso venga generata un eccezione di tipo BadCribException (perché il contenuto delle aree è assente o
perché il crib e il testo cifrato inseriti non producono concatenazioni) viene visualizzata una finestra di dialogo scomparsa la quale viene svuotato
il contenuto del componente lista. In caso ciò non si verifichi, ovvero in
caso ci sia una concatenazione, vengono lanciati i thread di theBomb e
infine caricati nella lista i risultati relativi al valore corrente della casella
combinata.
• Scambiatori: se si è istanziata la variabile oggetto theBomb, la lista viene
caricata con l’elenco dei risultati prodotti per il valore relativo alla nuova
disposizione selezionata nella casella combinata.
Riferimenti bibliografici
[1] Codici & Segreti “La storia affascinante dei messaggi cifrati dall’antico
Egitto ad Internet” - Simon Singh - Biblioteca Universale Rizzoli - 2005
[2] Enigma Machine - http://en.wikipedia.org/wiki/Enigma_machine
[3] CryptoAnalysis of the Enigma - http://en.wikipedia.org/ wiki/Cryptanalysis_of_the_Enigma
[Nota 1] Prodotti software usati per realizzare i programmi: “NetBeans 6.5”
[Nota 2] Prodotti software usati per realizzare la presente documentazione:
“Lyx version 1.6.2 Copyright 1995 by Matthias Ettrich”
[Nota 3] I testi descrittivi relativi al funzionamento di Enigma sono stati
liberamente tratti e riadattati dal libro Codici & Segreti
[Nota 4] Le immagini della presente documentazione sono stati digitalizzati dal
libro Codici & Segreti e tratti da en.wikipedia.org
[Nota 5] Il codice sorgente del progetto in esame è liberamente consultabile
all’indirizzo “http://code.google.com/p/iiwwcryptography/”
Fly UP