Rabin数字签名 Lamport 一次签名
2015-11-08 19:36
197 查看
Rabin数字签名 代码:
Lamport 一次签名:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> #include<iostream> #include<string.h> #include<math.h> #include<algorithm> #include<random> using namespace std; const int S = 10; long long mult_mod(long long a, long long b, long long c) { a %= c; b %= c; long long ret = 0; while (b) { if (b & 1) { ret += a; ret %= c; } a <<= 1; if (a >= c)a %= c; b >>= 1; } return ret; } //计算 ret = x^n %c long long pow_mod(long long x, long long n, long long mod)//x^n%c { if (n == 1)return x%mod; x %= mod; long long tmp = x; long long ret = 1; while (n) { if (n & 1) ret = mult_mod(ret, tmp, mod); tmp = mult_mod(tmp, tmp, mod); n >>= 1; } return ret; } bool check(long long a, long long n, long long x, long long t) { long long ret = pow_mod(a, x, n); long long last = ret; for (int i = 1; i <= t; i++) { ret = mult_mod(ret, ret, n); if (ret == 1 && last != 1 && last != n - 1) return true;//合数 last = ret; } if (ret != 1) return true; return false; } bool Miller_Rabin(long long n)//Miller_Rabin算法判断素数 { if (n<2)return false; if (n == 2)return true; if ((n & 1) == 0) return false;//偶数 long long x = n - 1; long long t = 0; while ((x & 1) == 0) { x >>= 1; t++; } for (int i = 0; i<S; i++) { long long a = rand() % (n - 1) + 1; if (check(a, n, x, t)) return false;//合数 } return true; } long long gcd(long long a, long long b) { if (a == 0)return 1; if (a<0) return gcd(-a, b); while (b) { long long t = a%b; a = b; b = t; } return a; } bool Legendre(int a, int p) { int tmp = pow(a, (p - 1) / 2); if (tmp % p == 1) return true; else return false; } int main() { cout << "*******************************************" << endl; cout << "测试数据假定 p = 7 q = 11 ,进行签名和验证" << endl; cout << "*******************************************" << endl << endl << endl; static uniform_int_distribution<unsigned> u(1000000, 1000000000); static default_random_engine e(time(0)); long long p = 6, q = 6; //随机产生素数p q while (!Miller_Rabin(p)) p = u(e); while (!Miller_Rabin(q)) q = u(e); //cout << p << " " << q << endl; long long n = p*q; cout << "素数p,q生成完毕!" << endl; p = 7; q = 11; //签名生成 cout << "请输入 m 进行签名:" << endl; long long m; cin >> m; if (!(Legendre(m, p) && Legendre(m, q))) { while (!(Legendre(m, p) && Legendre(m, q))) m = m - 1; } long long s = ((long long)sqrt(m)) % n; //签名验证 cout << "请输入s进行签名验证:" << endl; int ss; cin >> ss; if (m == ss*ss%n) cout << "true 验证成功!" << endl; else cout << "false 验证失败!" << endl; return 0; }
Lamport 一次签名:
#include <iostream> #include <stdio.h> #include <cmath> #include <string> using namespace std; int quickpow(int m, int n, int k) { int b = 1; while (n > 0) { if (n & 1) b = (b*m) % k; n = n >> 1; m = (m*m) % k; } return b; } int main() { int n, MOD; cin >> n >> MOD; int y10, y11, y20, y21, y30, y31; cin>>y10>>y11>>y20>>y21>>y30>>y31; int z10, z11, z20, z21, z30, z31; // z10 = quickpow(n, y10, MOD); z11 = quickpow(n, y11, MOD); z20 = quickpow(n, y20, MOD); z21 = quickpow(n, y21, MOD); z30 = quickpow(n, y30, MOD); z31 = quickpow(n, y31, MOD); // string cl; cin >> cl; int len = cl.size(); int Sign[100]; if (cl[0] == '0') Sign[0] = y30; else Sign[0] = y31; if (cl[1] == '0') Sign[1] = y20; else Sign[1] = y21; if (cl[2] == '0') Sign[2] = y10; else Sign[2] = y11; int Sign_ans[100]; for (int i = 0; i < 3; i++) { Sign_ans[i] = quickpow(n, Sign[2-i],MOD); cout << Sign_ans[i] << endl; } return 0; }
相关文章推荐
- Android选项切换条SHSegmentControl
- u-boot加载Linux过程
- XAMPP-1.8.3上部署老的mediawiki-1.21.2遇到错误
- MySQL学习笔记(1)之MySQL简介
- MySQL导入sql文件
- C++ 中使用dlopen加载动态库
- 图片替换文本
- Spring 集成 Mybatis
- 对于牛老师作业陈老师作业补充(老陈,小石头的典型用户、用例图、场景)
- Android AIDL进程间通信(IPC)
- [置顶] Android layout_weight 理解
- 核心动画的使用-King
- d3 之deal with data
- java继承课后作业
- Hdoj 1317 XYZZY
- Spark GraphX(一)
- 软件工程师考试总结
- C#语言 数组
- H5性能调优
- 黑马程序员——OC学习笔记 类的进阶使用