Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit bc5a308

Browse files
committedJul 29, 2018
first commit
1 parent d0cc326 commit bc5a308

File tree

4 files changed

+478
-0
lines changed

4 files changed

+478
-0
lines changed
 

‎Makefile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
CPP = g++ -g
2+
CFLAGS = -std=gnu++11 -D_XOPEN_SOURCE=700 -Wall -Werror -pedantic
3+
4+
.PHONY: all clean
5+
6+
all: clean logauth logveri
7+
clean:
8+
rm -f output.txt firstkey.dat logauth logauth.o logveri logveri.o
9+
10+
logveri: logveri.o
11+
$(CPP) -o $@ $^ -lcryptopp
12+
13+
logveri.o: logveri.cpp
14+
$(CPP) -c $(CFLAGS) $^
15+
16+
logauth: logauth.o logauth.h
17+
$(CPP) -o $@ $< -lcryptopp
18+
19+
logauth.o: logauth.cpp
20+
$(CPP) -c $(CFLAGS) $^

‎logauth.cpp

+262
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
#include <iostream>
2+
#include <fstream>
3+
#include <cstring>
4+
#include <unistd.h>
5+
#include <ctime>
6+
#include <algorithm>
7+
8+
#include "logauth.h"
9+
#include "cryptopp/hex.h"
10+
#include "cryptopp/integer.h"
11+
#include "cryptopp/dsa.h"
12+
#include "cryptopp/osrng.h"
13+
#include "cryptopp/files.h"
14+
15+
#ifndef A
16+
#define A 4
17+
#endif
18+
19+
#ifndef B
20+
#define B 4096
21+
#endif
22+
23+
#ifndef C
24+
#define C 2048
25+
#endif
26+
27+
#ifndef N
28+
#define N 4097
29+
#endif
30+
31+
using std::string;
32+
using std::ofstream;
33+
using std::ifstream;
34+
using std::time;
35+
using namespace CryptoPP;
36+
37+
static string oldLine = "";
38+
static struct timespec oldTime;
39+
40+
static AutoSeededRandomPool rng;
41+
static DSA::PublicKey pubA;
42+
static DSA::PrivateKey privA;
43+
44+
45+
// This method tries to retrieve the next event.
46+
// When implemented correct, it should return an pointer to an event OR NULL when no event happened.
47+
// Here with 'new' we allocate memory, so it has to be freed later.
48+
49+
// static event* getNextEvent(){
50+
// string line = "a simple mock event";
51+
// return new event(line);
52+
// }
53+
54+
/* This method computes the Authenticator (signature) on some elements of buffer.
55+
*/
56+
static string computeAuth(string buffer[], int start, int end){
57+
string concatString;
58+
for (int i = start; i <= end; ++i){
59+
concatString += buffer[i];
60+
}
61+
string signature;
62+
DSA::Signer signer(privA);
63+
StringSource ss1(concatString, true,
64+
new SignerFilter(rng, signer,
65+
new HexEncoder(new StringSink(signature))
66+
)
67+
);
68+
return signature;
69+
}
70+
71+
/* This method is used to signal that a timeout has happened.
72+
I am unsure whether this will be final as a method or if we find a better implementation.
73+
*/
74+
static bool timeout(){
75+
struct timespec newTime;
76+
clock_gettime(CLOCK_MONOTONIC, &newTime);
77+
78+
if(newTime.tv_sec - oldTime.tv_sec >= 2.0){ // every two seconds a timeout occurs
79+
oldTime = newTime;
80+
return true;
81+
}
82+
else{
83+
return false;
84+
}
85+
}
86+
87+
88+
89+
int main(int argc, char** argv){
90+
struct timespec start;
91+
struct timespec finish, globalstart;
92+
double elapsed;
93+
94+
//get start times for measurements
95+
clock_gettime(CLOCK_MONOTONIC, &start);
96+
clock_gettime(CLOCK_MONOTONIC, &globalstart);
97+
98+
int j;
99+
const int a = A;
100+
const int b = B;
101+
const int c = C;
102+
103+
ofstream Log;
104+
EVENT* currentEvent;
105+
106+
string buffer[b];
107+
string abuffer[(int) b/a];
108+
string vbuffer[(int)b/c];
109+
string vbuffer2[(int)b/c];
110+
111+
// Generate Private Key
112+
privA.GenerateRandomWithKeySize(rng, 2048);
113+
114+
// Generate Public Key
115+
pubA.AssignFrom(privA);
116+
if (!privA.Validate(rng, 3) || !pubA.Validate(rng, 3)){
117+
throw std::runtime_error("DSA key generation failed");
118+
}
119+
120+
//write first public key to a file
121+
{
122+
FileSink ouput("firstkey.dat");
123+
pubA.DEREncode(ouput);
124+
}
125+
126+
//used to track whether one of the main events was already handled
127+
int oldJa = 0;
128+
int oldJb = 0;
129+
int oldJc = 0;
130+
131+
//empty all buffers beforehand
132+
std::fill(buffer,buffer+b,"");
133+
std::fill(abuffer,abuffer+b/a,"");
134+
std::fill(vbuffer,vbuffer+b/c,"");
135+
std::fill(vbuffer2,vbuffer+b/c,"");
136+
137+
j = 0;
138+
139+
// used to measure the time it takes to initialize the program
140+
clock_gettime(CLOCK_MONOTONIC, &finish);
141+
elapsed = (finish.tv_sec - start.tv_sec);
142+
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;
143+
std::cout << elapsed << std::endl;
144+
145+
//used to measure the time it takes to handle one block of size b
146+
clock_gettime(CLOCK_MONOTONIC, &start);
147+
148+
// the main loop
149+
// the order in which the following if clauses are, is CRUCIAL
150+
while(j<N){
151+
if ((j % a) == 0 && j != oldJa){
152+
string Z = computeAuth(buffer,((j-a) % b), ((j-1) % b) );
153+
abuffer[(int)(((j-1)%b)/a)] = Z;
154+
oldJa = j;
155+
}
156+
157+
if((j % c) == 0 && j != 0 && j != oldJc){
158+
// Generate Private Key
159+
DSA::PrivateKey privateKey;
160+
privateKey.GenerateRandomWithKeySize(rng, 2048);
161+
162+
// Generate Public Key
163+
DSA::PublicKey publicKey;
164+
publicKey.AssignFrom(privateKey);
165+
if (!privateKey.Validate(rng, 3) || !publicKey.Validate(rng, 3)){
166+
throw std::runtime_error("DSA key generation failed");
167+
}
168+
169+
//generate encoded public key
170+
string encodedPubKey;
171+
publicKey.Save(HexEncoder(
172+
new StringSink(encodedPubKey)).Ref()
173+
);
174+
175+
//generate encoded signature of encoded public key
176+
string signature;
177+
DSA::Signer signer(privA);
178+
StringSource ss1(encodedPubKey, true,
179+
new SignerFilter(rng, signer,
180+
new HexEncoder(new StringSink(signature))
181+
)
182+
);
183+
184+
//overwrite keys and store the new key and signature in vbuffers
185+
privA = privateKey;
186+
pubA = publicKey;
187+
vbuffer[(((j-1) % b)/c)] = signature;
188+
vbuffer2[(((j-1) % b)/c)] = encodedPubKey;
189+
oldJc = j;
190+
}
191+
192+
if ((j % b) == 0 && j != 0 && j != oldJb){
193+
//used to measure the time it takes to handle one block of size b
194+
clock_gettime(CLOCK_MONOTONIC, &finish);
195+
elapsed = (finish.tv_sec - start.tv_sec);
196+
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;
197+
std::cout << elapsed << std::endl;
198+
199+
Log.open("output.txt", std::ofstream::out | std::ofstream::app);
200+
Log << "##### j is now " << j << " #############################################" << std::endl;
201+
Log << "The content of buffer:" << std::endl;
202+
for (int i = 0; i< b; i++){
203+
Log << buffer[i] << std::endl;
204+
}
205+
Log << "The content of abuffer:" << std::endl;
206+
for (int i = 0; i< (int)b/a; i++){
207+
Log <<abuffer[i] << std::endl;
208+
}
209+
Log << "The content of vbuffer:" << std::endl;
210+
for (int i = 0; i< (int)b/c; i++){
211+
Log << vbuffer[i] << std::endl;
212+
}
213+
Log << "The content of vbuffer2:" << std::endl;
214+
for (int i = 0; i< (int)b/c; i++){
215+
Log << vbuffer2[i] << std::endl;
216+
}
217+
Log.close();
218+
219+
std::fill(buffer,buffer+b,"");
220+
std::fill(abuffer,abuffer+b/a,"");
221+
std::fill(vbuffer,vbuffer+b/c,"");
222+
std::fill(vbuffer2,vbuffer2+b/c,"");
223+
oldJb = j;
224+
225+
//initialize time for measuring a block b
226+
clock_gettime(CLOCK_MONOTONIC, &start);
227+
}
228+
229+
if(timeout()){// if timeout then write metronome message with current time
230+
string output;
231+
char buf[27];
232+
struct timespec ts;
233+
clock_gettime(CLOCK_REALTIME, &ts);
234+
ctime_r(&ts.tv_sec, buf);
235+
output = buf;
236+
output.erase(std::remove(output.begin(), output.end(), '\n'), output.end());
237+
buffer[(j % b)] = output;
238+
j++;
239+
}
240+
else{
241+
currentEvent = getNextEvent();
242+
if(currentEvent){
243+
string l = currentEvent->getLog();
244+
buffer[(j % b)] = l;
245+
j++;
246+
delete currentEvent;
247+
}
248+
else{
249+
sleep(1);
250+
}
251+
}
252+
}
253+
254+
// used to measure the time it takes to execute the whole program
255+
clock_gettime(CLOCK_MONOTONIC, &finish);
256+
elapsed = (finish.tv_sec - globalstart.tv_sec);
257+
elapsed += (finish.tv_nsec - globalstart.tv_nsec) / 1000000000.0;
258+
std::cout << elapsed << std::endl;
259+
260+
exit(EXIT_SUCCESS);
261+
}
262+

