Invers modular

Problema

În cadrul multor probleme de informatică se cere calcularea unei valori și afișarea acesteia modulo unei constante precizate în enunț. Se poate observa faptul că operațiile de adunare, scădere și înmulțire se pot efectua fără probleme cu respect la un anumit modul, însă operația de împărțire trebuie tratată diferit. Mai exact, dacă AA, BB si MM sunt numere întregi, M0M \ne 0, B0B \ne 0, egalitatea ABmodM=AmodMBmodMmodM\frac{A}{B} \mod{M} = \frac{A \mod{M}}{B \mod{M}} \mod{M} nu este întotdeauna adevărată.

Se recomandă citirea informațiilor din articolul despre matematică de bază înainte de a citi noțiunile de aici.

Ce este inversul modular?

În matematică, inversul unui număr real xx este acel număr x1x^{-1} care satisface xx1=1x \cdot x^{-1} = 1. Împărțirea unui număr la xx este echivalentă cu înmulțirea acestuia cu x1=1xx^{-1} = \frac{1}{x}. Tot așa, și în aritmetica modulară definim inversul modular al unui număr xx (cu respect la modulul MM) acel număr notat x1x^{-1} care satisface relația xx11(modM)x \cdot x^{-1} \equiv{1} \pmod{M}. Se poate demonstra faptul că un număr întreg are un invers modular modulo MM dacă și numai dacă el și MM sunt prime între ele.

Atunci, pentru a efectua operația de împărțire cu respect la modul dintre AA și BB trebuie să îl înmulțim pe AA cu inversul modular al lui BB, deoarece (AB)modM=(AB1)modM(\frac{A}{B}) \mod{M} = (A \cdot B^{-1}) \mod{M}.

Cum calculăm inversul modular al unui număr?

Calcularea folosind mica teoremă a lui Fermat

Definiție

Dacă pp este un număr prim și aa este un număr întreg prim cu pp, atunci ap11(modp)a^{p-1} \equiv 1 \pmod{p}.

Congruența se mai poate scrie ca:

aap21(modp)a \cdot a^{p - 2} \equiv 1 \pmod{p}

Se poate observa ușor că de fapt inversul modular al lui aa este ap2a^{p - 2}, care poate fi calculat rapid folosind exponențierea logaritmică.

Algoritmul extins al lui Euclid

Luăm în considerare următoarea identitate:

Identitatea lui Bézout

Fie numerele întregi AA, BB și d=cmmdc(A,B)d = cmmdc(A, B). Atunci, există cel puțin o pereche de numere întregi xx și yy astfel încat Ax+By=dAx + By = d.

Daca AA și MM sunt prime între ele, atunci există x1x_1 și y1y_1 astfel încât Ax1+My1=1Ax_1 + My_1 = 1. De aici reiese faptul că Ax11(modM)Ax_1 \equiv 1 \pmod{M}, adică x1x_1 este inversul modular al lui AA.

Fie cc câtul împărțirii lui AA la MM și rr restul. Algoritmul lui Euclid ne spune că cmmdc(A,M)=cmmdc(M,r)    cmmdc(M,r)=1cmmdc(A, M) = cmmdc(M, r) \implies cmmdc(M, r) = 1. Astfel, există x2x_2 și y2y_2 care satisfac Mx2+ry2=1Mx_2 + ry_2 = 1.

Dar

r=AMc    Mx2+(AMc)y2=1    Mx2+Ay2Mcy2=1    Ay2+M(x2cy2)=1\begin{align*} r = A - M \cdot c &\implies Mx_2 + (A - M \cdot c)y_2 = 1\\ &\iff Mx_2 + Ay_2 - M \cdot c \cdot y_2 = 1\\ &\iff Ay_2 + M(x_2 - c \cdot y_2) = 1 \end{align*}

Se observa că x1=y2x_1 = y_2 și y1=x2cy2y_1 = x_2 - c \cdot y_2, iar c=AMc = \lfloor \frac{A}{M} \rfloor. Astfel, putem folosi recursiv algoritmul lui Euclid, adăugându-i parametrii x1x_1 și y1y_1:

void euclidExtins(const int a, const int b, int &x1, int &y1);

În cazul în care parametrul bb din funcție este egal cu 0, atunci aa va fi egal cu 1 și astfel vom seta x1=1x_1 = 1, iar y1y_1 poate lua orice valoare, de exemplu tot 1.

Atenție

Valoarea lui x1x_1 poate fi și negativă. Dacă este necesară o valoare pozitivă atunci facem operația x1=x1+Mx_1 = x_1 + M.

Mai jos se poate observa o implementare în C++ a algoritmului lui Euclid, respectiv a funcției de calculare a inversului modular al lui AA pentru modulul MM:

void euclidExtins(const int a, const int b, int &x1, int &y1) {
    if (b == 0) {
        x1 = 1;
        y1 = 1;
        return;
    }

    int x2, y2;

    euclidExtins(b, a % b, x2, y2);

    x1 = y2;
    y1 = (x2 - a / b * y2) % M;
}

int inversModular(const int A) {
    int x1, y1;

    euclidExtins(A, M, x1, y1);

    /* daca vrem x1 pozitiv
    if(x1 < 0)
        x1 += M;
    */

    return x1;
}

Probleme cu invers modular

Lectură suplimentară