zoukankan      html  css  js  c++  java
  • 「密码学」-Elgamal密码体制

    Elgamal:

    加密

    1. 随机选择一个质数(p),并且求出模(p)情况下的本原根(alpha),并将(p,alpha)公开
    2. 随机选择一个整数(a),作为私钥,并对(a)保密。
    3. 计算出公钥(A=alpha^{a}( mod p))
    4. 对于一段明文(x),随机选择一个整数(b),分别计算出(C_1=alpha^b( mod p) C_2=x*A^b( mod p))

    解密

    1. 对于密文((C_1,C_2))进行解密,首先应当计算(C_1^{a})(p)情况下的逆元(w)。然后明文(m=w*C_2( mod p))

    本原根:最小的原根被称为本原根

    习题

    • 选择一个质数(p=2357),在模(p)情况下的最小原根是(alpha=2),选择一个数(a=1751,b=1520),写出对明文(x=2035)加密密文和解密过程。

    • 加密
      依题意:其中的(p=2357,alpha=2,a=1751,b=1520)
      ( herefore)公钥(A=alpha^a( mod p)=2^{1751}\%2357=1185)
      (C_1=alpha^b( mod p)=2^{1520}\%2357=1430)
      (C_2=x*A^b( mod p)=2035*1185^{1520}\%2357=697)
      ( herefore)密文为((1430,697))

    • 解密
      依题意:其中(p=2357,alpha=2,a=1751,C:(1430,697))
      ( herefore)求出(1430^{1751})在模(p)的逆元(w=872)
      ( herefore x=872*697\%2357=2035)

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn = 1e5 + 5;
    ll factor[maxn], k;
    bool prim(ll x)
    {
        if(x==1)
        {
            return false;
        }
        if(x==2)
        {
            return true;
        }
        if(x%2==0)
        {
            return false;
        }
        for(ll i=3; i*i<=x; i++)
        {
            if(x%i==0)
            {
                return false;
            }
        }
        return true;
    }
    ll qpow(ll a,ll n,ll mod)
    {
        ll ans=1;
        ll base=a;
        while(n)
        {
            if(n&1)
            {
                ans=ans*base%mod;
            }
            base=base*base%mod;
            n>>=1;
        }
        return ans%mod;
    }
    void decompose(ll x)  //分解质因子
    {
        ll ans = 0;
        for (ll i = 2; i * i <= x; i++)
        {
            if (x % i == 0)
            {
                factor[k++] = i;
                while (x % i == 0)  x /= i;
            }
        }
        if (x > 1)  factor[k++] = x;
    }
    ll cal(ll n)  //求素数最小原根
    {
        k=0;
        decompose(n - 1);
        for (ll g = 2; g < n; g++)
        {
            int flag = 1;
            for (int i = 0; i < k; i++)
            {
                ll t = (n - 1) / factor[i];
                if (qpow(g, t, n) == 1)
                {
                    flag = 0;
                    break;
                }
            }
            if (flag == 1)
                return g;
        }
    }
    void exgcd(ll a,ll b,ll &gcd,ll &x,ll &y)
    {
        if(b==0)
        {
            gcd=a;
            x=1;
            y=0;
        }
        else
        {
            exgcd(b,a%b,gcd,y,x);
            y-=x*(a/b);
        }
    }
    ll inv(ll a,ll b)
    {
        ll gcd,x,y;
        exgcd(a,b,gcd,x,y);
        return gcd==1?(x%b+b)%b:-1;
    }
    int main()
    {
        printf("encry 1,decry2
    ");
        int flag;
        scanf("%d",&flag);
        ll p,a,b,x;
        ll A,B,C,byg;
        if(flag==1)
        {
            //printf("随机生成一个大的质数p");
            printf("Prime p,a,b,x
    ");
            scanf("%lld%lld%lld%lld",&p,&a,&b,&x);
            byg = cal(p);
            printf("%lld
    ", byg);
            A=qpow(byg,a,p);
            cout<<A<<endl;
            B=qpow(byg,b,p);
            C=(x*qpow(A,b,p))%p;
            printf("C(%lld,%lld)
    ",B,C);
        }
        else if(flag==2)
        {
            printf("Prime p,a,B,C");
            scanf("%lld%lld%lld%lld", &p,&a,&B,&C);
            ll K=inv(qpow(B,a,p),p);
            cout<<C *K%p<<endl;
        }
        // printf("输入质数p,随机数a,随机数b,明文x");
        // scanf("%lld%lld%lld%lld", &p,&a,&b,&x);
        // ll byg = cal(p);
        // printf("%lld
    ", byg);
        // ll A=qpow(byg,a,p);
        // cout<<A<<" A "<<endl;
        // ll B=qpow(byg,b,p);
    
        // ll C=(x*qpow(A,b,p)%p)%p;
        // printf("%lld %lld
    ",B,C);
        // ll K=inv(qpow(B,a,p),p);
        // cout<<C *K%p<<endl;
        return 0;
    }
    
  • 相关阅读:
    Design and Implementation of the Sun Network File System
    Flash: An Efficient and Portable Web Server
    Java集合框架练习-计算表达式的值
    后缀数组专题训练
    经典问题-生产者和消费者问题
    ubuntu14.04下配置Java环境以及安装最新版本的eclipse
    Java多线程之CountDownLatch学习
    ZooKeerper学习之Watcher
    ZooKeeper之FastLeaderElection算法详解
    python获取当天日期进行格式转换
  • 原文地址:https://www.cnblogs.com/lcbwwy/p/13124466.html
Copyright © 2011-2022 走看看