密码学基础练习五道 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, 即1Bytechar 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)*(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;}

流程图:

2.elgamal

#include<stdio.h>#include<stdlib.h>#include<math.h>//模重复平方算法,计算a^b mod pint 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=m*pow_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(p);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(p));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;      //明文要小于pint 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_);}

流程图:

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 pr=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-1exGcd(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)%bif(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");elseprintf("拒绝签名\n");}

流程图:

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 ;//随机数kr=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("不接受");}}

流程图:

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

#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>#include<cstring>#include<vector>#include<cmath>#include<bits/stdc++.h>int hex1=0x57,hex2=0x83;void jiafa(int hex1,int hex2){printf("请输入两个十六进制串:%x %x\n",hex1,hex2);printf("\n得到有限域内相加结果 : %#X\n\n",hex1^hex2);}//a减去b,其实就是a加上b的加法逆元,关键是找到b的加法逆元。void chengfa(int hex1,int hex2){int a[16],b[16],s[32];printf("请输入两个十六进制串:%x %x\n",hex1,hex2);int n=hex2,cnt=0;while(n)///转化为二进制{s[cnt++]=n%2;n/=2;}a[1]=0x01,b[1]=hex1;for(int i=2; i<=8; i++)a[i]=a[i-1]<<1;///得到0x01 0x02 0x04 0x08 0x10 0x20 0x40 0x80for(int i=2; i<=8; i++){if(b[i-1]&0x80)///如果最高为为1就对不可约多项式取模,否则直接左移b[i]=((b[i-1]<<1)^0x1B);elseb[i]=b[i-1]<<1;b[i]&=0xFF;///直接取后两位}int hex=0x00;for(int i=7; i>=0; i--){if(s[i]==1)///当二进制的这一位为1的时候才能异或hex^=b[i+1];}printf("\n得到有限域内相乘结果 : %#X\n\n",hex);}int main(){while(1){printf("请选择进行的运算: 0.退出运算  1.加/减法运算  2.乘法运算 \n\n");int ch;scanf("%d",&ch);switch(ch){case 0:system("cls");printf("\n谢谢使用!\n");exit(0);case 1:system("cls");jiafa(hex1,hex2);break;case 2:system("cls");chengfa(hex1,hex2);break;default :system("cls");printf("\n输入错误!请重新输入:\n\n");break;}}return 0;}

流程图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/5912.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flink on k8s 入门实战

Flink on k8s 入门实战 背景 最近一直在学习flink on k8s,踩了不少坑,折腾了好几天,终于是达到了自己想要的效果。 首先说一下,我要实现的效果是什么?Application模式下,ip和端口保持不变,根据不同的路径访问不同的任务。 环境部署 这一步也是我遇到问题最多的一步…

dockerfile 搭建lamp 实验模拟

一 实验目的 二 实验 环境 1, 实验环境 192.168.217.88一台机器安装docker 并做mysql nginx php 三台容器 2&#xff0c; 大致框架 3&#xff0c; php php:Nginx服务器不能处理动态页面&#xff0c;需要由 Nginx 把动态请求交给 php-fpm 进程进行解析 php有三…

Matlab基本语法

基本语法 x pi %使用等号创建变量 y sin(-5) %使用括号提供函数输入桌面管理 save %将当前工作区保存到MAT文件 load %将MAT文件中的变量加载到工作区 clear %清空工作区的所有变量 clc %清除命令行窗口的所有文本 format %更改数值输出的显示方式数字类型 4 %标量 …

LT6911UXB HDMI2.0 至四端口 MIPI DSI/CSI,带音频 龙迅方案

1. 描述LT6911UXB 是一款高性能 HDMI2.0 至 MIPI DSI/CSI 转换器&#xff0c;适用于 VR、智能手机和显示应用。HDMI2.0 输入支持高达 6Gbps 的数据速率&#xff0c;可为4k60Hz视频提供足够的带宽。此外&#xff0c;数据解密还支持 HDCP2.2。对于 MIPI DSI / CSI 输出&#xff0…

van-cascader(vant2)异步加载的bug

问题描述&#xff1a;由于一次性返回所有的级联数据的话&#xff0c;数据量太大&#xff0c;接口响应时间太久&#xff0c;因此采用了异步加载的方案&#xff0c;看了vant的官方示例代码&#xff0c;照着改了下&#xff0c;很轻松地实现了功能。正当我感叹世界如此美好的时候&a…

【C++ —— 多态】

C —— 多态 多态的概念多态的定义和实现多态的构成条件虚函数虚函数的重写虚函数重写的两个例外协变&#xff1a;析构函数的重写 C11 override和final重载、覆盖(重写)、隐藏(重定义)的对比 抽象类概念接口继承和实现继承 多态的继承虚函数表多态的原理动态绑定和静态绑定 单继…

区块链 | IPFS:Merkle DAG

Merkle DAG&#xff08;Merkle Directed Acyclic Graph&#xff09;是IPFS&#xff08;InterPlanetary File System&#xff09;系统中使用的一种创新的数据结构&#xff0c;用于组织和存储数据。它基于默克尔树&#xff08;Merkle Tree&#xff09;的概念&#xff0c;通过有向…

中科大研二:字节实习半年的感悟和求职经验

在科技巨头字节跳动的实习经历无疑是一段难忘之旅。我有幸作为中科大软件学院研二学生&#xff0c;获得了这样的机会。实习的总时长超过半年&#xff0c;让我深刻体会到了字节跳动对实习生的重视与培养。 在这里&#xff0c;我不仅技术能力得到了锤炼&#xff0c;更在mentor的…

数据库(MySQL)基础:多表查询(一)

一、多表关系 概述 项目开发中&#xff0c;在进行数据库表结构设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;由于业务之间相互关联&#xff0c;所以各个表结构之间也存在着各种联系&#xff0c;基本上分为三种&#xff1a;…

OceanBase开发者大会实录-陈文光:AI时代需要怎样的数据处理技术?

本文来自2024 OceanBase开发者大会&#xff0c;清华大学教授、蚂蚁技术研究院院长陈文光的演讲实录—《AI 时代的数据处理技术》。完整视频回看&#xff0c;请点击这里&#xff1e;> 大家好&#xff0c;我是清华大学、蚂蚁技术研究院陈文光&#xff0c;今天为大家带来《AI 时…

【C语言】atoi和atof函数的使用

人生应该树立目标&#xff0c;否则你的精力会白白浪费。&#x1f493;&#x1f493;&#x1f493; 目录 •&#x1f319;知识回顾 &#x1f34b;知识点一&#xff1a;atoi函数的使用和实现 • &#x1f330;1.函数介绍 • &#x1f330;2.代码演示 • &#x1f330;3.atoi函数的…

使用Python爬虫会遇到的问题和解决方法(包含案例)

一、HTTP错误&#xff08;如403 Forbidden&#xff09; 问题描述&#xff1a; 当使用requests库发起请求时&#xff0c;可能会遇到HTTP 403 Forbidden错误&#xff0c;这通常意味着服务器理解了请求&#xff0c;但是拒绝执行它。 解决方法&#xff1a; 1.设置headers&#xf…

Flask框架进阶-Flask流式输出和受访配置--纯净详解版

Flask流式输出&#x1f680; 在工作的项目当中遇到了一种情况&#xff0c;当前端页面需要对某个展示信息进行批量更新&#xff0c;如果直接将全部的数据算完之后&#xff0c;再返回更新&#xff0c;则会导致&#xff0c;前端点击刷新之后等待时间过长&#xff0c;开始考虑到用进…

【C++】C++ 11 新特性:使用示例

文章目录 C 11 新特性变量类型推导 auto表达式类型推导 decltype初始化列表基于范围的for循环Lambda 表达式智能指针空指针nullptr左值右值移动语义和完美转发常量表达式 constexpr委托构造函数继承构造函数overridefinal并发编程正则表达式 C 11 新特性 以下内容给出C11部分新…

liceo靶机复现

liceo-hackmyvm 靶机地址&#xff1a;https://hackmyvm.eu/machines/machine.php?vmLiceo 本机环境&#xff1a;NAT模式下&#xff0c;使用VirtualBox 信息收集&#xff1a; 首先局域网内探测靶机IP 发现IP为10.0.2.4 开启nmap扫描一下看看开了什么端口 扫描期间看一下web页…

粤嵌gec6818开发板-驱动usb摄像头

前段时间做了一个项目&#xff0c;用到了linux环境下gec6818开发板驱动usb摄像头&#xff0c;在这里给大家分享一下。 摄像头的操作步骤 1&#xff09;打开设备 2&#xff09;配置设备&#xff08;采集的频率、图像宽高、图像格式&#xff09; 3&#xff09;在内核空间申请缓冲…

[蓝桥杯2024]-PWN:fd解析(命令符转义,标准输出重定向,利用system(‘$0‘)获取shell权限)

查看保护 查看ida 这里有一次栈溢出&#xff0c;并且题目给了我们system函数。 这里的知识点没有那么复杂 方法一&#xff08;命令转义&#xff09;&#xff1a; 完整exp&#xff1a; from pwn import* pprocess(./pwn) pop_rdi0x400933 info0x601090 system0x400778payloa…

78、贪心-跳跃游戏

思路 方法1: canJump01 - 使用递归&#xff08;回溯法&#xff09; 这个方法是通过递归实现的&#xff0c;它从数组的第一个位置开始&#xff0c;尝试所有可能的跳跃步数&#xff0c;直到达到数组的最后一个位置或遍历完所有的可能性。 思路&#xff1a; 如果数组为空或者长…

【docker】docker compose 搭建私服

安装 Docker Registry 创建目录 mkdir -pv /usr/local/docker/registrymkdir -pv /usr/local/docker/data 创建 docker-compose.yml文件 进入目录创建docker-compose.yml cd /usr/local/docker/registrytouch docker-compose.yml 编辑docker-compose.yml vim docker-compo…

2024年【起重机械安全管理】考试内容及起重机械安全管理操作证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 起重机械安全管理考试内容根据新起重机械安全管理考试大纲要求&#xff0c;安全生产模拟考试一点通将起重机械安全管理模拟考试试题进行汇编&#xff0c;组成一套起重机械安全管理全真模拟考试试题&#xff0c;学员可…