· 5 years ago · Oct 12, 2020, 02:20 PM
1#include <boost/multiprecision/cpp_int.hpp>
2#include <boost/random.hpp>
3#include <iostream>
4
5
6using namespace boost::multiprecision;
7
8
9struct OpenKey {
10 cpp_int p; // usually 1024 bits (prime!)
11 cpp_int q; // usually 160 bits; (p - 1) % q == 0
12 // w < q
13 cpp_int g; // (g^q) % p == 1
14 cpp_int y; // y = g^(-w) % p
15};
16
17struct SecretKey {
18 cpp_int w;
19};
20
21
22auto init_random_value_gen(const OpenKey &open_key) {
23 using namespace boost::random;
24 return uniform_int_distribution<cpp_int>(0, open_key.q);
25}
26
27
28cpp_int pre_signing(const OpenKey &open_key, const cpp_int &rand_power) {
29 namespace mp = boost::multiprecision;
30 return mp::powm(open_key.g, rand_power, open_key.p);
31}
32
33
34template<typename T>
35auto init_random_value_gen(T bits_count) {
36 // multiprecision do not allow cpp_int as exponent, because https://stackoverflow.com/a/43508036
37 using namespace boost::random;
38 namespace mp = boost::multiprecision;
39 const cpp_int &base = 2;
40 return uniform_int_distribution<cpp_int>(0, mp::pow(base, bits_count) - 1);
41}
42
43cpp_int sign(const OpenKey &open_key, const SecretKey &secret_key, const cpp_int &r, const cpp_int &e) {
44 return (r + e * secret_key.w) % open_key.q;
45}
46
47bool check_sign(const OpenKey &open_key, const cpp_int &e, const cpp_int &x, const cpp_int &s) {
48 namespace mp = boost::multiprecision;
49 using namespace std;
50
51 auto maybe_x = (
52 mp::powm(open_key.g, s, open_key.p) * mp::powm(open_key.y, e, open_key.p)
53 ) % open_key.p;
54 cpp_int v = mp::powm(open_key.g, s, open_key.p);
55 // return maybe_x == x;
56 cout << "e: " << typeid(e).name() << endl;
57 cout << "x: " << typeid(x).name() << endl;
58 cout << "s: " << typeid(s).name() << endl;
59 cout << "maybe_x: " << typeid(maybe_x).name() << endl;
60 cout << "v: " << typeid(maybe_x).name() << endl;
61
62
63 return true;
64}
65
66
67bool singing(const OpenKey &open_key, const SecretKey &secret_key) {
68 // Note: Alice has secret key
69 using namespace boost::multiprecision;
70 using namespace boost::random;
71
72 mt19937 mt;
73
74 auto rand_power_gen = init_random_value_gen(open_key);
75 cpp_int r = rand_power_gen(mt);
76 cpp_int x = pre_signing(open_key, r);
77
78 int bit_count = 72;
79 auto e_gen = init_random_value_gen(bit_count);
80 cpp_int e = e_gen(mt);
81 cpp_int s = sign(open_key, secret_key, r, e);
82 return check_sign(open_key, e, x, s);
83};
84
85
86int main() {
87 using namespace std;
88 namespace mp = boost::multiprecision;
89
90
91 OpenKey open_key{48731, 443, 11444, 7355};
92 SecretKey secret_key{357};
93
94 cout << singing(open_key, secret_key) << endl;
95
96 cout << "";
97 return 0;
98}