· 5 years ago · Oct 12, 2020, 01:12 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 return maybe_x == x;
55}
56
57
58void singing(const OpenKey &open_key, const SecretKey &secret_key) {
59 // Note: Alice has secret key
60 using namespace boost::multiprecision;
61 using namespace boost::random;
62
63 mt19937 mt;
64
65 auto rand_power_gen = init_random_value_gen(open_key);
66 cpp_int r = rand_power_gen(mt);
67 auto x = pre_signing(open_key, r);
68
69 int bit_count = 72;
70 auto e_gen = init_random_value_gen(bit_count);
71 cpp_int e = e_gen(mt);
72 cpp_int s = sign(open_key, secret_key, r, e);
73 check_sign(open_key, e, x, s);
74
75};
76
77
78int main() {
79 using namespace std;
80 namespace mp = boost::multiprecision;
81
82 mp::cpp_int x = mp::pow(mp::cpp_int(2), 1024);
83 std::cout << x << "\n";
84 cpp_int v = 1;
85
86 // Do some arithmetic:
87 for (unsigned i = 1; i <= 1000; ++i)
88 v *= i;
89
90 std::cout << v << std::endl; // prints 1000! / 10
91
92 cpp_rational w(2, 3); // component wise constructor
93 std::cout << w << std::endl; // prints 2/3
94
95 OpenKey open_key{100, 234, 23452, 15434};
96
97 cout << "";
98 return 0;
99}