逆元(數論倒數)【密碼學筆記】


數論倒數,又稱逆元

取模

對於取模,有一下一些性質:

但是唯獨除法是不滿足的:

為什么除法錯的呢?很好證明:

而對於一些題目,我們必須在中間過程中進行求余,否則數字太大,電腦存不下,那如果這個算式中出現除法,我們就需要逆元了。

逆元

定義:

我們知道,如果a*x = 1,那么x是a的倒數,x = 1/a

而在數論問題中,大部分情況都有取模,所以問題就變成了:

這時x在數值上就不一定等於我們常規意義上的1/a了,我們可以理解為要求在0,1,2……p-1之間找一個數,是的這個數和a相乘后再取模p,得到的結果為1。

現在就要在回到剛才的問題了,除以一個數等於乘上這個數的倒數,在除法取余的情況下,就是乘上這個數的逆元,即:

這樣就把除法,完全轉換為乘法了。

逆元的求解

對於逆元的求解,如果n較小的話,是容易算出來的,例如,求3在模26下的逆元:

但是當n非常大的時候,就需要引入一個算法來計算

(1)擴展歐幾里得算法(extend_gcd)

對於逆元的表達式可以做一些變換:

 

 

 當gcd(a,n)=1時,代入extend_gcd(a,n,x,y),得到的非負的x值,就是a對模n的逆元。

算法實現與證明

也就是說,我們得到了一個和gcd算法中,gcd(m,n)=gcd(n,m%n)相似的恆等式

 什么意思呢?舉個例子,就是

 如果想要x為正值,根據

 只再做一步:

if (x < 0) {
    x += b; y -= a;
}

擴展:

完整算法:

int extend_gcd(int a, int b, int& x, int& y) {
    if (b == 0) {
        x = 1, y = 0;
        return a;
    }
    int q = extend_gcd(b, a % b, x, y);
    int temp = x;
    x = y;
    y = temp - a / b * y;
    return q;
}

(2)費馬小定理

如果p是一個質數,並且gcd(a,p)=1

兩邊同除以 a

所以

用快速冪求一下,復雜度O(logn)

(3)不知道叫啥

當p為質數時有

證明:

寫成算法就是一個遞歸,到1為止,因為1的逆元就是1

int inv(int t, int p) {
    return t == 1 ? 1 : (p - p / t) * inv(p % t, p) % p;
}

這個方法復雜度是O(n),但並不是說比前兩個差,它可以在O(n)的復雜度內算出n個數的逆元,上面的算法加一個記憶性搜索就行了

int inv(int t, int p) {
    return INV[t] = t == 1 ? 1 : (p - p / t) * inv(p % t, p) % p;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM