forked from gao27024037/Encryption
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDSS.h
More file actions
124 lines (113 loc) · 2.87 KB
/
DSS.h
File metadata and controls
124 lines (113 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#ifndef DSS_H
#define DSS_H
#include <string>
#include <iostream>
#include <cmath>
using namespace std;
class DSS
{
public:
unsigned __int64 x; //私钥
unsigned __int64 y; //公钥
unsigned __int64 r; //数字签名(r,s)
unsigned __int64 s;
string sig;
DSS() {
}
DSS(unsigned __int64 xy, string sigg) {
x = y = xy;
sig = sigg;
}
void signature(string message) {
//签名
srand(time(0));
hash<std::string> h;
unsigned __int64 k = rand() % q; //k为随机数 0<k<q
r = PowMod(g, k, p) % q;
s = mod_reverse(k, q)*((h(message) + x*r) % q) % q;
//r*1000+s 存入字符串sig
int str = r * 1000 + s;
char cnum[7];
sprintf_s(cnum, "%d", str);
sig = cnum;
while (sig.size() < 6) //若不够6位则在前面补0
{
sig = "0" + sig;
}
}
void verify(string message) {
//从sig里获取(x,s)
char cnum[7];
int str;
strcpy(cnum, sig.substr(0, 6).c_str());
sscanf(cnum, "%d", &str);
r = str / 1000;
s = str % 1000;
//验证
hash<std::string> h;
unsigned __int64 w = mod_reverse(s,q);
unsigned __int64 u1 = h(message) * w % q;
unsigned __int64 u2 = r * w % q;
unsigned __int64 v = (PowMod(g, u1, p)*PowMod(y, u2, p) % p) % q; //用了a*b % n = (a % n)*(b % n) % n
if (v == r) {
cout << "ture" << endl;
}
else
{
cout << "false" << endl;
}
}
//产生私钥x和公钥y
void generateKey() {
//0 < x < q;
srand(time(0));
x = rand() % q;
y = PowMod(g, x, p); //x为75时y为4567
cout << "私钥:" << x << endl;
cout << "公钥:" << y << endl;
}
private:
unsigned __int64 q = 101;
unsigned __int64 p = q * 78 + 1; // p = 7879
unsigned __int64 pMinus1Divideq = 78; // (p - 1) / q
unsigned __int64 h = 3;
unsigned __int64 g = PowMod(h, pMinus1Divideq, p); // g = 170
//模乘运算,返回值 x=a*b mod n
inline unsigned __int64 MulMod(unsigned __int64 a, unsigned __int64 b, unsigned __int64 n)
{
return a * b % n;
}
//模幂运算,返回值 x=base^pow mod n
unsigned __int64 PowMod(unsigned __int64 &base, unsigned __int64 &pow, unsigned __int64 &n)
{
unsigned __int64 a = base, b = pow, c = 1;
while (b)
{
while (!(b & 1))
{
b >>= 1; //a=a * a % n; //函数看起来可以处理64位的整数,但由于这里a*a在a>=2^32时已经造成了溢出,因此实际处理范围没有64位
a = MulMod(a, a, n);
} b--; //c=a * c % n; //这里也会溢出,若把64位整数拆为两个32位整数不知是否可以解决这个问题。
c = MulMod(a, c, n);
} return c;
}
//返回d=gcd(a,b);和对应于等式ax+by=d中的x,y
long long extend_gcd(long long a, long long b, long long &x, long long &y) {
if (a == 0 && b == 0) return -1;//无最大公约数
if (b == 0) {
x = 1; y = 0; return a;
}
long long d = extend_gcd(b, a%b, y, x);
y -= a / b*x;
return d;
}
//ax = 1(mod n) 求X 即: 求 1 / a % n
long long mod_reverse(long long a, long long n) {
long long x, y;
long long d = extend_gcd(a, n, x, y);
if (d == 1)
return (x%n + n) % n;
else return -1;
}
};
#endif