2021-11-15 22:13:00 +01:00
|
|
|
#ifndef FORTUNA_GENERATOR_CPP
|
|
|
|
#define FORTUNA_GENERATOR_CPP
|
|
|
|
|
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 <cryptopp/hex.h>
|
|
|
|
#include <cryptopp/filters.h>
|
|
|
|
#include <cryptopp/sha3.h>
|
2021-11-18 22:05:05 +01:00
|
|
|
#include <fmt/core.h>
|
2021-11-11 02:35:17 +01:00
|
|
|
|
2021-10-19 15:05:18 +02:00
|
|
|
#include "generator.h"
|
|
|
|
|
2021-11-01 09:23:22 +01:00
|
|
|
namespace fortuna {
|
|
|
|
namespace generator {
|
|
|
|
|
2021-11-03 02:57:23 +01:00
|
|
|
struct Generator::G_state{
|
2021-10-30 21:02:03 +02:00
|
|
|
int64_t k;
|
2021-11-15 22:47:22 +01:00
|
|
|
#pragma GCC diagnostic push
|
|
|
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
2021-10-26 15:59:22 +02:00
|
|
|
unsigned __int128 ctr;
|
2021-11-15 22:47:22 +01:00
|
|
|
#pragma GCC diagnostic pop
|
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;
|
2021-11-19 22:32:03 +01:00
|
|
|
fmt::print("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{};
|
|
|
|
}
|
|
|
|
|
2021-11-13 21:58:05 +01:00
|
|
|
auto Generator::reseed(const std::string& s) -> void {
|
2021-11-03 02:57:23 +01:00
|
|
|
G_state G = get_state();
|
2021-11-13 21:58:05 +01:00
|
|
|
std::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
|
2021-11-13 21:58:05 +01:00
|
|
|
std::string a = do_sha(to_be_hashed);
|
2021-11-11 02:35:17 +01:00
|
|
|
// 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-13 21:58:05 +01:00
|
|
|
auto Generator::do_sha(const std::string& k_n_s) -> std::string {
|
2021-10-30 21:06:54 +02:00
|
|
|
/* do sha256 */
|
2021-11-11 02:35:17 +01:00
|
|
|
using CryptoPP::HexEncoder;
|
|
|
|
using CryptoPP::HashFilter;
|
|
|
|
using CryptoPP::StringSink;
|
|
|
|
|
2021-11-13 21:58:05 +01:00
|
|
|
std::string digest;
|
2021-11-11 02:35:17 +01:00
|
|
|
|
2021-11-17 23:40:38 +01:00
|
|
|
// no reason not to go for Keccak
|
2021-11-11 02:35:17 +01:00
|
|
|
CryptoPP::SHA3_256 sha3_256;
|
|
|
|
|
|
|
|
digest.erase();
|
2021-11-17 23:40:38 +01:00
|
|
|
std::string to_compare =
|
|
|
|
"8eccfbbbc9df48b4272e6237ce45aad8fbe59629b4963c4dcda5716e61bb34e1";
|
2021-11-11 02:35:17 +01:00
|
|
|
|
|
|
|
CryptoPP::StringSource bar(k_n_s,true,
|
2021-11-14 22:16:52 +01:00
|
|
|
new HashFilter(sha3_256,new HexEncoder(new StringSink(digest),false))
|
2021-11-11 02:35:17 +01:00
|
|
|
);
|
2021-11-17 23:40:38 +01:00
|
|
|
assert(digest == to_compare);
|
2021-11-18 22:05:05 +01:00
|
|
|
fmt::print("{}\n", digest);
|
2021-11-17 23:40:38 +01:00
|
|
|
digest.erase();
|
2021-11-11 02:35:17 +01:00
|
|
|
|
|
|
|
// 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-15 22:47:22 +01:00
|
|
|
#pragma GCC diagnostic push
|
|
|
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
2021-11-13 21:58:05 +01:00
|
|
|
auto Generator::do_crypto(int64_t k, unsigned __int128 ctr) -> std::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-15 22:47:22 +01:00
|
|
|
#pragma GCC diagnostic pop
|
2021-10-19 15:05:18 +02:00
|
|
|
|
2021-11-13 21:58:05 +01:00
|
|
|
auto Generator::generate_blocks(unsigned int k_blocks) -> std::string {
|
2021-11-03 02:57:23 +01:00
|
|
|
G_state G = get_state();
|
2021-11-16 00:17:16 +01:00
|
|
|
assert ((G.ctr!=0) && "Counter is not 0, generator has been seeded");
|
2021-11-13 21:58:05 +01:00
|
|
|
std::string r = "";
|
2021-10-19 15:05:18 +02:00
|
|
|
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-13 21:58:05 +01:00
|
|
|
auto Generator::generate_random_data(uint n) -> std::string {
|
2021-11-03 02:57:23 +01:00
|
|
|
G_state G = get_state();
|
2021-11-13 21:58:05 +01:00
|
|
|
std::string r = "";
|
2021-10-19 15:05:18 +02:00
|
|
|
if (n < 0){
|
|
|
|
/* this should not be possible */
|
2021-11-19 22:32:03 +01:00
|
|
|
fmt::print("[*] error: n cannot be < 0\n");
|
2021-11-13 21:58:05 +01:00
|
|
|
throw std::invalid_argument("n cannot be < 0");
|
2021-10-19 15:05:18 +02:00
|
|
|
} else if (n > pow(2,20)){
|
2021-11-19 22:32:03 +01:00
|
|
|
fmt::print("[*] error: n cannot be > 2^20\n");
|
2021-11-13 21:58:05 +01:00
|
|
|
throw std::invalid_argument("n cannot be > 2^20");
|
2021-10-19 15:05:18 +02:00
|
|
|
}
|
|
|
|
/* do magic to compute r
|
|
|
|
* r ← first-n-bytes(GenerateBlocks(G, ceil(n/16) )) */
|
2021-11-13 21:58:05 +01:00
|
|
|
std::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
|
|
|
|
2021-11-01 09:23:22 +01:00
|
|
|
} // namespace generator
|
|
|
|
} // namespace fortuna
|
2021-11-03 02:57:23 +01:00
|
|
|
#endif
|