21
IL CRIVELLO QUADRATICO Dal metodo di Fermat, al crivello quadratico e alcune sue varianti MAGGIO 2018 FEDERICO MAZZONE Università degli Studi di Trento

Il Crivello Quadratico - me.unitn.it Alessandra/crivello... · Per quanto riguarda la complessità computazionale per gli algoritmi di fattorizzazione, viene misurata sul numero di

  • Upload
    hamien

  • View
    214

  • Download
    0

Embed Size (px)

Citation preview

IL CRIVELLO QUADRATICO Dal metodo di Fermat, al crivello quadratico e alcune sue varianti

MAGGIO 2018 FEDERICO MAZZONE

Università degli Studi di Trento

Sommario 1. Introduzione agli algoritmi di fattorizzazione ............................................................................................ - 1 -

1.1 Perché studiare gli algoritmi di fattorizzazione esponenziali? ............................................................ - 1 -

2. Metodo di Fermat ...................................................................................................................................... - 2 -

2.1 Strategia dei due quadrati ................................................................................................................... - 2 -

2.2 Numero massimo di iterazioni ............................................................................................................ - 3 -

2.3 Confronto con la Trial Division ............................................................................................................ - 3 -

2.4 Algoritmo per verificare se un numero è un quadrato ....................................................................... - 4 -

2.5 Trucchi per velocizzare l’algoritmo ...................................................................................................... - 4 -

2.6 Implementazione alternativa .............................................................................................................. - 5 -

2.7 Codice in C++ e output di esempio ...................................................................................................... - 5 -

3. Il crivello quadratico .................................................................................................................................. - 6 -

3.1 Strategia di base .................................................................................................................................. - 6 -

3.2 Struttura dell’algoritmo ....................................................................................................................... - 7 -

3.3 Numeri 𝐵-smooth e come trovarli ...................................................................................................... - 8 -

3.4 Algebra lineare .................................................................................................................................. - 10 -

3.5 Complessità probabilistica del crivello quadratico ............................................................................ - 11 -

3.6 Pseudocodice riassuntivo .................................................................................................................. - 12 -

4. Varianti del crivello quadratico ............................................................................................................... - 13 -

4.1 Large Prime Variation ........................................................................................................................ - 13 -

4.2 Multiple Polynomial Quadratic Sieve (MPQS) ................................................................................... - 14 -

5. Appendice ................................................................................................................................................ - 15 -

5.1 Algoritmo per calcolare il simbolo di Legendre-Jacobi ...................................................................... - 15 -

5.2 Algoritmo di Shanks-Tonelli ............................................................................................................... - 16 -

5.3 Lemma di Hensel ............................................................................................................................... - 18 -

6. Bibliografia ............................................................................................................................................... - 18 -

- 1 -

1. Introduzione agli algoritmi di fattorizzazione Lo scopo di un algoritmo di fattorizzazione è di trovare un divisore non banale di un intero positivo 𝑛:

Se tale divisore non viene trovato, allora 𝑛 è primo e abbiamo finito.

Altrimenti sia 𝑎 tale divisore, calcoliamo 𝑏 ≔ 𝑛 𝑎⁄ e applichiamo ricorsivamente l’algoritmo ad 𝑎 e

𝑏 per fattorizzare completamente 𝑛.

Notiamo subito che possiamo assumere 𝑛 dispari, altrimenti 𝑎 = 2 è già un suo divisore e abbiamo vinto.

Per quanto riguarda la complessità computazionale per gli algoritmi di fattorizzazione, viene misurata sul

numero di cifre di 𝑛, ossia su log 𝑛. Distinguiamo due principali categorie di algoritmi di fattorizzazione in

base alla loro complessità:

Esponenziali: forza bruta, metodo di Fermat, metodo di Lehman, metodo di Pollard rho…

Sub-esponenziali: crivello quadratico, crivello dei campi numerici, metodo delle curve ellittiche…

1.1 Perché studiare gli algoritmi di fattorizzazione esponenziali? Gli algoritmi di fattorizzazione esponenziali vengono studiati per diversi motivi:

1. Spesso risultano buoni per input piccoli e dunque possono essere utilizzati un sottoprocessi ausiliari

di algoritmi sub-esponenziali.

2. In qualche caso sono gli “antenati” diretti di algoritmi sub-esponenziali, dunque dal loro studio

potrebbe nascere l’ispirazione per qualche nuovo algoritmo sub-esponenziale.

3. Hanno il vantaggio di aver “subito” un’analisi rigorosa e deterministica, mentre la maggior parte

degli algoritmi sub-esponenziali sono analizzabili solo in maniera euristica.

Qui vedremo come la strategia dei due quadrati del metodo di Fermat venga migliorata e riapplicata per il

crivello quadratico (la cui strategia verrà migliorata ulteriormente nel crivello dei campi numerici).

- 2 -

2. Metodo di Fermat

2.1 Strategia dei due quadrati

Se riusciamo a scrivere un numero 𝑛 come differenza di due quadrati, diciamo

𝑛 = 𝑎2 − 𝑏2

per certi 𝑎, 𝑏 interi positivi, allora avremo una fattorizzazione di 𝑛 data da

𝑛 = (𝑎 + 𝑏)(𝑎 − 𝑏)

che risulta non banale nel caso in cui 𝑎 − 𝑏 > 1.

Viceversa, supponiamo che un numero dispari 𝑛 ammetta una fattorizzazione

𝑛 = 𝑢𝑣

per certi 𝑢, 𝑣 interi positivi dispari (visto che 𝑛 è dispari), allora ponendo

𝑎 =1

2(𝑢 + 𝑣) 𝑏 =

1

2|𝑢 − 𝑣|

(si noti che sono entrambi positivi; inoltre sono interi in quanto somma e differenza di dispari è pari) si ha

𝑎2 − 𝑏2 =1

4(𝑢2 + 2𝑢𝑣 + 𝑣2 − 𝑢2 + 2𝑢𝑣 − 𝑣2) = 𝑢𝑣 = 𝑛.

Abbiamo quindi provato il seguente:

Lemma. Sia 𝑛 > 1 un intero dispari, allora i seguenti problemi sono equivalenti:

Trovare una fattorizzazione non banale di 𝑛.

Scrivere 𝑛 come differenza di due quadrati 𝑎2 − 𝑏2 tali che 𝑎 − 𝑏 > 1.

Osservazione. Sia (𝑎, 𝑏) una coppia di interi tale che 𝑛 = 𝑎2 − 𝑏2, allora 𝑎2 ≥ 𝑛 e dunque 𝑎 ≥ ⌊√𝑛⌋.

Possiamo finalmente esporre la strategia alla base del metodo di Fermat:

1. Sia 𝑎 ≔ ⌊√𝑛⌋.

2. Se 𝑎2 = 𝑛 concludiamo, altrimenti poniamo 𝑎 ≔ 𝑎 + 1 e procediamo.

3. Andiamo a verificare se 𝑎2 − 𝑛 è un quadrato.

Se lo è, diciamo 𝑏2, scriviamo 𝑛 = 𝑎2 − 𝑏2 e abbiamo vinto.

Se non lo è, incrementiamo 𝑎 di 1 e torniamo al punto (3).

- 3 -

2.2 Numero massimo di iterazioni Notiamo cosa succede per 𝑛 = 3𝑝 con 𝑝 primo. Per tale caso si vede facilmente che la fattorizzazione viene

raggiunta per

𝑎 = (𝑛 + 9) 6⁄ 𝑏 = (𝑛 − 9) 6⁄ .

Mostriamo ora che quello appeno visto è il peggior caso che possa presentarsi.

Osservazione. Se 𝑛 è un numero composto dispari, allora questa procedura restituisce una fattorizzazione

non banale al più raggiungendo 𝑎 = ⌊(𝑛 + 9) 6⁄ ⌋. Difatti, se 𝑛 = 𝑎2 − 𝑏2 con 𝑎 > (𝑛 + 9) 6⁄ , allora

𝑏 = √𝑎2 − 𝑛 > √(𝑛 + 9

6)2

