• 【墨鳌】【数论小结 03】【RSA加密算法】


    数论小结 03

    欧拉函数的应用

    RSA加密算法

    1. 选取两个质数 \(p,q\)
    2. \(\varphi(n),n=p\cdot q\),显然:\(\varphi(n)=(p-1)(q-1)\)
    3. 构造公钥 \((n,e)\),选取 \(e\in[2,\varphi(n))\) 并且 \(\gcd(e,\varphi(n))=1\)
    4. 构造私钥 \((n,d)\),求 \(ed\equiv1\mod \varphi(n)\)
    5. 加密过程:\(C\leftarrow M^e\mod n\)
    6. 解密过程:\(M\leftarrow C^d\mod n\)

    通讯过程模拟

    //
    // 有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
    // Created by Mo-Ao on 2022-4-29 14:25:00
    //
    
    #include "Solution.h"
    
    int main() {
        Solution sol = Solution();
    
        typedef long long ll;
        /**
         * n=p*q
         * p=10000993
         * q=12072001
         * e=1000000007 (公钥:(n,e))
         * ed≡1 (mod φ(n)) 扩展欧几里得 or 费马小定理 求解 d
         * 注意:这里不可用“费马小定理”求解d,因为此时模数φ(n)不是质数
         * d=115336154889143 (私钥:(n,d))
         * C ← M^e mod n (公钥:(n,e))
         * M ← C^d mod n (私钥:(n,d))
         */
        ll p = 10000993;
        ll q = 12072001;
        ll phi = (p - 1) * (q - 1);
        // 以上参数应当销毁
    
        ll n = p * q;
        ll e = 1000000007;
        ll d = sol.inv(e, phi);
        //以上两组密钥(n,e),(n,d)由通讯双方持有
    
    
        string text = "Hello!";
        auto code = sol.send(text, n, e);
    
        //通讯中
        cout << "code = ";
        for (auto &ch: code)cout << ch << " ";
        cout << endl;
    
        auto receivedText = sol.receive(code, n, d);
        cout << receivedText << endl;
        return 0;
    }
    

    通讯模板工具

    //
    // 有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
    // Created by Mo-Ao on 2022-4-29 14:25:00
    //
    
    #ifndef TESTDEMO_SOLUTION_H
    #define TESTDEMO_SOLUTION_H
    
    #include <bits/stdc++.h>
    
    using namespace std;
    
    class Solution {
    public:
        typedef long long ll;
    
        /**
         * 光速乘
         * @param x
         * @param y
         * @param mod
         * @return (x*y) % mod
         */
        ll mul(ll x, ll y, ll mod) {
            ll ret = x * y - (ll) ((long double) x / mod * y + 0.5) * mod;
            return (ret % mod + mod) % mod;
        }
    
        /**
         * 快速幂
         * @param a
         * @param n
         * @param mod
         * @return pow(a,n) % mod
         */
        ll quick_pow(ll a, ll n, ll mod) {
            if (n == 0) return 1;
            ll x = quick_pow(a, n / 2, mod);
            ll ans = mul(x, x, mod);
            if (n % 2 == 1) ans = mul(ans, a, mod);
            return ans;
        }
    
    
        /**
         * 扩展欧几里得算法
         * @param a
         * @param b
         * @param x
         * @param y
         * @return (x,y) for  ax + by = gcd(a,b)
         */
        ll ex_gcd(ll a, ll b, ll &x, ll &y) {
            if (b == 0) {
                x = 1, y = 0;
                return a;
            }
            ll d = ex_gcd(b, a % b, y, x);// 注意:这里已经调换了x,y顺序
            y -= (a / b) * x;
            return d;
        }
    
        /**
         * 扩展欧几里得求逆元更具一般性
         * @param a
         * @param n
         * @return x for ax ≡ 1 (mod n)
         */
        ll inv(ll a, ll n) {
            ll x, y, d = ex_gcd(a, n, x, y);
            if (d == 1) {
                if (x % n <= 0)
                    return x % n + n;
                else
                    return x % n;
            }
            return -1;
        }
    
        /**
         * C ← M^e mod n
         * @param C
         * @param n
         * @param e
         * @return C
         */
        ll encode(ll M, ll n, ll e) {
            return quick_pow(M, e, n);
        }
    
        /**
         * M ← C^d mod n
         * @param C
         * @param n
         * @param d
         * @return M
         */
        ll decode(ll C, ll n, ll d) {
            return quick_pow(C, d, n);
        }
    
        /**
         * 发送端 C ← M^e mod n (公钥:(n,e))
         * @param text
         * @param n
         * @param e
         * @return
         */
        vector <ll> send(string&text, ll n, ll e) {
            vector <ll> C;
            for (char&ch: text) {
                ll M = ch;
                C.push_back(encode(M, n, e));
            }
            return C;
        }
        /**
         * 接收端 M ← C^d mod n (私钥:(n,d))
         * @param C
         * @param n
         * @param d
         * @return
         */
        string receive(vector<ll>&C,ll n,ll d){
            string text;
            for(ll&c:C){
                ll C=c;
                text+=(char)(decode(C,n,d));
            }
            return text;
        }
    
    };
    
    #endif //TESTDEMO_SOLUTION_H
    
  • 相关阅读:
    scgi_params
    ngin 模块及模板
    nginx常用模块
    HTML
    nginx部署网页小游戏
    nginx的server标签还有日志管理
    关于使用yum安装的nginx的主从配置文件的碎碎念
    判断所ping主机的操作系统
    CentOS 7修改主机名
    CentOS7 设置系统时间
  • 原文地址:https://www.cnblogs.com/JasonCow/p/16206601.html
Copyright © 2020-2023  润新知