用生日攻击方法求解离散对数问题(C语言实现)-大三密码学实验
实验原理:
生日攻击:输入为生成元a的阶p-1和元b,输出为离散对数。设置两个长度为p的列表:
1)列表1包含,通过随机选取p个k得到;
2)列表2包含,通过随机选取p个l得到;
则在两个列表中很有可能出现重复的项,即,因此,那么就是要找的离散对数。
生日攻击是一个概率算法,无法保证一定能得到输出结果。
实验内容:
a.简单的同余函数的构造
int tongyu(int a,int m,int n){//递归原理 long long int temp=a%n,ans;if(m==1){ans=temp;}else if(m>=2){ans=(temp*tongyu(a,m-1,n))%n;}return ans;
}
原理:(a*b)mod c=((a mod c)*(b mod c))mod c
这里是,m逐步减小,直到1
但是这个顶多m为10000多,再多就不能运行了,而我们如果需要计算很大的m,就需要分解计算
b.对较大数字的拆分
void chaifen(int a,int b[10]){//把a按照万,千,百,十,个位上的数字区分开来,便于计算 int i,temp=10000;for(i=0;i<5;i++){b[i]=a/temp;a=a%temp;temp/=10;}
}
数组b是用来储存a的万位,千位,百位,十位,个位上的值
类似于水仙花数的处理
c.求a的10000,1000,100,10,1的次方的mod p
void qiu_cd(int c1[10],int a,int p){int temp=10000;for(int i=0;i<5;i++)//求对于a的10000,1000等次方对于p的求余 {c1[i]=tongyu(a,temp,p);temp/=10;}}
d.对a的万位,千位,百位,十位,个位的值的次方分别求余
void cheng(int p,int c1[10],int c11[10],int c111[10]){//各位上的数字的求余 for(int i=0;i<5;i++){if(c11[i]>0){c111[i]=tongyu(c1[i],c11[i],p);}else{c111[i]=0;}}
}
如果c11[i]=0,直接置0,否则就用用到tongyu函数,(a*b)mod c=((a mod c)*(b mod c))mod c
e.对a各个位的值整合起来
long long int result_c(int a, int c1[10],int p,int c11[10],int c111[10]){//输出列表的值 long long int temp=1; chaifen(a,c11);cheng(p,c1,c11,c111);for(int j=0;j<5;j++){//万位到个位上的求余结合起来 if(c111[j]!=0){temp=((temp%p)*(c111[j]%p))%p; }}return temp;
}
也是利用那个公式(a*b)mod c=((a mod c)*(b mod c))mod c
但是c111[j]=0不能带进去,因为会使得一个乘数为0,整体为0
f.构造列表并比较
void bijiao(int p,int a, int b,int p1,long long int c[15000][2],unsigned long long int ans,long long int d[15000][2],int c1[10],int c11[10],int c111[10],int count){int flag=0;for(int i=0;i<p1;i++){//求第一个列表 c[i][0] = 1+ rand() % (p-2);c[i][1] = result_c(c[i][0],c1,p,c11,c111);}for(int i=0;i<p1;i++){//求第二个列表 d[i][0] = 1+ rand() % (p-2);ans=result_c(d[i][0],c1,p,c11,c111);ans=((b%p)*ans)%p;d[i][1]=ans;}for(int i=0;i<p1;i++){ for(int j=0;j<p1;j++){if(c[i][1]==d[j][1]){//如果找到 cout<<"能找到离散对数x="<<c[i][0]-d[j][0]<<"(mod "<<p-1<<")"; flag=1;break;}}if(flag==1){//如果找到了,跳出循环 break;}}count++;if(count>10){//超过十轮,还是没找到 cout<<"找不到";flag=1;}if(flag==0){bijiao(p,a,b,p1,c,ans,d,c1,c11,c111,count);}
}
rand是随机数,rand()%(b),表明随机生成0-b之间的数字
两个for循环找相同值,找不到继续找,进入下一轮,再次调用bijiao函数,如果找了十轮还没找到,就说明真的很难找,建议不找,找到了通过flag跳出两个for循环。
g.总函数
#include<iostream>
#include<stdlib.h>
#include<time.h>
#include<math.h>
using namespace std;
int tongyu(int a,int m,int n){//递归原理 long long int temp=a%n,ans;if(m==1){ans=temp;}else if(m>=2){ans=(temp*tongyu(a,m-1,n))%n;}return ans;
}void cheng(int p,int c1[10],int c11[10],int c111[10]){//各位上的数字的求余 for(int i=0;i<5;i++){if(c11[i]>0){c111[i]=tongyu(c1[i],c11[i],p);}else{c111[i]=0;}}
}void chaifen(int a,int b[10]){//把a按照万,千,百,十,个位上的数字区分开来,便于计算 int i,temp=10000;for(i=0;i<5;i++){b[i]=a/temp;a=a%temp;temp/=10;}
}void qiu_cd(int c1[10],int a,int p){int temp=10000;for(int i=0;i<5;i++)//求对于a的10000,1000等次方对于p的求余 {c1[i]=tongyu(a,temp,p);temp/=10;}}long long int result_c(int a, int c1[10],int p,int c11[10],int c111[10]){//输出列表的值 long long int temp=1; chaifen(a,c11);cheng(p,c1,c11,c111);for(int j=0;j<5;j++){//万位到个位上的求余结合起来 if(c111[j]!=0){temp=((temp%p)*(c111[j]%p))%p; }}return temp;
}
void bijiao(int p,int a, int b,int p1,long long int c[15000][2],unsigned long long int ans,long long int d[15000][2],int c1[10],int c11[10],int c111[10],int count){int flag=0;for(int i=0;i<p1;i++){//求第一个列表 c[i][0] = 1+ rand() % (p-2);c[i][1] = result_c(c[i][0],c1,p,c11,c111);}for(int i=0;i<p1;i++){//求第二个列表 d[i][0] = 1+ rand() % (p-2);ans=result_c(d[i][0],c1,p,c11,c111);ans=((b%p)*ans)%p;d[i][1]=ans;}for(int i=0;i<p1;i++){ for(int j=0;j<p1;j++){if(c[i][1]==d[j][1]){//如果找到 cout<<"能找到离散对数x="<<c[i][0]-d[j][0]<<"(mod "<<p-1<<")"; flag=1;break;}}if(flag==1){//如果找到了,跳出循环 break;}}count++;if(count>10){//超过十轮,还是没找到 cout<<"找不到";flag=1;}if(flag==0){bijiao(p,a,b,p1,c,ans,d,c1,c11,c111,count);}
}
int main(){int a,b,p,p1,count=0;unsigned long long int ans=0;//p1为p的开方,ans中间值,count为轮数 long long int c[15000][2],d[15000][2];//c,d为两个列表 int c1[10],c11[10],c111[10];//c1为求a的10000等对p的余,c11为随机数的各个位上的数,c111为各个位上余数的集合 cout<<"输入三个数:";cin>>a>>b>>p;p1=int(sqrt(p));//求关于p的开方 qiu_cd(c1,a,p);//求c1 bijiao(p,a,b,p1,c,ans,d,c1,c11,c111,count);return 0;
}
h.测试结果
用生日攻击方法求解离散对数问题(C语言实现)-大三密码学实验相关推荐
- DES的加密解密在ECB上的使用(C语言实现)——大三密码学实验
目录 实验内容 实验原理 DES加密解密 ECB(电码本模式) 代码 DES函数的构建 RE_DES函数的构建 ECB函数的构建 RE_ECB的函数的构建 主函数的构建 总代码 测试结果 实验内容 输 ...
- 银行家算法C语言实现(大三操作系统实验)
实验原理: 1.银行家算法 银行家算法最初级为银行系统设计,以确保银行在发放现金贷款时,不会发生不能满足所有客户需要的情况.在OS设计中,用它来避免死锁. 为实现银行家算法,每个新进程在进入系统时它必 ...
- R语言入门第三集 实验二:基本数据处理
R语言入门第三集 实验二:基本数据处理 一.资源 [R语言]R语言数据处理--东北大学大数据班R实训第二次作业 二.答案更新纠正 2.11.从df中选取date . item_id . cate_id ...
- c语言程序设计编程解读,C语言程序设计第三次实验报告解读
<C语言程序设计第三次实验报告解读>由会员分享,可在线阅读,更多相关<C语言程序设计第三次实验报告解读(15页珍藏版)>请在人人文库网上搜索. 1.C语言程序设计实验报告专业 ...
- 数据结构c语言版第三版实验四答案,数据结构(C语言版)第三四章习题答案
Push( &s, t[i]); while( !EmptyStack( &s)) {// 每弹出一个字符与相应字符比较 temp=Pop (&s); if( temp!=S[ ...
- c语言编程非线性方程求解,c语言计算机编程三种方法求解非线性方程
c语言计算机编程三种方法求解非线性方程 本 科 专 业 学 年 论 文题 目:非线性方程求解比较姓 名: 何 娟 专 业: 计算机科学技术系 班 级: 08 级本科(2)班 指 导 老 师: 刘 晓 ...
- c语言编程非线性方程求解,c语言计算机编程三种方法求解非线性方程.doc
c语言计算机编程三种方法求解非线性方程.doc 本 科 专 业 学 年 论 文题 目非线性方程求解比较姓 名 何 娟 专 业 计算机科学技术系 班 级 08 级本科(2)班 指 导 老 师 刘 晓 娜 ...
- 求解欧拉方程的c语言,用有限体积方法求解欧拉方程
<用有限体积方法求解欧拉方程>由会员分享,可在线阅读,更多相关<用有限体积方法求解欧拉方程(12页珍藏版)>请在人人文库网上搜索. 1.有限体积法求解二维可压缩Euler方程计 ...
- c语言迷宫游戏怎么存放坐标,求解迷宫问题(c语言,很详细哦
<求解迷宫问题(c语言,很详细哦>由会员分享,可在线阅读,更多相关<求解迷宫问题(c语言,很详细哦(5页珍藏版)>请在人人文库网上搜索. 1.求迷宫问题就是求出从入口到出口的路 ...
最新文章
- 佛弟子有三样东西需要永远保密!
- ubuntu服务器python3.6报错ModuleNotFoundError: No module named '_bz2'
- 1.窗体与界面设计-菜单应用实例
- SqlServer查询出数据库中所有的表及其字段属性
- H5-表格的基本样式
- 最新版网站推广完全手册(2007年)!
- ThreeJS自带网格线
- 远程服务器挂机好吗,什么服务器挂机好
- 【Android 2D 游戏开发(5)】——九宫格拼图(苍老师版)
- 电力系统机组调度 考虑了源荷不确定性 考虑源荷两侧不确定性的含风电的低碳调度,引入模糊机会约束,程序包括储能、风光、火电机组及水电机组
- 防疫与复工同行,长沙望城进入“双统筹”的关键时刻
- medusa破解ssh
- 计算机毕业设计springboot+vue+elementUI股票交易模拟系统
- B2B不是难事情之EDI协议简介
- MAC 输入摄氏度小技巧
- 需要计算机安装msxml,Win7安装Office2010提示让安装MSXML组件的五种解决方法
- 全志A31编译环境搭建
- 你的Qt按钮可以加载Gif圆形的头像吗?
- jvm内存结构和内存模型
- 大周手把手教你,用手机获取视频剪辑素材,做短视频事半功倍