-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTransaction.hpp
143 lines (113 loc) · 4.04 KB
/
Transaction.hpp
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
133
134
135
136
137
138
139
140
141
142
143
#ifndef TRANSACTION_H
#include <hex.h>
#include <osrng.h>
#include <pssr.h>
#include <rsa.h>
#include <whrlpool.h>
#include <base64.h>
#include <utility>
using Verifier = CryptoPP::RSASS<CryptoPP::PSSR, CryptoPP::Whirlpool>::Verifier;
using Signer = CryptoPP::RSASS<CryptoPP::PSSR, CryptoPP::Whirlpool>::Signer;
class Transaction {
public:
Transaction(string, string, int64_t);
Transaction(string, string, string, int64_t);
Transaction(string, int64_t);
void signTransaction(const string&);
bool isValidTransaction();
string asString();
string getReceiver();
string getSender();
string getSign();
int64_t getAmount();
bool isMinerReward();
private:
string sender;
string receiver;
string signature;
int64_t amount;
string getHash();
bool isReward = false;
};
string Transaction::asString() {
return "\tSender: " + this->sender + "; Receiver: " + this->receiver + "; Amount: " + to_string(this->amount);
}
string Transaction::getHash() {
std::string digest;
CryptoPP::SHA256 hash;
CryptoPP::StringSource foo(this->asString(), true,
new CryptoPP::HashFilter(hash,
new CryptoPP::Base64Encoder (
new CryptoPP::StringSink(digest))));
return digest;
}
Transaction::Transaction(string sender, string receiver, int64_t amount) {
this->sender = std::move(sender);
this->receiver = std::move(receiver);
this->amount = amount;
}
Transaction::Transaction(string sender, string receiver, string signature, int64_t amount) {
this->sender = std::move(sender);
this->receiver = std::move(receiver);
this->signature = std::move(signature);
this->amount = amount;
}
void Transaction::signTransaction(const string& pr) {
CryptoPP::RSA::PrivateKey privateKey;
privateKey.Load(CryptoPP::StringSource(pr, true,
new CryptoPP::HexDecoder()).Ref());
// sign message
std::string sig;
Signer signer(privateKey);
CryptoPP::AutoSeededRandomPool rng;
CryptoPP::StringSource ss(this->getHash(), true,
new CryptoPP::SignerFilter(rng, signer,
new CryptoPP::HexEncoder(
new CryptoPP::StringSink(sig))));
this->signature = sig;
}
bool Transaction::isValidTransaction() {
if (isReward) {
return true; // checking for reward correctness?
}
string message = this->getHash();
CryptoPP::RSA::PublicKey publicKey;
publicKey.Load(CryptoPP::StringSource(this->sender, true,
new CryptoPP::HexDecoder()).Ref());
// decode signature
std::string decodedSignature;
CryptoPP::StringSource ss(this->signature, true,
new CryptoPP::HexDecoder(
new CryptoPP::StringSink(decodedSignature)));
// verify message
bool result = false;
Verifier verifier(publicKey);
CryptoPP::StringSource ss2(decodedSignature + message, true,
new CryptoPP::SignatureVerificationFilter(verifier,
new CryptoPP::ArraySink(
(CryptoPP::byte *) &result,
sizeof(result))));
return result;
}
string Transaction::getReceiver() {
return receiver;
}
string Transaction::getSender() {
return sender;
}
string Transaction::getSign() {
return signature;
}
int64_t Transaction::getAmount() {
return amount;
}
bool Transaction::isMinerReward() {
return this->isReward;
}
Transaction::Transaction(string rec, int64_t amount) {
this->amount = amount;
this->receiver = std::move(rec);
this->isReward = true;
this->sender = "";
}
#endif