-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmc_dlog.cpp
More file actions
132 lines (104 loc) · 3.54 KB
/
mc_dlog.cpp
File metadata and controls
132 lines (104 loc) · 3.54 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
125
126
127
128
129
130
131
132
#include <iostream>
#include <sstream>
#include <ctime>
#include <random>
#include <cmath>
//#include <cstring>
#include "HashTable.h"
using namespace std;
/* Implement mc_dlog in this file */
// function declerations
ulint orderG(ulint, ulint, HashTable&);
ulint discreteLog(ulint, ulint, ulint, HashTable&, HashTable&);
void MC_DLog(ulint, ulint, ulint, HashTable&, HashTable&, HashTable&);
inline ulint modexp(ulint, ulint, ulint);
inline ulint randNum(ulint);
//
int main(int argc, char** argv) {
ulint n, g, a;
if (argc == 4) {
HashTable Ord = HashTable();
HashTable A = HashTable();
HashTable B = HashTable();
n = atoi(argv[1]);
g = atoi(argv[2]);
a = atoi(argv[3]);
cout << "order g" << endl;
cout << orderG(n, g, Ord) << endl;
cout << "\ndiscrete log" << endl;
cout << discreteLog(n, g, a, A, B) << endl;
cout << "\nmc_dlog" << endl;
MC_DLog(n, g, a, Ord, A, B);
}
else
cout << "Number of arguments must be no more or no less than 3." << endl;
return 0;
}
ulint orderG(ulint n, ulint g, HashTable &Ord) {
ulint y, rnd, case_one, case_two;
for (int i = 0; i < sqrt(n); i++) {
rnd = randNum(n-1);
y = modexp(g, rnd, n);
// if the key is found
if (Ord.findKey(y) == true) {
// two cases
case_one = rnd - Ord.hash_function(y); // random minus hashed y
case_two = Ord.hash_function(y) - rnd; // hased y minus random
if (case_one > 0) { // first case greater than 0
return case_one;
}
else if (case_two > 0) { // second case greater than 0
return case_two;
}
else
rnd = Ord.hash_function(y); // set rnd to hashed y
}
else
Ord.insert(y, rnd); // key not found then add to the hash table
}
return n - 1;
}
ulint discreteLog(ulint n, ulint g, ulint a, HashTable &A, HashTable &B) {
ulint y, rnd, rnd_two;
for (ulint i = 0; i < (ulint)sqrt(n); i++) {
rnd = randNum(n-1);
y = a * (modexp(g, rnd, n));
// key is found
if (B.findKey(y) == true)
return (B.hash_function(y) - rnd); // return rand minus hashed y if the key is found in B
else
A.insert(y, rnd); // not found then insert at key y with a random number in A
rnd_two = randNum(n-1); // generate another random number
y = modexp(g, rnd, n);
// key is found
if (A.findKey(y) == true)
return (rnd - A.hash_function(y)); // return rand minus hashed y if the key is found in A
else
B.insert(y, rnd_two); // not found then insert at key y with a random number in A
}
return 0;
}
void MC_DLog(ulint n, ulint g, ulint a, HashTable &Ord, HashTable &A, HashTable &B) {
ulint dLog = discreteLog(n, g, a, A, B);
ulint oG = orderG(n, g, Ord);
ulint result = dLog % oG; // modulus of discrete log and order of g is the result
if (result < 0) { // if the result is less than 0 then add order of g to the result
result += oG;
}
cout << "result: " << result << endl;
}
inline ulint modexp(ulint x, ulint exp, ulint mod_num) {
ulint result = 1;
while ((exp--) > 0) {
result = (result * x) % mod_num;
}
return result;
}
inline ulint randNum(ulint n) {
ulint rnd;
time_t t;
// random number generator depending on the current data and time
srand(time(&t));
rnd = (int)rand() % n;
return rnd;
}