密码学基础练习五道 RSA、elgamal、elgamal数字签名、DSA数字签名、有限域(GF)上的四则运算

1.RSA

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <math.h>

#include <time.h>

#define PRIME_MAX 200      //生成素数范围

#define EXPONENT_MAX 200       //生成指数e范围

#define Element_Max 127       //加密单元的最大值,这里为一个char, 即1Byte

char str_read[100]="hello world !";      //待加密的明文

int str_encrypt[100];      //存放加密后的内容

char str_decrypt[100];      //存放解密出来的内容

int str_read_len;      //str_read 的长度

int prime1, prime2;      //随机生成的两个质数

int mod,eular;      //模数和欧拉数

int pubKey, priKey;      //公钥指数和私钥指数

//生成随机素数

int randPrime()

{

int prime,prime2,i;

next:

prime=rand()%PRIME_MAX;      //随机产生数

if (prime <= 1) goto next;      //不是质数,生成下一个随机数

if (prime == 2 || prime == 3)

return prime;

prime2=prime/2;      //注:prime>=4, prime2 的平方必定大于 prime , 因此只检查小于等于prime2的数

for (i=2;i<=prime2;i++)      //判断是否为素数

{

if(i*i>prime)

return prime;

if(prime%i==0)

goto next;      //不是质数,生成下一个随机数

}

}



// 欧几里德算法,判断a,b互质

int gcd(int a, int b)

{

int temp;

while (b!=0){

temp=b;

b=a%b;

a=temp;

}

return a;

}



//生成公钥,条件是 1< e < 欧拉数,且与欧拉数互质。

int randExponent()

{

int e;

while (1)

{

e=rand()%eular;

if(e<EXPONENT_MAX)

break;

}

while (1)

{

if(gcd(e, eular)==1)

return e;

e=(e+1)%eular;

if(e==0||e>EXPONENT_MAX)

e = 2;

}

}



//生成私钥指数

int inverse()

{

int d,x;

while (1)

{

d=rand()%eular;

x=pubKey*d%eular;

if(x==1)

{

    return d;

}

}

}



//加密函数

void jiami()

{

str_read_len = strlen(str_read);//从参数表示的地址往后找,找到第一个'\0',即串尾.计算'\0'至首地址的“距离”,即隔了几个字符,从而得出长度.

printf("密文是:");

for(int i=0;i<str_read_len;i++)

{

int C=1;

int a=str_read[i],b=a%mod;

for(int j=0;j<pubKey;j++)      //实现加密

{

C=(C*b)%mod;

}

str_encrypt[i]=C;

printf("%d",str_encrypt[i]);

}

printf("\n");

}



//解密函数

void jiemi()

{

int i=0;

for(i=0;i<str_read_len;i++)

{

int C=1;

int a=str_encrypt[i],b=a%mod;

for(int j=0;j<priKey;j++)

{

C=(C*b)%mod;

}

str_decrypt[i]=C;

}

str_decrypt[i]='\0';

printf("解密文是:%s\n",str_decrypt);

}



//主函数

int main()

{

srand(time(NULL));

while (1)

{

prime1=randPrime();

prime2=randPrime();

printf("随机产生两个素数:prime1=%d,prime2=%d",prime1,prime2);

mod=prime1*prime2;

printf("模数:mod=prime1*prime2=%d\n",mod);

if(mod>Element_Max)

break;      //模数要大于每个加密单元的值

}

eular=(prime1-1)*(prime
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值