Elgamal签名算法(初始化和签名)含C语言

Elgamal签名算法(初始化和签名)

在这里插入图片描述

Elgamal签名算法(验证)

在这里插入图片描述

Elgamal签名算法(正确性)

在这里插入图片描述

Elgamal签名算法(举例)

在这里插入图片描述

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
int xy[22];
int myPow(int a, int b, int m) {
    
    
        int res = 1;
        a %= m;
        while (b != 0) {
    
    
            if ((b & 1) == 1)
                res = (res * a) % m;
            a = (a * a) % m;
            b >>= 1;
        }
        return res;
    }
// 判断两个数是否互质
int isHuZhi(int a, int b) {
    
    
    return b == 0 ? a : isHuZhi(b, a % b);
}


int calculate3(int y,int k,int p){
    
    
	printf("...%d %d %d\n",y,k,p);
	int l=1;
	for(int i = 0;i<k;i++){
    
    
		l=l*y;
		l=l%p;
	}
	printf("l=%d\n",l);
	return l;
}
// 求 a mod b 的逆元
void exGcd(int a, int b) {
    
    
    if (b == 0) {
    
    
        xy[0] = 1;
        xy[1] = 0;
    } else {
    
    
        exGcd(b, a % b);
        int x = xy[0];
        xy[0] = xy[1];
        xy[1] = x - (a / b) * xy[1];
    }
}
main()
{
    
    
	int p,q,x,y,k,k1,m,r,a;
	int k2,ni;
	int s;
	printf("请输入大素数 p ");
	scanf("%d",&p);
	printf("请输入消息 m  ");
	scanf("%d",&m);
	printf("请输入本源元 q ");
	scanf("%d",&q); 
	
	srand(time(NULL)); //随机数种子
	x=15;//rand()%p-1+2 ;
	printf("x=%d\n",x);
	y = myPow(q, x, p); // y是公开密钥
	printf("公开密钥y=%d\n",y);
	
	
	k =11;//rand()%p-1+1 ;
	while (isHuZhi(k, p-1) != 1) {
    
    
        k =rand()%p-1+1 ;
    }
    printf("k=%d",k);
     // r = g^k mod p
    r = myPow(q, k, p);
    printf("r=%d\n",r);
    printf("若是加密请输入1,签名输入2");
    scanf("%d",&a);
    switch(a){
    
    
    	case 1:
				s=calculate3(y,k,p);
				if(s < 0) s =(s+(p-1))%(p-1);
				s=s*m%p;
				printf("发送密文(%d,%d)\n",r,s);
				//解密
				 k2=myPow(r, x, p);
				 printf("k2=%d\n",k2);
				 exGcd(r,p);
				 ni=xy[0];
				 if(ni<0)ni=ni+p;
				 printf("ni=%d",ni);
				 m=myPow(ni,x,p)*s;
				
				 printf("m=%d",m%p); 
				break;
    	case 2: // 计算k^-1 mod p-1
			    exGcd(k, (p-1));
				k1 = xy[0];
			    if(k1 < 0) k1 += (p-1);
			    printf("k1=%d\n",k1);
			    // s = k^(-1)*(m-rx)(mod p-1)
			    s = (k1*(m-r*x))%(p-1); // (m,r,s)为对消息m的数字签名
			    printf("s=%d\n",s);
			    // s可能为负值,所以要将其转化为正数,利用a%b=(a%b+b)%b
			    if(s < 0) s =(s%(p-1)+(p-1))%(p-1);
			   
				printf("签名为(%d,%d)",r,s);
				
			    if ((myPow(y, r, p) * myPow(r, s, p))%p == myPow(q, m, p)) {
    
    
			        printf("接受签名"); 
			    } else {
    
    
			        printf("拒绝签名"); 
			    }
				
			
			    // 计算k^-1 mod p-1
			    exGcd(k, (p-1));
				k1 = xy[0];
			    if(k1 < 0) k1 += (p-1);
			    printf("k1=%d\n",k1);
			    // s = k^(-1)*(m-rx)(mod p-1)
			    s = (k1*(m-r*x))%(p-1); // (m,r,s)为对消息m的数字签名
			    printf("s=%d\n",s);
			    // s可能为负值,所以要将其转化为正数,利用a%b=(a%b+b)%b
			    if(s < 0) s =(s%(p-1)+(p-1))%(p-1);
			   
				printf("签名为(%d,%d,%d)",r,s,p);
				
			    if ((myPow(y, r, p) * myPow(r, s, p))%p == myPow(q, m, p)) {
    
    
			        printf("接受签名"); 
			    } else {
    
    
			        printf("拒绝签名"); 
			    }
			    break;
			}
	
}

おすすめ

転載: blog.csdn.net/mlynb/article/details/110569522