美文网首页密码学
「密码学」-Elgamal密码体制

「密码学」-Elgamal密码体制

作者: 雨落八千里 | 来源:发表于2019-09-26 22:24 被阅读0次

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
    \therefore公钥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
    \therefore密文为(1430,697)

  • 解密
    依题意:其中p=2357,\alpha=2,a=1751,C:(1430,697)
    \therefore求出1430^{1751}在模p的逆元w=872
    \therefore 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\n");
    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\n");
        scanf("%lld%lld%lld%lld",&p,&a,&b,&x);
        byg = cal(p);
        printf("%lld\n", 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)\n",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\n", 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\n",B,C);
    // ll K=inv(qpow(B,a,p),p);
    // cout<<C *K%p<<endl;
    return 0;
}

相关文章

网友评论

    本文标题:「密码学」-Elgamal密码体制

    本文链接:https://www.haomeiwen.com/subject/bonjuctx.html