‎logauth.h

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* @file logauth.h
3+
* @brief
4+
*
5+
* bla
6+
*/
7+
8+
#ifndef LOGAUTH_H
9+
#define LOGAUTH_H
10+
11+
/* This is the event class.
12+
Events are Objects with a log message.
13+
*/
14+
class EVENT{
15+
public:
16+
std::string log;
17+
18+
EVENT(std::string l){
19+
log = l;
20+
}
21+
std::string getLog(){
22+
return log;
23+
}
24+
};
25+
26+
27+
/* This method tries to retrieve the next event.
28+
When implemented correct, it should return an pointer to an event OR NULL when no event happened.
29+
Here with 'new' we allocate memory, so it has to be freed later.
30+
*/
31+
static EVENT* getNextEvent(){
32+
std::string line = "a simple mock event";
33+
return new EVENT(line);
34+
}
35+
36+
37+
#endif /* LOGAUTH_H */

‎logveri.cpp

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
#include "cryptopp/integer.h"
2+
#include "cryptopp/dsa.h"
3+
#include "cryptopp/osrng.h"
4+
#include "cryptopp/files.h"
5+
#include "cryptopp/cryptlib.h"
6+
#include "cryptopp/filters.h"
7+
#include "cryptopp/hex.h"
8+
#include "cryptopp/integer.h"
9+
#include <fstream>
10+
#include <iostream>
11+
#include <unistd.h>
12+
13+
14+
15+
int main(int argc, char** argv) {
16+
using namespace CryptoPP;
17+
using std::string;
18+
19+
// load first Key from file,
20+
// Key is DER Encoded
21+
DSA::PublicKey publicKey;
22+
{
23+
FileSource input("firstkey.dat", true);
24+
publicKey.BERDecode(input);
25+
}
26+
27+
28+
int blockNumber = 1;
29+
int a = atoi(argv[1]);
30+
int b = atoi(argv[2]);
31+
int c = atoi(argv[3]);
32+
const int leng = 5+b+(b/a)+(2*(b/c));
33+
std::ifstream input("output.txt");
34+
35+
36+
while(!input.eof()){
37+
int readLines = 0;
38+
std::vector<string> lines;
39+
40+
//read one block
41+
while(readLines < leng){
42+
string line;
43+
if(std::getline(input, line)){
44+
lines.push_back(line);
45+
readLines++;
46+
}
47+
else{ // no line read
48+
std::cout << "Verified until logmessage nr. " << (blockNumber-1)*b<< std::endl;
49+
exit(EXIT_SUCCESS);
50+
}
51+
}
52+
53+
// now: process the block
54+
std::cout << "=============> Message Block: " << blockNumber << std::endl;
55+
56+
// read plaintext messages and concatenate
57+
std::vector<string> messages;
58+
string tmp;
59+
for (int i = 1; i <= b; ++i){
60+
string concat = tmp + lines.at(1+i) ;
61+
tmp = concat;
62+
if (i % a == 0){
63+
messages.push_back(tmp);
64+
tmp.clear();
65+
}
66+
}
67+
68+
// read signatures of message blocks
69+
std::vector<std::string> auths;
70+
for (int i = 0; i <b/a; ++i){
71+
std::string atmp = lines.at(b+3+i);
72+
auths.push_back(atmp);
73+
}
74+
75+
// read signatures of new public keys
76+
std::vector<std::string> signedKeys;
77+
for (int i = 0; i <b/c; ++i){
78+
std::string ctmp = lines.at(b+4+b/a+i);
79+
signedKeys.push_back(ctmp);
80+
}
81+
82+
// read new public keys
83+
std::vector<std::string> unsignedKeys;
84+
for (int i = 0; i <b/c; ++i){
85+
std::string cctmp = lines.at(b+5+b/a+b/c+i);
86+
unsignedKeys.push_back(cctmp);
87+
}
88+
89+
90+
for (int i = 0; i < b/c; ++i){
91+
// verify blocks of messages until a new key has to be used
92+
for (int j = i*(c/a); j < i*(c/a)+(c/a); ++j){
93+
string message = messages.at(j);
94+
string signature = auths.at(j);
95+
96+
string decodedSignature;
97+
StringSource ss2(signature, true,
98+
new HexDecoder(
99+
new StringSink(decodedSignature)
100+
)
101+
);
102+
103+
DSA::Verifier verifier(publicKey);
104+
bool result = false;
105+
StringSource ss3(decodedSignature+message, true,
106+
new SignatureVerificationFilter(
107+
verifier, new ArraySink((byte*)&result, sizeof(result))
108+
)
109+
);
110+
111+
std::cout << "Verirfying signature of authenticaction block " << (blockNumber-1)*(b/a)+j+1 << std::endl;
112+
if(result){
113+
std::cout << " -> Auth verified" << std::endl;
114+
}
115+
else{
116+
std::cout << " -> Auth NOT verified, messages authentic until block " << ((blockNumber-1)*(b/a)+j)<< std::endl;
117+
exit(EXIT_FAILURE);
118+
}
119+
120+
}
121+
122+
// after b/c many messages update/verify new key
123+
string signedKey = signedKeys.at(i);
124+
string unsignedKey = unsignedKeys.at(i);
125+
126+
string decodedSignature;
127+
StringSource ss0(signedKey, true,
128+
new HexDecoder(
129+
new StringSink(decodedSignature)
130+
)
131+
);
132+
133+
DSA::Verifier verifier(publicKey);
134+
bool result = false;
135+
StringSource ss3(decodedSignature+unsignedKey, true,
136+
new SignatureVerificationFilter(
137+
verifier, new ArraySink((byte*)&result, sizeof(result))
138+
)
139+
);
140+
std::cout << "" << std::endl;
141+
std::cout << "Verirfying new Public Key " << (blockNumber-1)*b/c+i+1 << std::endl;
142+
if (result){
143+
std::cout << " -> Key verified" << std::endl;
144+
std::cout << "" << std::endl;
145+
DSA::PublicKey newkey;
146+
newkey.Load(StringSource(unsignedKey, true,
147+
new HexDecoder()).Ref());
148+
publicKey = newkey;
149+
}
150+
else{
151+
std::cout << " ->Key NOT verified, messages authentic until message " << (blockNumber-1)*b+c*(i+1)<< std::endl;
152+
exit(EXIT_FAILURE);
153+
}
154+
155+
}
156+
blockNumber++;
157+
}
158+
return 0;
159+
}

0 commit comments

Comments
 (0)
Please sign in to comment.