2021-10-19 15:25:20 +02:00
|
|
|
#include <cmath>
|
|
|
|
#include <cassert>
|
2021-10-30 21:02:03 +02:00
|
|
|
#include <cstdint>
|
2021-10-19 15:05:18 +02:00
|
|
|
#include <stdexcept>
|
2021-11-11 02:35:17 +01:00
|
|
|
#include <iostream>
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
#include <cryptopp/hex.h>
|
|
|
|
#include <cryptopp/filters.h>
|
|
|
|
#include <cryptopp/sha.h>
|
|
|
|
#include <cryptopp/sha3.h>
|
|
|
|
|
2021-10-19 15:05:18 +02:00
|
|
|
#include "generator.h"
|
|
|
|
|
2021-11-03 02:57:23 +01:00
|
|
|
#ifndef FORTUNA_GENERATOR_CPP
|
|
|
|
#define FORTUNA_GENERATOR_CPP
|
2021-11-01 09:23:22 +01:00
|
|
|
namespace fortuna {
|
|
|
|
namespace generator {
|
|
|
|
|
2021-10-19 15:05:18 +02:00
|
|
|
using namespace std;
|
|
|
|
|
2021-11-03 02:57:23 +01:00
|
|
|
struct Generator::G_state{
|
2021-10-30 21:02:03 +02:00
|
|
|
int64_t k;
|
2021-10-26 15:59:22 +02:00
|
|
|
unsigned __int128 ctr;
|
2021-10-19 15:05:18 +02:00
|
|
|
};
|
|
|
|
|
2021-11-03 02:57:23 +01:00
|
|
|
void Generator::initialize_generator(){
|
|
|
|
// Generator::G_state *G = new G_state; // -> was told to use auto by
|
|
|
|
// clang-tidy...
|
|
|
|
auto G = new Generator::G_state{};
|
|
|
|
G->k = 0;
|
|
|
|
G->ctr = 0;
|
|
|
|
printf("Generator initialized\n");
|
2021-11-11 02:35:17 +01:00
|
|
|
// TODO(me): rm this, it's here just so it's called
|
|
|
|
do_sha("fortuna");
|
2021-11-03 02:57:23 +01:00
|
|
|
delete(G);
|
|
|
|
};
|
|
|
|
|
|
|
|
auto Generator::get_state() -> G_state {
|
|
|
|
return G_state{};
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Generator::reseed(const string& s) -> void {
|
|
|
|
G_state G = get_state();
|
2021-11-01 09:50:09 +01:00
|
|
|
string to_be_hashed = std::to_string(G.k) + s;
|
2021-11-11 02:35:17 +01:00
|
|
|
// TODO(me): wrap do_sha in a try-catch
|
|
|
|
string a = do_sha(to_be_hashed);
|
|
|
|
// str, size, base
|
|
|
|
G.k = stol(a,nullptr,10);
|
2021-11-01 09:50:09 +01:00
|
|
|
G.ctr++;
|
2021-10-30 21:06:54 +02:00
|
|
|
}
|
|
|
|
|
2021-11-11 02:35:17 +01:00
|
|
|
auto Generator::do_sha(const string& k_n_s) -> string {
|
2021-10-30 21:06:54 +02:00
|
|
|
/* do sha256 */
|
2021-11-11 02:35:17 +01:00
|
|
|
using std::cout;
|
|
|
|
using std::endl;
|
|
|
|
using CryptoPP::HexEncoder;
|
|
|
|
using CryptoPP::HashFilter;
|
|
|
|
using CryptoPP::StringSink;
|
|
|
|
|
|
|
|
string digest;
|
|
|
|
|
|
|
|
CryptoPP::SHA256 sha2_256;
|
|
|
|
CryptoPP::SHA3_256 sha3_256;
|
|
|
|
|
|
|
|
digest.erase();
|
|
|
|
CryptoPP::StringSource foo(k_n_s,true,
|
|
|
|
new HashFilter(sha2_256,new HexEncoder(new StringSink(digest)))
|
|
|
|
);
|
|
|
|
digest = strtolowerpls(digest);
|
2021-11-11 03:56:20 +01:00
|
|
|
assert(digest.compare("bbc093b9819f87c7fa17f135d95ad07ad830ad4a8e74ff0c609709809bf1f1e0")==0);
|
2021-11-11 02:35:17 +01:00
|
|
|
cout << digest << endl;
|
|
|
|
|
|
|
|
digest.erase();
|
|
|
|
|
|
|
|
CryptoPP::StringSource bar(k_n_s,true,
|
|
|
|
new HashFilter(sha3_256,new HexEncoder(new StringSink(digest)))
|
|
|
|
);
|
|
|
|
digest = strtolowerpls(digest);
|
2021-11-11 03:56:20 +01:00
|
|
|
assert(digest.compare("8eccfbbbc9df48b4272e6237ce45aad8fbe59629b4963c4dcda5716e61bb34e1")==0);
|
2021-11-11 02:35:17 +01:00
|
|
|
cout << digest << endl;
|
|
|
|
|
|
|
|
// return digest;
|
|
|
|
// TODO(me)
|
|
|
|
// do not return the proper digest just yet, too long to fit into
|
|
|
|
// int64_t. G.k has to be a 256bit-wide type. for now just return a
|
|
|
|
// small enough number
|
|
|
|
return "42";
|
2021-10-30 21:06:54 +02:00
|
|
|
}
|
|
|
|
|
2021-11-03 02:57:23 +01:00
|
|
|
auto Generator::do_crypto(int64_t k, unsigned __int128 ctr) -> string {
|
2021-10-19 15:05:18 +02:00
|
|
|
/* this function calls the block cipher
|
2021-10-27 18:53:53 +02:00
|
|
|
* returns a string of k*(16 bytes);
|
2021-11-03 02:57:23 +01:00
|
|
|
* do whatever atm */
|
2021-10-19 15:05:18 +02:00
|
|
|
k = 0;
|
2021-10-24 23:14:53 +02:00
|
|
|
ctr = 0;
|
2021-10-19 15:05:18 +02:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2021-11-08 09:47:18 +01:00
|
|
|
auto Generator::generate_blocks(unsigned int k_blocks) -> string {
|
2021-11-03 02:57:23 +01:00
|
|
|
G_state G = get_state();
|
2021-10-24 23:14:53 +02:00
|
|
|
assert (G.ctr!=0);
|
2021-10-19 15:05:18 +02:00
|
|
|
string r = "";
|
|
|
|
for (int i = 0; i < k_blocks; ++i) {
|
2021-10-24 23:14:53 +02:00
|
|
|
r += do_crypto(G.k, G.ctr);
|
2021-11-01 10:05:43 +01:00
|
|
|
G.ctr++;
|
2021-10-19 15:05:18 +02:00
|
|
|
}
|
2021-11-03 02:57:23 +01:00
|
|
|
return r;
|
2021-10-19 15:05:18 +02:00
|
|
|
}
|
|
|
|
|
2021-11-03 02:57:23 +01:00
|
|
|
auto Generator::generate_random_data(uint n) -> string {
|
|
|
|
G_state G = get_state();
|
2021-10-19 15:05:18 +02:00
|
|
|
string r = "";
|
|
|
|
if (n < 0){
|
|
|
|
/* this should not be possible */
|
2021-10-27 18:53:53 +02:00
|
|
|
printf("[*] error: n cannot be < 0\n");
|
2021-10-19 15:05:18 +02:00
|
|
|
throw invalid_argument("n cannot be < 0");
|
|
|
|
} else if (n > pow(2,20)){
|
2021-10-27 18:53:53 +02:00
|
|
|
printf("[*] error: n cannot be > 2^20\n");
|
2021-10-19 15:05:18 +02:00
|
|
|
throw invalid_argument("n cannot be > 2^20");
|
|
|
|
}
|
|
|
|
/* do magic to compute r
|
|
|
|
* r ← first-n-bytes(GenerateBlocks(G, ceil(n/16) )) */
|
2021-11-03 02:57:23 +01:00
|
|
|
string rr = generate_blocks(ceil(n/16));
|
2021-10-19 15:05:18 +02:00
|
|
|
r = rr.substr(0,n);
|
2021-10-26 15:59:22 +02:00
|
|
|
|
|
|
|
/* re-key */
|
|
|
|
// TODO: check conversions
|
2021-11-03 02:57:23 +01:00
|
|
|
G.k = stoul(generate_blocks(2));
|
|
|
|
return r;
|
2021-10-19 15:05:18 +02:00
|
|
|
};
|
|
|
|
|
2021-11-03 02:57:23 +01:00
|
|
|
|
2021-11-11 02:25:41 +01:00
|
|
|
auto Generator::strtolowerpls(std::string &s) -> std::string {
|
|
|
|
std::transform(s.begin(),s.end(),s.begin(),::tolower);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2021-11-01 09:23:22 +01:00
|
|
|
} // namespace generator
|
|
|
|
} // namespace fortuna
|
2021-11-03 02:57:23 +01:00
|
|
|
#endif
|