− 𝑛 = √𝑛2 − 18𝑛 + 81

36=𝑛 − 9

6

da cui

𝑎 + 𝑏 >𝑛 + 9

6+𝑛 − 9

6=𝑛

3 ⟹ 𝑎 − 𝑏 =

𝑛

𝑎 + 𝑏< 𝑛

3

𝑛= 3.

Essendo 𝑛 dispari per ipotesi, ciò ci condurrebbe solo ad una fattorizzazione banale di 𝑛.

2.3 Confronto con la Trial Division Si noti come il metodo di Fermat sia ottimo nel caso in cui 𝑛 sia prodotto di due numeri molto vicini alla sua

radice, mentre sia pessimo nel caso in cui 𝑛 sia prodotto di un primo per altri fattori “piccoli”. Dunque è

forse possibile combinare tale algoritmo con quello della divisione per tentativi: i due presentano infatti

casi ottimi e casi pessimi antipodali.

Anzitutto però dobbiamo fare alcune considerazioni essenziali:

All’inizio del ciclo si ha che 𝑎 = ⌊√𝑛⌋ + 1, dunque 𝑎 + 𝑏 > √𝑛 e dunque 𝑎 − 𝑏 < √𝑛.

Durante il ciclo: 𝑎 cresce, dunque anche 𝑏2 = 𝑎2 − 𝑛 cresce, dunque anche 𝑏 cresce, dunque 𝑎 + 𝑏

cresce e quindi 𝑎 − 𝑏 deve decrescere.

Dunque questo algoritmo, se ha successo, trova la coppia (𝑎, 𝑏) minima per cui 𝑛 si fattorizza.

Di conseguenza 𝑎 + 𝑏 è il più piccolo fattore ≥ √𝑛 e 𝑎 − 𝑏 è il più grande fattore ≤ √𝑛.

Quindi se ad un certo punto dell’algoritmo esso non ha terminato, vuol dire che non ci sono fattori di 𝑛 tra

𝑎 − 𝑏 e √𝑛. Perciò possiamo implementare un algoritmo combinato con la divisione per tentativi nel

seguente modo:

1. Si applica il metodo di Fermat con 𝑎 che va da ⌊√𝑛⌋ ad un certo 𝑐 > √𝑛

(quindi 𝑎 − 𝑏 arriva fino a 𝑐 − √𝑐2 − 𝑛).

2. Poi si applica la Trial Division tentando divisori fino a 𝑐 − √𝑐2 − 𝑛).

In totale si fanno dunque 𝑘1 ∙ (𝑐 − √𝑛) + 𝑘2 ∙ (𝑐 − √𝑐2 − 𝑛) operazioni, ove 𝑘1 e 𝑘2 indicano il numero di

operazioni effettuate rispettivamente in un’iterazione del metodo di Fermat e in una della Trial Division.

È possibile ricavare 𝑐 a priori per ottimizzare la velocità dell’algoritmo combinato semplicemente

minimizzando la funzione di costo. Per esempio se 𝑘1 = 𝑘2 si ha che il valore ottimale è pari a 𝑐 = √4𝑛 3⁄ .

Si noti tuttavia che tale esempio è poco informativo, visto che evidentemente il costo per un’iterazione di

Fermat è decisamente maggiore di quello di una semplice divisione (e confronto).

- 4 -

2.4 Algoritmo per verificare se un numero è un quadrato Per verificare se 𝑎2 − 𝑛 è un quadrato, utilizzeremo il seguente algoritmo basato sul metodo di Newton:

tale algoritmo prende in input un intero positivo 𝑁 e ne calcola ⌊√𝑁⌋ per verificare se 𝑁 è un quadrato.

Prima però definiamo la funzione 𝐵:ℕ → ℕ che associa ad ogni 𝑛 ∈ ℕ ∖ {0} il numero di bits della sua

rappresentazione binaria e 𝐵(0) = 0.

1. Sia 𝑥 = 2⌈𝐵(𝑁) 2⁄ ⌉.

2. Sia 𝑦 = ⌊(𝑥 + ⌊𝑁 𝑥⁄ ⌋) 2⁄ ⌋.

Se 𝑦 < 𝑥, poni 𝑥 = 𝑦 e ritorna al punto (2).

Altrimenti si ha che 𝑥 = ⌊√𝑁⌋. Dunque calcola 𝑥2 e restituisci 𝑥2 == 𝑁.

Si può dimostrare che questo algoritmo ha costo 𝑂(ln ln𝑁).

2.5 Trucchi per velocizzare l’algoritmo È possibile in alcuni casi velocizzare l’algoritmo.

Ricordiamo che

