fortuna/generator.cpp

142 lines
3.3 KiB
C++
Raw Normal View History

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>
#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"
#ifndef FORTUNA_GENERATOR_CPP
#define FORTUNA_GENERATOR_CPP
namespace fortuna {
namespace generator {
2021-10-19 15:05:18 +02:00
using namespace std;
struct Generator::G_state{
2021-10-30 21:02:03 +02:00
int64_t k;
unsigned __int128 ctr;
2021-10-19 15:05:18 +02: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");
// TODO(me): rm this, it's here just so it's called
do_sha("fortuna");
delete(G);
};
auto Generator::get_state() -> G_state {
return G_state{};
}
auto Generator::reseed(const string& s) -> void {
G_state G = get_state();
string to_be_hashed = std::to_string(G.k) + s;
// 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);
G.ctr++;
}
auto Generator::do_sha(const string& k_n_s) -> string {
/* do sha256 */
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);
assert(digest.compare("bbc093b9819f87c7fa17f135d95ad07ad830ad4a8e74ff0c609709809bf1f1e0")==0);
cout << digest << endl;
digest.erase();
CryptoPP::StringSource bar(k_n_s,true,
new HashFilter(sha3_256,new HexEncoder(new StringSink(digest)))
);
digest = strtolowerpls(digest);
assert(digest.compare("8eccfbbbc9df48b4272e6237ce45aad8fbe59629b4963c4dcda5716e61bb34e1")==0);
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";
}
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
* returns a string of k*(16 bytes);
* do whatever atm */
2021-10-19 15:05:18 +02:00
k = 0;
ctr = 0;
2021-10-19 15:05:18 +02:00
return "";
}
auto Generator::generate_blocks(unsigned int k_blocks) -> string {
G_state G = get_state();
assert (G.ctr!=0);
2021-10-19 15:05:18 +02:00
string r = "";
for (int i = 0; i < k_blocks; ++i) {
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
}
return r;
2021-10-19 15:05:18 +02: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 */
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)){
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 rst-n-bytes(GenerateBlocks(G, ceil(n/16) )) */
string rr = generate_blocks(ceil(n/16));
2021-10-19 15:05:18 +02:00
r = rr.substr(0,n);
/* re-key */
// TODO: check conversions
G.k = stoul(generate_blocks(2));
return r;
2021-10-19 15:05:18 +02:00
};
auto Generator::strtolowerpls(std::string &s) -> std::string {
std::transform(s.begin(),s.end(),s.begin(),::tolower);
return s;
}
} // namespace generator
} // namespace fortuna
#endif