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

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)*(prime2-1);

printf(“欧拉数:eular=(prime1-1)*(prime2-1)=%d\n”,eular);

pubKey=randExponent();

printf(“公钥指数pubKey=%d\n”,pubKey);

priKey=inverse();

printf(“私钥指数:priKey=%d\n  私钥为(%d, %d)\n”, priKey, priKey, mod);

jiami();

jiemi();

return 0;

}


流程图:


![](https://img-blog.csdnimg.cn/direct/30c37fa204484d43abdc14e65fc5fec3.png)



2.elgamal



#include<stdio.h>

#include<stdlib.h>

#include<math.h>

//模重复平方算法,计算a^b mod p

int pow_mod(int a,int b,int p)

{

int ans=1;

int tmp=a%p;

while(b){

if(b&1)

ans=ans*tmp%p;

b>>=1;

tmp=tmp*tmp%p;

}

return ans%p;

}

//elgamal加密算法,k为任意整数,m为明文,pub为公钥,p为大素数,g为生成元,c1,c2为密文

void elgamal_en(int m,int pub,int p,int g,int *c1,int *c2)

{

int k=5;

*c1=pow_mod(g,k,p);

c2=mpow_mod(pub,k,p)%p;

}

//elgamal解密算法,m_为解密后的数据,p为大素数,g为生成元,c1_为c1模p的逆元,pr为私钥

int elgamal_de(int c1,int c2,int pr,int p,int g)

{

int m;

int c1_=pow_mod(c1,p-2,p);

m=c2*pow_mod(c1_,pr,p)%p;

return m;

}

//判断是否为素数(为了严谨性而存在的函数,题中所给出的测试数据已经是素数了)

int is_prime(int p)

{

int i;

for(i=2;i<=sqrt§;i++){

if(p%i==0)

return 0;

}

return 1;

}

int main(){

int p=1069;      //必须为素数

int g=2;      //本原元

do{

printf(“请输入一个素数:%d\n”,p);

}

while(!is_prime§);

int pr=123;      //用户A的私钥

printf(“输入用户A的私钥:%d\n”,pr);

int pub;

pub=pow_mod(g,pr,p);

printf(“用户A的公钥为:%d\n”,pub);

int m=677;      //明文要小于p

int c1,c2;

elgamal_en(m,pub,p,g,&c1,&c2);

printf(“用公钥加密后的密文为:c1=%d,c2=%d\n”,c1,c2);

int m_=elgamal_de(c1,c2,pr,p,g);

printf(“用私钥解密后的明文为:%d\n”,m_);

}




流程图:


![](https://img-blog.csdnimg.cn/direct/7c81e8f358b446f39fb3b9dc7d5d08cc.png)


3.elgamal数字签名:



#include <stdio.h>

#include <stdlib.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 Coprime(int a, int b) {

return b==0?a:Coprime(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];

}

}

//主函数

int main() {

int p=1669,m=101,q=2;        //p为大素数,m为消息,q为本原元

int x,y,k,k1,r,a;

int k2,ni;

int s;

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(Coprime(k,p-1)!=1) {

k=rand()%p-1+1;

}

printf(“k=%d\n”,k);

//求r :r = g^k mod p

r=myPow(q,k,p);

printf(“r=%d\n”,r);

//加密过程

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\n”,ni);

m=myPow(ni,x,p)*s;

printf(“m=%d\n”,m%p);

//签名过程

// 计算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)\n”,r,s);

if((myPow(y,r,p)*myPow(r,s,p))%p==myPow(q,m,p))

printf(“接受签名\n”);

else

printf(“拒绝签名\n”);

}




流程图:


![](https://img-blog.csdnimg.cn/direct/c6aa62b03d01470886b99f802b1c038b.png)


4.DSA数字签名算法:



#include <stdlib.h>

#include <stdio.h>

#include <time.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 calculate(int h,int p,int q){

int a=(p-1)/q;

long int k=1;

for(int i=0;i<a;i++){

k=k*h;

}

return k%p;

}

int calculate1(int g,int x,int p){

long int k=1;

for(int i=0;i<x;i++){

k=k*g;

}

return k%p;

}

// 求 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];

}

}

//主函数

int main()

{

int p=23;

short q=11;      //p q为两个大素数,且满足(p-1)能够被q整除(这里为了方便选取了两个较小数,也可取p=7879,q=101)

int g,x,y,s,k,m,w,u1,u2,v,h,r;      //对出现的变量进行初始化

printf(“请输入大素数p=%d和q=%d ,满足(p-1)能够被q整除\n”,p,q);

srand(time(NULL));      //随机数种子

h=12;      //rand()%p-1+2 ;//随机数

g=calculate(h,p,q);

x=10;      //rand()%p-1+2 ;//私钥

y=calculate1(g,x,p);      //计算公钥

printf(“公钥是(%d,%d,%d,%d)\n”,p,q,g,y);

printf(“私钥为%d\n”,x);

//签名过程

k=9;      //rand()%p-1+2 ;//随机数k

r=calculate1(g,k,p)%q;

exGcd(k, q);

k = xy[0];

if(k < 0) k += (p-1);

m=13;

s=(m+x*r)*k%q;

printf(“签名为(%d,%d)\n”,r,s);

//验证程序

exGcd(s,q);

w =xy[0];

if(w < 0) w += (q);

u1=(m*w)%q;

u2=r*w%q;

v=myPow(g, u1, p)*myPow(y, u2, p)%p%q;

printf(“(w,u1,u2,v)=(%d,%d,%d,%d)\n”,w,u1,u2,v);

if(v==r){

printf(“接受”);

}else{

printf(“不接受”);

}

}



流程图:


![](https://img-blog.csdnimg.cn/direct/d77692e558db4905a563d20549debdf2.png)


5.有限域(GF)上的加、减、乘法计算器



#include

#include

#include

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

#include<cstdio>

#include<cstdlib>

#include<iostream>
## 最后

**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**

[外链图片转存中...(img-1onmbWhq-1715684660227)]

[外链图片转存中...(img-Gxk6E5db-1715684660228)]

[外链图片转存中...(img-prnuHCON-1715684660228)]

[外链图片转存中...(img-tS0CPmVS-1715684660228)]

[外链图片转存中...(img-HvPMwVJ1-1715684660229)]

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!**

[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875)

**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

  • 36
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值