𝑥2 ≡4 {0, 𝑥 ∈ {0, 2}

1, 𝑥 ∈ {1, 3}.

Se 𝑛 ≡ 1 (𝑚𝑜𝑑 4), si ha che 𝑛 + 𝑏2 può essere solo 1 o 2 (𝑚𝑜𝑑 4). Ma 𝑛 + 𝑏2 = 𝑎2 e dunque 𝑎2 ≡

1 (𝑚𝑜𝑑 4) e quindi 𝑎 ≡ 1 o 3 (𝑚𝑜𝑑 4). E quindi basta cercare per 𝑎 dispari.

Se 𝑛 ≡ 3 (𝑚𝑜𝑑 4), si ha che 𝑛 + 𝑏2 può essere solo 0 o 3 (𝑚𝑜𝑑 4). Ma 𝑛 + 𝑏2 = 𝑎2 e dunque 𝑎2 ≡

0 (𝑚𝑜𝑑 4) e quindi 𝑎 ≡ 0 o 2 (𝑚𝑜𝑑 4). E quindi basta cercare per 𝑎 pari.

Ricordiamo che

𝑥2 ≡3 {0, 𝑥 ∈ {0}

1, 𝑥 ∈ {1, 2}.

Se 𝑛 ≡ 2 (𝑚𝑜𝑑 3), si ha che 𝑛 + 𝑏2 può essere solo 0 o 2 (𝑚𝑜𝑑 3). Ma 𝑛 + 𝑏2 = 𝑎2 e dunque 𝑎2 ≡

0 (𝑚𝑜𝑑 3) e quindi 𝑎 ≡ 0 (𝑚𝑜𝑑 3). E quindi basta cercare per 𝑎 multiplo di 3.

Similmente si potrebbe procedere per gli altri casi o considerando moduli più grandi. Bisogna notare

tuttavia che controlli di questo tipo aumentano l’efficienza dell’algoritmo solo di costanti moltiplicative, e

dopo una certa soglia, il vantaggio dato dal controllare meno casi si perde nel vaglio dei casi stessi.

- 5 -

2.6 Implementazione alternativa Un altro modo per implementare il metodo di Fermat è il seguente. Consideriamo la quantità

𝑆 ≔ 𝑎2 − 𝑏2 − 𝑛

e cerchiamo dei valori di 𝑎, 𝑏 per cui si annulli.

1. Inizializza 𝑎 = ⌊√𝑛⌋ e 𝑏 = 0.

2. Se 𝑆 = 0 abbiamo vinto.

3. Se 𝑆 > 0 incrementiamo 𝑏 di 1.

4. Se 𝑆 < 0 incrementiamo 𝑎 di 1.

5. Ritorna al punto (2).

Per rendere più efficiente questo algoritmo, al posto di ricalcolare 𝑆 ogni volta, è sufficiente notare che

𝑎2 − (𝑏 + 1)2 − 𝑛 = 𝑎2 − 𝑏2 − 2𝑏 − 1 − 𝑛 = 𝑆 − 2𝑏 − 1

(𝑎 + 1)2 − 𝑏2 − 𝑛 = 𝑎2 + 2𝑎 + 1 − 𝑏2 − 𝑛 = 𝑆 + 2𝑎 + 1.

Si noti che questa implementazione è più veloce a livello della singola iterazione, in quanto deve compiere

solo operazioni elementari di somma, prodotto e confronto. Tuttavia è difficile stimarne la complessità a

livello di ciclo, essendo complicato valutare quante iterazioni sono necessarie per il caso medio.

2.7 Codice in C++ e output di esempio#include <iostream> using namespace std; int power(int base, int exp){ int result = 1; for(int i = 0; i < exp; i++){ result *= base; } return result; } int B(int N){ int result; for(result = 0; N > 0; N >>= 1) result++; return result; } int newton_floor_sqrt(int N){ int x = power(2,B(N)/2+1); int y = (x + N/x)/2; while(y < x){ x = y; y = (x + N/x)/2; } return x; }

pair<int,int> fermat_method(long long int N){ int a = newton_floor_sqrt(N); if(a*a == N) return make_pair(a,a); for(a = a+1; a <= (N+9)/6; a++){ int b = newton_floor_sqrt(a*a-N); if(b*b == a*a-N) return make_pair(a-b,a+b); } return make_pair(1,N); } int main(){ long long int N = 37463527; pair<int,int> result = fermat_method(N); cout<<result.first<<" "<<result.second; return 0; }

- 6 -

3. Il crivello quadratico

3.1 Strategia di base Come premesso, il crivello quadratico si ispira al metodo di Fermat, andando sempre ad utilizzare la

strategia dei due quadrati, ma questa volta modulo 𝑛.

Lemma. Sia 𝑛 un numero composto dispari. Se esistono interi 𝑎, 𝑏 ∈ ℕ tali per cui

𝑎2 ≡ 𝑏2 (𝑚𝑜𝑑 𝑛)

e 𝑎 ≢ ±𝑏 (𝑚𝑜𝑑 𝑛), allora gcd(𝑛, 𝑎 + 𝑏) e gcd(𝑛, 𝑎 − 𝑏) sono fattori non banali di 𝑛.

Dimostrazione. Notiamo che

𝑎2 ≡ 𝑏2 (𝑚𝑜𝑑 𝑛) ⟺ 𝑛 ∣ (𝑎 + 𝑏)(𝑎 − 𝑏).

Se 𝑝 è un divisore primo di 𝑛, allora si possono presentare due casi:

𝑝 divide (𝑎 + 𝑏) e dunque gcd(𝑛, 𝑎 + 𝑏) > 1, oppure

𝑝 divide (𝑎 − 𝑏) e dunque gcd(𝑛, 𝑎 − 𝑏) > 1.

La condizione 𝑎 ≢ ±𝑏 (𝑚𝑜𝑑 𝑛) ci garantisce la non trivialità dei fattori.

Osservazione. Se i fattori gcd(𝑛, 𝑎 − 𝑏) e gcd(𝑛, 𝑎 + 𝑏) sono entrambi non banali, allora si ha che

𝑛 = gcd(𝑛, 𝑎 − 𝑏) ∙ gcd(𝑛, 𝑎 + 𝑏).

Durante il crivello, andremo dunque a cercare coppie di interi (𝑎, 𝑏) che soddisfino 𝑎2 ≡ 𝑏2 (𝑚𝑜𝑑 𝑛), non

preoccupandoci più di tanto della condizione 𝑎 ≢ ±𝑏 (𝑚𝑜𝑑 𝑛): nel caso in cui tale condizione non venisse

rispettata ci basterà provare altre coppie.

Osservazione. Notiamo tali coppie (𝑎, 𝑏) esistono sempre, e dunque cercarle ha senso. Infatti se 𝑛 è un

numero dispari con esattamente 𝑘 fattori primi distinti, allora ci sono esattamente 2𝑘 radici quadrate di 1

modulo 𝑛. Ossia esistono 2𝑘 interi 𝑥 tali che 𝑥2 ≡ 1 ≡ 12 (𝑚𝑜𝑑 𝑛), ossia 2𝑘 coppie (𝑥, 1).

Due di queste radici sono ovviamente ±1 e vanno dunque a costituire le coppie banali (1, 1) e (−1, 1).

Tutte le altre sono interessanti in quanto possono essere utilizzate per fattorizzare 𝑛.

Dimostrazione. Il caso 𝑘 = 1 è facile, mentre il caso generale segue dal Teorema Cinese del resto.

- 7 -

3.2 Struttura dell’algoritmo Iniziamo con un esempio per vedere come lavora questo crivello e in cosa differisce dal metodo di Fermat.

Esempio 1. Sia 𝑛 = 1649. Come con il metodo di Fermat, iniziamo con numeri appena sopra √𝑁 ≃ 40.6

412 = 1681 ≡ 32 (𝑚𝑜𝑑 1649)

422 = 1764 ≡ 115 (𝑚𝑜𝑑 1649)

432 = 1849 ≡ 200 (𝑚𝑜𝑑 1649).

Con il metodo di Fermat avremmo continuato fino a 572 ≡ 1600 (𝑚𝑜𝑑 1649), tuttavia questa volta

procederemo in modo differente. Notiamo che nessuno tra 32, 115 e 200 è un quadrato modulo 𝑛. Ma

moltiplicando fra loro la prima e la terza relazione otteniamo

1142 ≡ (𝟒𝟏 ∙ 𝟒𝟑)𝟐 ≡ 𝟑𝟐 ∙ 𝟐𝟎𝟎 ≡ 802 (𝑚𝑜𝑑 1649)

Poniamo 𝑎 ≔ 114 e 𝑏 ≔ 80 e notiamo che 𝑎 ≢ ±𝑏 (𝑚𝑜𝑑 1649). Passiamo quindi a calcolare

gcd(𝑛, 𝑎 − 𝑏) = gcd(1649, 34) = 17

gcd(𝑛, 𝑎 + 𝑏) = gcd(1649, 194) = 97.

e otteniamo la fattorizzazione 1649 = 17 ∙ 97.

L’idea alla base del crivello quadratico consiste infatti nel trovare un insieme di congruenze della forma

𝑥𝑖2 ≡ 𝑦𝑖 (𝑚𝑜𝑑 𝑛)

ove ∏𝑦𝑖 è un quadrato, diciamo 𝑏2. Se poniamo 𝑎 ≔ ∏𝑥𝑖, si ha che 𝑎2 ≡ 𝑏2 (𝑚𝑜𝑑 𝑛).

Come già detto, il requisito aggiuntivo per cui 𝑎 ≢ ±𝑏 (𝑚𝑜𝑑 𝑛) è ignorato. Se questa condizione viene

soddisfatta, siamo felici, altrimenti cerchiamo altre congruenze.

Vogliamo dunque produrre in modo sistematico relazioni del tipo 𝑥𝑖2 ≡ 𝑦𝑖 (𝑚𝑜𝑑 𝑁) per poi trovare un loro

sottoinsieme non vuoto con prodotto un quadrato. Notiamo che se nella decomposizione in fattori primi di

un 𝑦𝑖 appare un primo con potenza dispari, dovremo trovare anche un 𝑦𝑗 in cui appaia lo stesso primo con

potenza nuovamente dispari. Ciò risulta tanto più difficile quanto questo primo è “grande”. Dunque

setacceremo il nostro insieme di congruenze e terremo solo quelle in cui 𝑦𝑖 presenta fattori primi “piccoli”.

Abbiamo due problemi da affrontare:

1. Come individuare tali numeri con fattori primi piccoli? Quanti ce ne servono?

2. Come trovarne un sottoinsieme il cui prodotto sia un quadrato?

- 8 -

3.3 Numeri 𝐵-smooth e come trovarli Definizione. Un intero 𝑥 si dice 𝐵-smooth se tutti i primi 𝑝 della sua fattorizzazione sono tali che 𝑝 ≤ 𝐵.

I numeri che andremo a setacciare sono

𝑎(𝑗) ≔ (𝑋0 + 𝑗)2 − 𝑛 𝑋0 ≔ ⌊√𝑛⌋ 𝑗 ∈ {−𝑀,… ,𝑀}

ove 𝑀 ≪ 𝑛 è sufficientemente piccolo da ritenere −𝑛 ≪ 𝑎(𝑗) ≪ 𝑛.

Notiamo che gli 𝑎(𝑗) non sono consecutivi, ma sparsi nell’intervallo [(𝑋0 −𝑀)2 − 𝑛, (𝑋0 +𝑀)

2 − 𝑛].

Scegliamo 𝑋0 = ⌊√𝑛⌋ in modo da massimizzare la probabilità che 𝑎(𝑗) sia 𝐵-smooth. Infatti, se 𝑋0 = ⌊√𝑛⌋,

gli 𝑎(𝑗) sono centrati in 𝑋02 − 𝑛 e dunque più piccoli possibile in modulo.

Fissiamo dunque 𝐵 ∈ ℕ uno smoothness bound e una factor base

𝐹 ≔ { 𝑝1, … , 𝑝𝛼 ∶ 𝑝𝑖 ≤ 𝐵, (𝑛

𝑝𝑖) = 1}.

Abbiamo considerato solo i primi 𝑝 per i quali 𝑛 è un quadrato modulo 𝑝. Infatti se 𝑝 ∣ 𝑎(𝑗), allora

(𝑋0 + 𝑗)2 ≡ 𝑛 (𝑚𝑜𝑑 𝑝) e dunque 𝑛 è un quadrato modulo 𝑝. Si veda il paragrafo 1 dell’appendice per un

algoritmo che calcoli il simbolo di Legendre.

D’ora in avanti, con abuso di linguaggio, chiameremo 𝐵-smooth gli interi che si decompongono nei primi

della factor base.

Per capire quali 𝑎(𝑗) siano 𝐵-smooth utilizzeremo un crivello. Il nostro scopo è il seguente:

Se un elemento 𝑎(𝑗) è divisibile per 𝑝𝑖, deve essere sostituito con 𝑎(𝑗) 𝑝𝑖𝑘⁄ ove 𝑝𝑖

𝑘 ∣∣ 𝑎(𝑗).

Lo si fa per ogni 𝑗 e per ogni 𝑖. Gli elementi che alla fine della procedura sono diventati 1 sono quelli che

originariamente erano 𝐵-smooth. L’idea chiave del crivello sta nel modo in cui si individuano gli elementi

che sono divisibili per un certo 𝑝𝑖𝑘 una volta che se ne è localizzato uno.

Per ogni 𝑝 ∈ 𝐹 con 𝑝 ≠ 2 ripetiamo la seguente procedura:

1. Capire per quali 𝑗 si ha che 𝑝 ∣ 𝑎(𝑗) è equivalente a trovare tutte le soluzioni dell’equazione 𝑥2 ≡

𝑛 (𝑚𝑜𝑑 𝑝), ove abbiamo posto 𝑥 = 𝑋0 + 𝑗. Se 𝑛 ≢ 0 (𝑚𝑜𝑑 𝑝) allora, visto che 𝑝 ≠ 2, tale

equazione ha due soluzioni in ℤ𝑝, diciamo 𝑟 e – 𝑟, e sono facilmente ottenibili mediante l’algoritmo

di Shanks-Tonelli per il calcolo delle radici modulo un primo (vedi paragrafo 2 dell’appendice).

Dunque ponendoci su ℤ, le soluzioni dell’equazione sono 𝑟 + 𝑝ℤ e −𝑟 + 𝑝ℤ, infatti:

(±𝑟 + 𝑝𝑧)2 = 𝑟2 ± 2𝑟𝑝𝑧 + 𝑝2𝑧2 ≡ 𝑟2 (𝑚𝑜𝑑 𝑝) Procediamo quindi a dividere per 𝑝 tutti gli 𝑎(𝑟 − 𝑋0 + 𝑝ℤ) e tutti gli 𝑎(−𝑟 − 𝑋0 + 𝑝ℤ).

2. Ora procediamo con 𝑝𝑚 per ogni 𝑚 > 1. Abbiamo le due radici ±𝑟 modulo 𝑝 del polinomio

𝑓(𝑥) ≔ 𝑥2 − 𝑛, inoltre 𝑓′(±𝑟) = ±2𝑟 ≢ 0 (𝑚𝑜𝑑 𝑝) (se no si avrebbe che 𝑝 ∣ 𝑟2 e 𝑝 ∣ 𝑟2 − 𝑛, da

cui 𝑝 ∣ 𝑛). Dunque per il Lemma di Hensel (vedi paragrafo 3 dell’appendice) si ha che esistono

uniche due radici ±𝑠 modulo 𝑝𝑚 e sono facilmente calcolabili con l’Hensel lifting.

Dunque ponendoci su ℤ, le soluzioni dell’equazione sono 𝑠 + 𝑝𝑚ℤ e −𝑠 + 𝑝𝑚ℤ, infatti:

(±𝑠 + 𝑝𝑚𝑧)2 = 𝑠2 ± 2𝑠𝑝𝑚𝑧 + 𝑝2𝑚𝑧2 ≡ 𝑠2 (𝑚𝑜𝑑 𝑝𝑚) Procediamo quindi a dividere per 𝑝 tutti gli 𝑎(𝑠 − 𝑋0 + 𝑝

𝑚ℤ) e tutti gli 𝑎(−𝑠 − 𝑋0 + 𝑝𝑚ℤ).

- 9 -

3. Per 𝑝𝑚 > 2𝑀 ci sarà al più un elemento divisibile per 𝑝𝑚. Quindi non ha più senso setacciare e

basterà continuare a dividere tale elemento per 𝑝.

Trattiamo a parte il caso 𝑝 = 2:

1. Un intero 𝑛 dispari è un quadrato modulo 2 ed è il quadrato di un numero dispari. In particolare, un

intero della forma (𝑋0 + 𝑗)2 − 𝑛 è divisibile per 2 se e solo se (𝑋0 + 𝑗) è dispari, ossia

{𝑗 = 1 + 2ℤ, 𝑋0 ≡ 0 (𝑚𝑜𝑑 2)

𝑗 = 2ℤ, 𝑋0 ≡ 1 (𝑚𝑜𝑑 2).

Dunque verifichiamo la parità di 𝑋0, dopodiché dimezziamo tutti gli 𝑎(𝑗) con 𝑗 di parità opposta.

2. Sia 𝑛 un intero dispari tale che 2 ∣ (𝑋0 + 𝑗)2 − 𝑛, allora

{

2 ∣∣ (𝑋0 + 𝑗)2 − 𝑛, 𝑛 ≡ 3, 7 (𝑚𝑜𝑑 8)

22 ∣∣ (𝑋0 + 𝑗)2 − 𝑛, 𝑛 ≡ 5 (𝑚𝑜𝑑 8)

23 ∣ (𝑋0 + 𝑗)2 − 𝑛, 𝑛 ≡ 1 (𝑚𝑜𝑑 8)

.

Dimostrazione. Per ipotesi e per il punto 1 sappiamo che 𝑋0 + 𝑗 è dispari, ossia che 𝑋0 + 𝑗 = 2𝑚 +

1 per un certo 𝑚 intero. Allora:

Se 𝑛 ≡ 3 (𝑚𝑜𝑑 8), allora

(𝑋0 + 𝑗)2 − 𝑛 = (2𝑚 + 1)2 − (3 + 8𝑡) = 4𝑚(𝑚 + 1) − 2 − 8𝑡 ≡ 2 (𝑚𝑜𝑑 4)

Se 𝑛 ≡ 7 (𝑚𝑜𝑑 8), allora

(𝑋0 + 𝑗)2 − 𝑛 = (2𝑚 + 1)2 − (7 + 8𝑡) = 4𝑚(𝑚 + 1) − 6 − 8𝑡 ≡ 2 (𝑚𝑜𝑑 4)

Se 𝑛 ≡ 5 (𝑚𝑜𝑑 8), allora

(𝑋0 + 𝑗)2 − 𝑛 = (2𝑚 + 1)2 − (5 + 8𝑡) = 4𝑚(𝑚 + 1) − 4 − 8𝑡 ≡ 4 (𝑚𝑜𝑑 8)

Se 𝑛 ≡ 1 (𝑚𝑜𝑑 8), allora

(𝑋0 + 𝑗)2 − 𝑛 = (2𝑚 + 1)2 − (1 + 8𝑡) = 4𝑚(𝑚 + 1) − 8𝑡 ≡ 0 (𝑚𝑜𝑑 8)

Ma come scegliere il limite di smoothness 𝐵?

Se scegliamo 𝐵 piccolo, abbiamo il vantaggio che non abbiamo bisogno di molti residui 𝐵-smooth per

trovare un sottoprodotto che sia un quadrato. Ma se 𝐵 è troppo piccolo, la proprietà di essere 𝐵-smooth

diventerebbe così rara che potremmo non trovare alcun numero 𝐵-smooth. Dobbiamo dunque bilanciare le

due forze che operano sul limite 𝐵: il limite deve essere abbastanza piccolo da non necessitare troppi interi

𝐵-smooth per vincere, ma deve essere grande abbastanza affinché ci siano abbastanza interi 𝐵-smooth.

Scopriremo come risolvere questo problema nel paragrafo sulla complessità.

- 10 -

3.4 Algebra lineare Siano 𝑠1, … , 𝑠𝑘 i numeri 𝐵-smooth ottenuti dal setaccio.

{

𝑥1

2 ≡ 𝑠1 ≡ 𝑝1𝑒1,1 ∙∙∙ 𝑝𝛼

𝑒1,𝛼

𝑥22 ≡ 𝑠2 ≡ 𝑝1

𝑒2,1 ∙∙∙ 𝑝𝛼𝑒2,𝛼

𝑥𝑘2 ≡ 𝑠𝑘 ≡ 𝑝1

𝑒𝑘,1 ∙∙∙ 𝑝𝛼𝑒𝑘,𝛼

.

Dobbiamo trovarne un sottoinsieme il cui prodotto sia un quadrato.

Ad ogni numero 𝐵-smooth 𝑠𝑖 = 𝑝1𝑒𝑖,1 ∙∙∙ 𝑝𝛼

𝑒𝑖,𝛼 associamo il vettore di esponenti 𝑣(𝑠𝑖) = (𝑒𝑖,1, … , 𝑒𝑖,𝛼).

Notiamo che

𝑣(𝑠𝑖𝑠𝑗) = (𝑒𝑖,1 + 𝑒𝑗,1, … , 𝑒𝑖,𝛼 + 𝑒𝑗,𝛼) = (𝑒𝑖,1, … , 𝑒𝑖,𝛼) + (𝑒𝑗,1, … , 𝑒𝑗,𝛼) = 𝑣(𝑠𝑖) + 𝑣(𝑠𝑗).

Notiamo inoltre che un numero 𝑠 è un quadrato se e solo se 𝑣(𝑠) ha tutte le coordinate pari.

Consideriamo dunque tutti i vettori di esponenti ridotti modulo 2, come elementi di ℤ2𝛼. Il campo scalare di

questo spazio vettoriale è ℤ2 che ha solo due elementi: 0 e 1. Quindi una combinazione lineare di vettori

differenti in questo spazio vettoriale non è altro che una sottosomma. Dunque la ricerca di un sottoinsieme

non vuoto di interi il cui prodotto sia un quadrato è ridotta alla ricerca di una dipendenza lineare in un

insieme di vettori.

Ci sono due grandi vantaggi nel vederla in questo modo. Primo, abbiamo immediatamente il teorema

dall’algebra lineare per il quale condizione sufficiente affinché un insieme di vettori siano linearmente

dipendenti è che ve ne siano più della dimensione dello spazio vettoriale in questione. Dunque abbiamo

una risposta: la creazione di un prodotto come quadrato richiede al più 𝛼 + 1 numeri positivi 𝐵-smooth.

Secondo, dall’algebra lineare otteniamo anche algoritmi efficienti come la riduzione delle matrici. Quindi il

problema di trovare una dipendenza lineare in un insieme di vettori si riduce alla riduzione per righe di una

matrice formata da questi vettori.

- 11 -

3.5 Complessità probabilistica del crivello quadratico Definizione. Siano 𝑥, 𝑦 interi positivi, allora definiamo

𝜓(𝑥, 𝑦) ≔ #{𝑎 ∈ {1,… , 𝑥} ∶ 𝑎 sia 𝑦-smooth}.

Teorema (Dickman). Possiamo stimare

𝜓(𝑥, 𝑥1 𝑢⁄ ) ∼ 𝜌(𝑢)𝑥 con log 𝜌(𝑢) ∼ −𝑢 log𝑢 ⟹ 𝜌(𝑢) ∼ 𝑢−𝑢.

Corollario. La probabilità che un 𝑎 ∈ {1,… , 𝑥} sia 𝑦-smooth è stimabile con

𝜓(𝑥, 𝑦)

𝑥∼ 𝑢−𝑢 con 𝑥1 𝑢⁄ = 𝑦 ⟹ 𝑢 =

log 𝑥

log 𝑦.

Scriviamo anzitutto 𝑀 = 𝑛𝜖 con 0 < 𝜖 ≪ 1. Per definizione gli 𝑥 ≔ 𝑋0 + 𝑗 sono tali che

√𝑛 − 𝑛𝜖 ≤ 𝑥 ≤ √𝑛 + 𝑛𝜖 ⟹ 𝑥2 − 𝑛 = 𝑂(𝑛2𝜖 + 2√𝑛𝑛𝜖) = 𝑂 (𝑛12+𝜖)

dunque la probabilità che un 𝑥2 − 𝑛 sia 𝐵-smooth è stimabile con

𝑢−𝑢 con 𝑢 =log 𝑛

12+𝜖

log𝐵∼

log 𝑛

2 log𝐵.

Nota che i numeri che stiamo setacciando potrebbero non avere la stessa probabilità di essere 𝐵-smooth di

un numero generico, tuttavia stiamo solo stimando euristicamente la probabilità, quindi non ne teniamo

più di tanto conto.

Ora, abbiamo una probabilità di 𝑢−𝑢 che un candidato risulti 𝐵-smooth, quindi per avere un 𝐵-smooth ci

serviranno approssimativamente 𝑢𝑢 candidati, e per averne 𝛼 + 1 ce ne serviranno (𝛼 + 1)𝑢𝑢. Per

verificare ogni candidato utilizziamo un crivello variante di quello di Eratostene, esso ha dunque un costo

ammortizzato (per singolo candidato) pari a log log𝐵. Il costo totale per la parte di crivello è quindi

𝑇(𝐵) = 𝑢𝑢(𝛼 + 1) log log𝐵 con 𝑢 =log 𝑛

2 log𝐵.

Sempre a livello euristico possiamo supporre che la factor-base abbia cardinalità pari a

𝛼 ∼ 𝜋(𝐵) ∼𝐵

log𝐵∼ 𝐵

dunque

log 𝑇(𝐵) ∼ 𝑆(𝐵) ≔ 𝑢 log𝑢 + log𝐵.

Possiamo dunque minimizzare 𝑇(𝐵) nel modo seguente

𝑑𝑆(𝐵)

𝑑𝐵=𝑑𝑢

𝑑𝐵(log 𝑢 + 1) +

1

𝐵= −

log𝑛

2𝐵 log2 𝐵(log log 𝑛 − log log𝐵 − log 2 + 1) +

1

𝐵.

- 12 -

Ponendo questo a 0, troviamo che log𝐵 è compreso tra 𝑐1√log𝑛 e 𝑐2√log𝑛 log log 𝑛. Quindi abbiamo

trovato che il 𝐵 ottimale e le altre quantità si comportano nel modo seguente:

log𝐵 ∼1

2√log𝑛 log log 𝑛 𝐵 ∼ 𝑒

12√log𝑛 log log𝑛

𝑢 ∼ √log𝑛 log log 𝑛⁄ 𝑆(𝐵) ∼ √log 𝑛 log log 𝑛.

Concludiamo che la durata dell’algoritmo con questa scelta di 𝐵 sia circa

𝑇(𝑁) ∼ 𝑒𝑆(𝐵) = 𝑒√log𝑛 log log𝑛 ∼ 𝐵2.

Abbreviamo quest’ultima funzione di 𝑛 come segue:

𝐿(𝑛) = 𝑒√log𝑛 log log𝑛.

L’argomento di cui sopra ignora la complessità della parte di algebra lineare, ma si può mostrare che

anch’essa è circa 𝐵2.

3.6 Pseudocodice riassuntivo Riassunto qualitativo del QS:

1. [Inizializzazione]

𝐵 = ⌈𝐿(𝑛)1 2⁄ ⌉

𝑝1 = 2

Trovare tramite crivello di Eratostene i primi dispari 𝑝 ≤ 𝐵.

Controllare quali di questi sono tali che (𝑝

𝑛) = 1 e identificarli con 𝑝2, … , 𝑝𝛼.

2. [Crivello]

Calcolare le radici 𝑎𝑖 di 𝑛 modulo 𝑝𝑖 per ogni 𝑖 (algoritmo di Shanks-Tonelli).

Siano 𝑥𝑖 ≔ ⌈√𝑛⌉ + 𝑖 per 𝑖 ∈ {−𝑀,… ,𝑀}.

Setacciare gli 𝑦𝑖 ≔ 𝑥𝑖2 − 𝑛 alla ricerca di valori 𝐵-smooth, memorizzandone la

fattorizzazione 𝑝1𝑒1 ∙∙∙ 𝑝𝛼

𝑒𝛼.

3. [Algebra lineare]

Per ogni numero che ha superato il setaccio, inserire (𝑒1, … , 𝑒𝛼) (𝑚𝑜𝑑 2) in una matrice.

Utilizzare un algoritmo di algebra lineare per trovare un sottoinsieme di righe dipendenti:

siano esse le righe relative a 𝑦1, … , 𝑦𝑘.

4. [Fattorizzazione]

𝑥 = 𝑥1 ∙∙∙ 𝑥𝑘 (𝑚𝑜𝑑 𝑛)

𝑦 = √𝑦1 ∙∙∙ 𝑦𝑘 (𝑚𝑜𝑑 𝑛)

return gcd(𝑥 − 𝑦, 𝑛)

- 13 -

4. Varianti del crivello quadratico

4.1 Large Prime Variation Questa variante del QS è un modo economico per ottenere qualche congruenza aggiuntiva senza dover

aumentare lo smoothness bound 𝐵. Consiste nell’andare a considerare anche quei numeri della forma

𝑝1𝑒1 ∙∙∙ 𝑝𝛼

𝑒𝛼𝑃

ove i 𝑝𝑖 sono i primi della factor-base, mentre 𝑃 è un primo non troppo grande, diciamo compreso in

(𝐵, 𝐵2]. Normalmente numeri come questo sarebbero scartati dal nostro setaccio, tuttavia, come vedremo,

ci torneranno utili. Nota che è ben diverso dal richiedere che tale numero sia 𝐵2-smooth.

Sono facili da individuare questi numeri in quanto se dopo il setaccio (ossia dopo aver diviso un numero per

tutti i primi della factor-base) rimane un numero 𝑃 e tale numero è tale che 1 < 𝑃 ≤ 𝐵2, allora si ha

necessariamente che è primo (se per assurdo fosse composto, avremmo trovato almeno un suo fattore

primo tra quelli della factor-base).

Come possiamo poi usare questi numeri nella parte di algebra lineare? Non possiamo aggiungere bits in più

per tenere conto di ogni possibile large prime, se no è come avere la stessa complessità di 𝐵2 come

smoothness bound, dunque li ordiniamo in base al large prime. Se un large prime 𝑃 appare solo una volta,

non possiamo farci molto e lo scartiamo. Se appare 𝑡 > 1 volte sotto forma di 𝑥𝑖 − 𝑛 = 𝑦𝑖𝑃 per 𝑖 ∈

{1,… , 𝑡}, allora ci basterebbe considerare le 𝑘 − 1 congruenze

(𝑥1𝑥𝑖)2 ≡ 𝑦1𝑦𝑖𝑃

2 (𝑚𝑜𝑑 𝑛) 𝑖 = 2,… , 𝑘.

Essendo il costo di riordinamento assai contenuto rispetto ai rimanenti, otteniamo in maniera pressoché

gratuita 𝑘 − 1 nuove congruenze per ogni large prime che troviamo.

Uno potrebbe chiedersi quanto sia probabile che un large prime appaia almeno due volte nella nostra lista.

Il paradosso dei compleanni da teoria della probabilità ci suggerisce che non sia così improbabile.

Empiricamente (ed è anche supportato da alcuni risultati teorici) si nota che più è grande il large prime,

meno probabile è trovargli almeno un match con un altro. Per questo si tende a stare più stretti nel range

per cui accettare il large prime, ponendolo, come suggerisce Pomerance, a (𝐵, 20𝐵] o magari (𝐵, 100𝐵].

È possibile anche farlo con due large primes. Ma ci sono varie nuove complicazioni. Se un intero in (1, 𝐵2]

ha tutti i fattori primi più grandi di 𝐵, allora deve essere primo. Cosa succede se un intero in (𝐵2, 𝐵3] non

ha fattori primi ≤ 𝐵? Allora o è primo o è prodotto di due primi superiori a 𝐵 (se per assurdo fosse

prodotto di tre o più fattori primi > 𝐵, allora tale intero sarebbe più grande di 𝐵3).

Dunque la double large prime variation concede di passare al filtro dei 𝐵-smooth quelli per cui la parte non

fattorizzata 𝑚 è al più 𝐵3. Se 𝑚 > 𝐵2 si utilizza un test di pseudoprimalità veloce, per esempio si controlla

se 2𝑚−1 ≡ 1 (𝑚𝑜𝑑 𝑚). Se 𝑚 soddisfa la congruenza, potrebbe essere un primo e dunque lo scartiamo, se

non la soddisfa è sicuramente composto e lo fattorizziamo con qualche algoritmo di fattorizzazione

esponenziale. La parte di algebra lineare consiste nell’individuare cicli che portino al match di tutti i large

primes: per esempio se abbiamo 𝑦1𝑃1, 𝑦2𝑃2, 𝑦3𝑃1𝑃2, allora 𝑦1𝑦2𝑦3𝑃12𝑃2

2 può essere utilizzato nella nostra

matrice. Ma possono esserci cicli molto più complicati. Ne hanno discusso Lenstra e Manasse per la

risoluzione dell’RSA129.

E tre large primes? Sono troppi, si preferisce utilizzare un 𝐵 più grande.

- 14 -

4.2 Multiple Polynomial Quadratic Sieve (MPQS) Come suggerisce il nome, il MPQS è una variante del QS in cui sono usati più polinomi al posto del solito

𝑓(𝑥) ≔ (⌊√𝑛⌋ + 𝑥)2− 𝑛

al fine di produrre i possibili candidati ad essere 𝐵-smooth per le nostre congruenze.

Per quale motivo usare più polinomi? Usando il solo polinomio 𝑓(𝑥) si ottengono valori che crescono

velocemente. Usando più polinomi, otteniamo più candidati, possiamo quindi considerare l’intervallo su cui

valutarli più piccolo e ciò rende più piccoli anche i valori stessi di questi polinomi valutati nei punti.

Tre vantaggi derivanti da avere un array di interi più piccoli:

1. Computazione più veloce.

2. Più probabilità che siano 𝐵-smooth.

3. Essendoci più 𝐵-smooth, possiamo ridurre 𝐵, o equivalentemente la dimensione della factor base.

Altro vantaggio è dato dal fatto che possiamo far lavorare i processori in parallelo su polinomi differenti.

Peter Montgomery propose di usare polinomi della forma

𝑓(𝑥) ≔ 𝑎𝑥2 + 2𝑏𝑥 + 𝑐

con 𝑎, 𝑏, 𝑐 interi non negativi tali che 𝑏2 − 𝑎𝑐 = 𝑛. Notiamo che

𝑎𝑓(𝑥) = 𝑎2𝑥2 + 2𝑎𝑏𝑥 + 𝑏2 − 𝑏2 + 𝑎𝑐 = (𝑎𝑥 + 𝑏)2 − 𝑛.

Dunque

(𝑎𝑥 + 𝑏)2 ≡ 𝑎𝑓(𝑥) (𝑚𝑜𝑑 𝑛).

Se abbiamo un valore di 𝑎 che è 𝐵-smooth e un valore di 𝑥 per il quale 𝑓(𝑥) è 𝐵-smooth, allora il vettore di

esponenti di 𝑎𝑓(𝑥) modulo 2 può essere utilizzato per la nostra matrice. Inoltre, notiamo che se un primo

𝑝 ≤ 𝐵 divide 𝑓(𝑥), allora deve essere che 𝑝 ∣ 𝑎𝑓(𝑥) = (𝑎𝑥 + 𝑏)2 − 𝑛 e dunque (𝑛

𝑝) = 1, ossia possiamo

usare la stessa factor-base di prima.

Supponiamo che il nostro intervallo da setacciare sia [−𝑀,𝑀]. Vogliamo ottimizzare il valore di 𝑓(𝑥) su

questo intervallo. Un modo per fare ciò è determinare i nostri coefficienti cosicché il minimo e il massimo

valore di 𝑓(𝑥) su [−𝑀,𝑀] abbiano all’incirca lo stesso ordine di grandezza, ma siano di segno opposto. Il

nostro minimo è a 𝑥 = −𝑏 𝑎⁄ ove 𝑓(−𝑏 𝑎⁄ ) = −𝑛 𝑎⁄ . Notiamo che supponendo 𝑏 < 𝑎 si ha che

0 ≤ 𝑏 < 𝑎 ⟹ 0 ≤ 𝑏 𝑎⁄ < 1 ⟹ −1 < −𝑏 𝑎⁄ ≤ 0

dunque il nostro massimo sarà a −𝑀 o 𝑀 e sarà circa

𝑓(𝑀) =(𝑎𝑀 + 𝑏)2 − 𝑛

𝑎≈𝑎2𝑀2 − 𝑛

𝑎.

Vogliamo che questo sia circa 𝑛 𝑎⁄ , dunque

𝑎2𝑀2 − 𝑛

𝑎≈𝑛

𝑎 ⟹ 𝑎 ≈

√2𝑛

𝑀.

Euristicamente si nota che questa variante accelera il QS di un fattore di 1

2√log𝑛 log log 𝑛. Per 𝑛 di circa

100 cifre, ciò equivale ad accelerare il QS di 17 volte.

- 15 -

5. Appendice

5.1 Algoritmo per calcolare il simbolo di Legendre-Jacobi Sia 𝑝 un primo dispari. L’equazione 𝑥2 ≡ 𝑎 (𝑚𝑜𝑑 𝑝) può

Non avere soluzioni, equivalentemente 𝑎 non è un quadrato modulo 𝑝. Allora

(𝑎

𝑝) = −1.

Avere una soluzione: se e solo se 𝑎 ≡ 0 (𝑚𝑜𝑑 𝑝), in quanto 𝑥 ≡ −𝑥 (𝑚𝑜𝑑 𝑝) ⟺ 𝑝|2𝑥. Allora

(𝑎

𝑝) = 0.

Avere due soluzioni: in tal caso 𝑎 è detto residuo quadratico modulo 𝑝. Allora

(𝑎

𝑝) = 1.

Più in generale si definisce il simbolo di Jacobi come

(𝑚

𝑝1𝑒1 ∙∙∙ 𝑝𝑙

𝑒𝑙) ≔ (

𝑚

𝑝1)𝑒1∙∙∙ (

𝑚

𝑝𝑙)𝑒𝑙.

Come possiamo calcolare il valore del simbolo di Jacobi/Legendre (𝑎

𝑚)?

Una soluzione banale è data dal criterio di Eulero, per il quale si ha che

𝑎𝑝−12 ≡ (

𝑎

𝑝) (𝑚𝑜𝑑 𝑝).

Tuttavia tale soluzione comporterebbe calcolare una fattorizzazione completa di 𝑛 e, per ogni primo 𝑝 della

sua fattorizzazione, calcolare la potenza 𝑎𝑝−1

2 modulo 𝑝.

Esiste tuttavia una soluzione più furba che sfrutta la legge di reciprocità quadratica.

Algoritmo: dato 𝑎 intero e 𝑚 intero positivo dispari, restituisce (𝑎

𝑚).

a = a mod m; t = 1; while (a != 0){ while(a even){ a = a/2; if(m = 3,5 mod 8) t = -t; } swap(a,m); if(a = m = 3 mod 4) t = -t; a = a mod m; } if(m == 1) return t; else return 0;

Complessità: 𝑂(log2𝑚).

- 16 -

Cosa stiamo facendo in questo algoritmo? Anzitutto ricordiamo che se 𝑎, 𝑏 sono interi e 𝑚 è un intero

positivo dispari, si hanno varie proprietà, tra cui le seguenti tre:

(𝑎𝑏

𝑚) = (

𝑎

𝑚)(𝑏

𝑚)

(2

𝑚) = (−1)

𝑚2−18 = {

1, 𝑚 ≡ 1, 7 (𝑚𝑜𝑑 8)

−1, 𝑚 ≡ 3, 5 (𝑚𝑜𝑑 8)

(𝑚, 𝑛) = 1 ⟹ (𝑚

𝑛) = (−1)

(𝑚−1)(𝑛−1)4 (

𝑛

𝑚).

Ciò che facciamo è questo: scriviamo 𝑎 = 2𝑎′ e dunque

(𝑎

𝑚) = (

2𝑎′

𝑚) = (

2

𝑚)(𝑎′

𝑚) = 𝑡 (

𝑎′

𝑚)

e procediamo così fintanto che non otteniamo 𝑎 = 2𝑘𝑞 con 𝑞 dispari e

(𝑎

𝑚) = 𝑡 (

𝑞

𝑚).

A questo punto scriviamo

(𝑞

𝑚) = (−1)

(𝑞−1)(𝑚−1)4 (

𝑚

𝑞)

e (−1)(𝑞−1)(𝑚−1)

4 = 1 se e solo se (𝑞−1)(𝑚−1)

4 pari se e solo se almeno uno tra 𝑞 e 𝑚 è congruo a 1 (𝑚𝑜𝑑 4).

Nota che se venisse a mancare la coprimalità in qualche punto dell’algoritmo, si otterrebbe 0, in quanto per

definizione si ha che

(𝑚

𝑝1𝑒1 ∙∙∙ 𝑝𝑙

𝑒𝑙) = (

𝑚

𝑝1)𝑒1∙∙∙ (

𝑚

𝑝𝑙)𝑒𝑙.

5.2 Algoritmo di Shanks-Tonelli Cerchiamo radici quadrate modulo 𝑝, ossia soluzioni all’equazione 𝑥2 ≡ 𝑎 (𝑚𝑜𝑑 𝑝).

Supporremo di sapere già che 𝑎 sia un residuo quadratico. Distinguiamo i vari casi:

Se 𝑝 ≡ 3 (𝑚𝑜𝑑 4) la soluzione è data da

𝑥 = 𝑎𝑝+14 (𝑚𝑜𝑑 𝑝).

Infatti 𝑥2 = 𝑎𝑝+1

2 = 𝑎 ∙ 𝑎𝑝−1

2 ≡ 𝑎 (𝑚𝑜𝑑 𝑝).

Se 𝑝 ≡ 5 (𝑚𝑜𝑑 8), siccome ℤ𝑝 è un campo, abbiamo che

𝑎𝑝−12 ≡ 1 (𝑚𝑜𝑑 𝑝) ⟹ 𝑎

𝑝−14 ≡ ±1 (𝑚𝑜𝑑 𝑝).

Se 𝑎𝑝−1

4 ≡ 1 (𝑚𝑜𝑑 𝑝), allora 𝑥 = 𝑎𝑝+3

8 è soluzione, infatti

- 17 -

𝑥2 = 𝑎𝑝+34 = 𝑎 ∙ 𝑎

𝑝−14 ≡ 𝑎 (𝑚𝑜𝑑 𝑝).

Se 𝑎𝑝−1

4 ≡ −1 (𝑚𝑜𝑑 𝑝), allora per la legge di reciprocità quadratica si ha che

2𝑝−12 ≡𝑝 (

2

𝑝) = (

2

𝑝) ∙ 1 = (

2

𝑝) (𝑝

2) = (−1)

(2−1)(𝑝−1)4 = (−1)

𝑝−14 = (−1)

5+8𝑘−14 = (−1)1+2𝑘 = −1.

E quindi 𝑥 = 2𝑎(4𝑎)𝑝−5

8 (𝑚𝑜𝑑 𝑝) è soluzione, infatti

𝑥2 = 4𝑎2(4𝑎)𝑝−54 = 2

𝑝−12 𝑎

𝑝−14 𝑎 ≡ 𝑎 (𝑚𝑜𝑑 𝑝).

Se 𝑝 ≡ 1 (𝑚𝑜𝑑 8) dobbiamo usare l’algoritmo di Shanks-Tonelli, tuttavia l’algoritmo ha valenza generale.

Possiamo sempre scrivere 𝑝 − 1 = 2𝑠𝑡 con 𝑡 dispari. Il criterio di Eulero ci dice che

(𝑎𝑡)2𝑠−1

= 𝑎𝑝−12 ≡ 1 (𝑚𝑜𝑑 𝑝)

ossia che l’ordine moltiplicativo di 𝑎𝑡 in 𝐺 ≔ ℤ𝑝∗ divide 2𝑠−1. Sia 𝑑 un residuo non quadratico modulo 𝑝

(metà degli elementi lo sono, quindi è facile da trovare). Sia 𝐷 ≔ 𝑑𝑡 (𝑚𝑜𝑑 𝑝) e notiamo che l’ordine di 𝐷 è

2𝑠, infatti:

𝐷2𝑠= 𝑑2

𝑠𝑡 = 𝑑𝑝−1 ≡ 1 (𝑚𝑜𝑑 𝑝)

𝐷2𝑠−1

= 𝑑2𝑠−1𝑡 = 𝑑

𝑝−12 ≡ −1 (𝑚𝑜𝑑 𝑝).

Dunque anche l’ordine di 𝐷−1 è 2𝑠. Essendo 𝐺 ciclico, abbiamo che 𝐴 ≔ 𝑎𝑡 (𝑚𝑜𝑑 𝑝) sta nel sottogruppo

ciclico generato da 𝐷−2, in particolare è della forma 𝐴 ≡ 𝐷−2𝜇 (𝑚𝑜𝑑 𝑝) per un certo 0 ≤ 𝜇 < 2𝑠−1.

Abbiamo dunque che

𝑎𝑡𝐷2𝜇 ≡ 1 (𝑚𝑜𝑑 𝑝) ⟹ (𝑎𝑡+12 𝐷𝜇)

2

≡ 𝑎 (𝑚𝑜𝑑 𝑝).

Algoritmo (di Shanks-Tonelli):

1. Trova a caso un intero 𝑑 ∈ [2, 𝑝 − 1] tale che (𝑑

𝑝) = −1.

2. Scrivi 𝑝 − 1 = 2𝑠𝑡 con 𝑡 dispari.

𝐴 = 𝑎𝑡 (𝑚𝑜𝑑 𝑝)

𝐷 = 𝑑𝑡 (𝑚𝑜𝑑 𝑝)

𝑚 = 0 //𝑚 = 2𝜇

3. for(0 ≤ 𝑖 < 𝑠)

if ((𝐴𝐷𝑚)2𝑠−1−𝑖

≡ −1 (𝑚𝑜𝑑 𝑝))

𝑚 = 𝑚 + 2𝑖

4. return 𝑎𝑡+1

2 𝐷𝑚

2 (𝑚𝑜𝑑 𝑝)

Caso pessimo: 𝑂(log4 𝑝).

Caso medio: 𝑂(log3 𝑝).

- 18 -

5.3 Lemma di Hensel Se un’equazione polinomiale ha una radice semplice modulo un primo 𝑝, allora questa radice corrisponde

in maniera univoca a una radice della stessa equazione modulo ogni potenza di 𝑝. Tale nuova radice può

essere trovata iterativamente slittando la soluzione modulo potenze successive di 𝑝.

Lemma. Sia 𝑓(𝑥) un polinomio a coefficienti interi e siano 𝑚, 𝑘 interi positivi tali che 𝑚 ≤ 𝑘. Se 𝑟 è un

intero tale che

𝑓(𝑟) ≡ 0 (𝑚𝑜𝑑 𝑝𝑘) ∧ 𝑓′(𝑟) ≢ 0 (𝑚𝑜𝑑 𝑝)

allora esiste un intero 𝑠 tale che

𝑓(𝑠) ≡ 0 (𝑚𝑜𝑑 𝑝𝑘+𝑚) ∧ 𝑟 ≡ 𝑠 (𝑚𝑜𝑑 𝑝𝑘).

Inoltre questo 𝑠 è unico modulo 𝑝𝑘+𝑚 e può essere calcolato esplicitamente come l’intero tale che

𝑠 = 𝑟 − 𝑓(𝑟) ∙ 𝑎 con 𝑎 ≡ [𝑓′(𝑟)]−1 (𝑚𝑜𝑑 𝑝𝑚).

Dimostrazione. Ovviamente una radice 𝑠 modulo 𝑝𝑘+𝑚 deve per forza essere congrua a 𝑟 modulo 𝑝𝑘,

dunque 𝑠 = 𝑟 + 𝑡𝑝𝑘. Sviluppiamo ora il polinomio 𝑓 in serie di Taylor (termina visto che è un polinomio):

𝑓(𝑟 + 𝑡𝑝𝑘) = ∑𝑓(𝑛)(𝑟)

𝑛!(𝑡𝑝𝑘)

𝑛𝑁

𝑛=0

.

Dunque

𝑓(𝑟 + 𝑡𝑝𝑘) = 𝑓(𝑟) + 𝑡𝑝𝑘𝑓′(𝑟) + 𝑡2𝑝2𝑘𝑔(𝑡)

per qualche polinomio 𝑔(𝑡) a coefficienti interi. Riduciamo ambo i membri modulo 𝑝𝑘+𝑚 con 𝑚 ≤ 𝑘:

𝑓(𝑟 + 𝑡𝑝𝑘) ≡ 𝑓(𝑟) + 𝑡𝑝𝑘𝑓′(𝑟) (𝑚𝑜𝑑 𝑝𝑘+𝑚).

Imponiamo ora che sia una radice e notiamo che 𝑓(𝑟) = 𝑧𝑝𝑘, dunque

(𝑧 + 𝑡𝑓′(𝑟))𝑝𝑘 ≡ 0 (𝑚𝑜𝑑 𝑝𝑘+𝑚) ⟺ 𝑧 + 𝑡𝑓′(𝑟) ≡ 0 (𝑚𝑜𝑑 𝑝𝑚).

Risolvendo quest’ultima per 𝑡 in ℤ𝑝𝑚 si ottiene la formula del Lemma. Notiamo che l’ipotesi 𝑓′(𝑟) ≢

0 (𝑚𝑜𝑑 𝑝) serve a garantire l’esistenza dell’inverso di 𝑓′(𝑟) modulo 𝑝𝑚 (il quale è unico). Dunque una

soluzione per 𝑡 esiste unica modulo 𝑝𝑚 ed 𝑠 esiste unica modulo 𝑝𝑘+𝑚.

6. Bibliografia

Richard Crandall, Carl Pomerance, Prime Numbers - A Computational Perspective; Springer-Verlag,

2001.

Eric Landquist, The Quadratic Sieve Factoring Algorithm; MATH 488: Cryptographic Algorithms,

December 14, 2001.

Henri Cohen, A Course in Computational Algebraic Number Theory; Springer, 2000.