模重複平方演算法

來源:互聯網
上載者:User

在RSA演算法裡頭經常要用到“求x的n次方模m”這樣的過程,通常使用O(log(n))的模重複平方演算法來實現,提高效率。

其實這是大二學的《資訊安全數學基礎》裡面的內容,那時為了考試需要(手算+寫出很羅嗦的過程),還專門寫了代碼放在Blog空間裡考試的時候用—……

同樣O(log(n))的遞迴演算法其實很容易理解:

/* C */int square(int x) { return x * x; } /* 這裡可不能用宏喲 */int fast_mod(int x, int n, int m){    if (n == 0)        return 1;    else if (n % 2 == 0)        return square(fast_mod(x, n / 2, m)) % m;    else         return x * fast_mod(x, n - 1, m) % m;}#Pythonfast_mod = lambda x, n, m: 1 if n == 0 else fast_mod(x, n / 2, m) ** 2 % m if n % 2 == 0 else x * fast_mod(x, n - 1, m) % m;Scheme(define (even? n) (= (remainder n 2) 0))(define (mod-fast x n m)    (define (square x) (* x x))     (cond ((= n 0) 1)          ((even? n) (remainder (square (mod-fast x (/ n 2) m)) m))           (else (remainder (* x (mod-fast x (- n 1) m)) m))))(mod-fast 79 24 33);

但是SICP要求寫一個迭代版的。印象中我是記得可以把 n 寫成二進位(比如n=13, 1101),然後一位一位地推。

試推了一下從高位到低位,倒是挺簡單的,記B[i]為第 i 位的值,通過A[i] = A[i+1]^2 * x^B[i] 從高到低計算出A[0],就得到結果了。但是問題是,為了從高到低計算,又得一次遞迴,似乎不能滿足要求。

於是只好反過來,從低位往高位推。這個過程其實也挺簡單的,舉例來說:

當n=13,即二進位的 1101 = 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0時,最終結果 

ans = x^n % m
    = x^(1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0) % m
    = [x^(1 * 2^3)] * [x^(1 * 2^2)] * [(x ^ (0 * 2^1)] * [x ^ (1 * 2^0)] % m

也就是說,從低到高,在第 i 位的時候,將 x^(Bit[i] * 2^i) % m 乘到結果中即可。這裡可以稍微變換一下:僅當Bit[i] == 1的時候,將x^(2^i) % m乘進去即可。所以這裡可以用一個輔助的變數 b 來儲存 x^(2^i) % m,在每次迭代的過程中 b =
b^2 % m 。

於是實現就容易了:

/* C */int fast_mod_iter(int x, int n, int m){    int a = 1, b = x; //i=0的時候b = x^(2^0) = x    while (n)    {        if (n % 2 == 1)            a = a * b % m;        b = b * b % m;        n /= 2;    }    return a;}#Pythondef fast_mod(x, n, m):     a = 1     b = x     while True:        if n == 0:            return a        if n % 2 == 1:            a = a * b % m         b = b * b % m         n /= 2;Scheme(define (even? n) (= (remainder n 2) 0))(define (mod-fast-iter x n m)    (define (iter a b n)        (cond ((= n 0) a)              ((even? n)                (iter a (remainder (* b b) m) (/ n 2)))              (else                (iter (remainder (* a b) m) (* b b) (/ (- n 1) 2)))))    (iter 1 x n))(mod-fast-iter 79 24 33);

轉自大牛 http://www.felix021.com/blog/read.php?2112 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.