more state and utility

This commit is contained in:
Green Sky 2024-08-05 11:49:28 +02:00
parent 868e4c33d5
commit 7399956a06
No known key found for this signature in database
2 changed files with 172 additions and 24 deletions

View File

@ -1,5 +1,7 @@
#include "./tox_p2prng.hpp" #include "./tox_p2prng.hpp"
#include <solanaceae/tox_contacts/components.hpp>
#include <iostream> #include <iostream>
// packets: // packets:
@ -23,6 +25,86 @@
// secret_request // secret_request
// - id // - id
void ToxP2PRNG::RngState::fillInitalStatePreamble(const ByteSpan id) {
// id
// res = id
inital_state_preamble = static_cast<std::vector<uint8_t>>(id);
for (const auto c : contacts) {
if (!c.any_of<Contact::Components::ToxFriendPersistent, Contact::Components::ToxGroupPeerPersistent>()) {
inital_state_preamble.clear();
return;
}
if (const auto* tfp = c.try_get<Contact::Components::ToxFriendPersistent>(); tfp != nullptr) {
inital_state_preamble.insert(inital_state_preamble.cend(), tfp->key.data.cbegin(), tfp->key.data.cend());
continue;
}
if (const auto* tgpp = c.try_get<Contact::Components::ToxGroupPeerPersistent>(); tgpp != nullptr) {
inital_state_preamble.insert(inital_state_preamble.cend(), tgpp->peer_key.data.cbegin(), tgpp->peer_key.data.cend());
continue;
}
}
}
void ToxP2PRNG::RngState::genFinalResult(void) {
if (contacts.size() < 2) {
return;
}
if (hmacs.size() < contacts.size()) {
return;
}
if (secrets.size() < contacts.size()) {
return;
}
// val
if (inital_state.empty()) {
return;
}
if (inital_state_preamble.empty()) {
return;
}
final_result.resize(P2PRNG_COMBINE_LEN);
{ // fist secret
const auto& fs = secrets.at(contacts.front());
if (p2prng_combine_init(final_result.data(), fs.data(), fs.size()) != 0) {
final_result.clear();
return;
}
}
for (size_t i = 1; i < contacts.size(); i++) {
const auto& s = secrets.at(contacts.at(i));
if (p2prng_combine_update(final_result.data(), final_result.data(), s.data(), s.size()) != 0) {
final_result.clear();
return;
}
}
// finally, add in is
// hmmm copy, meh, we could do preamble and app is in seperate updates, which changes the algo, but should be fine
{
std::vector<uint8_t> full_is = inital_state_preamble;
full_is.insert(full_is.cend(), inital_state.cbegin(), inital_state.cend());
if (p2prng_combine_update(final_result.data(), final_result.data(), full_is.data(), full_is.size()) != 0) {
final_result.clear();
return;
}
}
// we done
}
ToxP2PRNG::ToxP2PRNG( ToxP2PRNG::ToxP2PRNG(
ToxI& t, ToxI& t,
ToxEventProviderI& tep, ToxEventProviderI& tep,
@ -72,20 +154,19 @@ bool ToxP2PRNG::handlePacket(
switch (pkg_type) { switch (pkg_type) {
case PKG::INIT_WITH_HMAC: case PKG::INIT_WITH_HMAC:
return parse_init_with_hmac(c, id, data+32, data_size-(32)); return handle_init_with_hmac(c, id, data+32, data_size-(32));
case PKG::HMAC: case PKG::HMAC:
return parse_hmac(c, id, data+32, data_size-(32)); return handle_hmac(c, id, data+32, data_size-(32));
case PKG::HMAC_REQUEST: case PKG::HMAC_REQUEST:
return parse_hmac_request(c, id, data+32, data_size-(32)); return handle_hmac_request(c, id, data+32, data_size-(32));
case PKG::SECRET: case PKG::SECRET:
return parse_secret(c, id, data+32, data_size-(32)); return handle_secret(c, id, data+32, data_size-(32));
case PKG::SECRET_REQUEST: case PKG::SECRET_REQUEST:
return parse_secret_request(c, id, data+32, data_size-(32)); return handle_secret_request(c, id, data+32, data_size-(32));
default: default:
return false; return false;
} }
return false; return false;
} }
@ -139,39 +220,72 @@ bool ToxP2PRNG::handleGroupPacket(
return handlePacket(c, tpr_pkg_type, data+2, data_size-2); return handlePacket(c, tpr_pkg_type, data+2, data_size-2);
} }
bool ToxP2PRNG::parse_init_with_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) { bool ToxP2PRNG::handle_init_with_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) {
std::cerr << "TP2PRNG: got packet init_with_hmac\n"; std::cerr << "TP2PRNG: got packet INIT_WITH_HMAC\n";
size_t curser = 0; size_t curser = 0;
return false; return false;
} }
bool ToxP2PRNG::parse_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) { bool ToxP2PRNG::handle_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) {
std::cerr << "TP2PRNG: got packet hmac\n"; std::cerr << "TP2PRNG: got packet HMAC\n";
size_t curser = 0; size_t curser = 0;
return false; return false;
} }
bool ToxP2PRNG::parse_hmac_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) { bool ToxP2PRNG::handle_hmac_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) {
std::cerr << "TP2PRNG: got packet hmac_request\n"; std::cerr << "TP2PRNG: got packet HMAC_REQUEST\n";
if (data_size > 0) {
std::cerr << "TP2PRNG warning: HMAC_REQUEST pkg has extra data!\n";
}
return false;
}
bool ToxP2PRNG::handle_secret(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) {
std::cerr << "TP2PRNG: got packet SECRET\n";
size_t curser = 0; size_t curser = 0;
return false; return false;
} }
bool ToxP2PRNG::parse_secret(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) { bool ToxP2PRNG::handle_secret_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) {
std::cerr << "TP2PRNG: got packet secret\n"; std::cerr << "TP2PRNG: got packet SECRET_REQUEST\n";
size_t curser = 0;
if (data_size > 0) {
std::cerr << "TP2PRNG warning: SECRET_REQUEST pkg has extra data!\n";
}
return false; return false;
} }
bool ToxP2PRNG::parse_secret_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) { ToxP2PRNG::RngState* ToxP2PRNG::getRngSate(Contact3Handle c, ByteSpan id_bytes) {
std::cerr << "TP2PRNG: got packet secret_request\n"; if (id_bytes.size != ID{}.size()) {
size_t curser = 0; return nullptr;
}
return false; ID r_id{};
{ // building the id is very annoying, should have not used array?
// TODO: provide custom comperator ?
for (size_t i = 0; i < r_id.size(); i++) {
r_id[i] = id_bytes[i];
}
}
const auto find_it = _global_map.find(r_id);
if (find_it == _global_map.cend()) {
return nullptr;
}
const auto find_c = std::find(find_it->second.contacts.cbegin(), find_it->second.contacts.cend(), c);
if (find_c == find_it->second.contacts.cend()) {
// id exists, but peer looking into id is not participating, so we block the request
return nullptr;
}
return &find_it->second;
} }
bool ToxP2PRNG::onToxEvent(const Tox_Event_Friend_Lossless_Packet* e) { bool ToxP2PRNG::onToxEvent(const Tox_Event_Friend_Lossless_Packet* e) {

View File

@ -2,9 +2,14 @@
#include "./p2prng.hpp" #include "./p2prng.hpp"
#include <p2prng.h>
#include <solanaceae/tox_contacts/tox_contact_model2.hpp> #include <solanaceae/tox_contacts/tox_contact_model2.hpp>
#include <entt/container/dense_map.hpp>
#include <cstdint> #include <cstdint>
#include <vector>
// implements P2PRNGI for tox // implements P2PRNGI for tox
// both tox friends(1to1) aswell as tox ngc(NtoN) should be supported // both tox friends(1to1) aswell as tox ngc(NtoN) should be supported
@ -24,6 +29,33 @@ class ToxP2PRNG : public P2PRNGI, public ToxEventI {
SECRET_REQUEST, SECRET_REQUEST,
}; };
using ID = std::array<uint8_t, 32>;
struct IDHash {size_t operator()(const ID& a) const {return (a[0] | a[1] << 1*8 | a[2] << 1*16 | a[3] << 1*24) ^ (a[31] | a[30] << 1*8);}};
struct RngState {
// all contacts participating, including self
std::vector<Contact3Handle> contacts;
// app given
std::vector<uint8_t> inital_state;
// the other stuff needed for full IS (preamble+IS)
// - ID
// - list of public keys of contacts (same order as later used to calc res)
std::vector<uint8_t> inital_state_preamble;
void fillInitalStatePreamble(const ByteSpan id);
// use contacts instead?
entt::dense_map<Contact3, std::array<uint8_t, P2PRNG_MAC_LEN>> hmacs;
entt::dense_map<Contact3, std::array<uint8_t, P2PRNG_LEN + P2PRNG_MAC_KEY_LEN>> secrets;
entt::dense_map<Contact3, bool> secrets_valid;
void genFinalResult(void);
std::vector<uint8_t> final_result; // cached
};
entt::dense_map<ID, RngState, IDHash> _global_map;
public: public:
ToxP2PRNG( ToxP2PRNG(
ToxI& t, ToxI& t,
@ -60,11 +92,13 @@ class ToxP2PRNG : public P2PRNGI, public ToxEventI {
const bool _private const bool _private
); );
bool parse_init_with_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size); bool handle_init_with_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size);
bool parse_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size); bool handle_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size);
bool parse_hmac_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size); bool handle_hmac_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size);
bool parse_secret(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size); bool handle_secret(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size);
bool parse_secret_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size); bool handle_secret_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size);
RngState* getRngSate(Contact3Handle c, ByteSpan id);
protected: protected:
bool onToxEvent(const Tox_Event_Friend_Lossless_Packet* e) override; bool onToxEvent(const Tox_Event_Friend_Lossless_Packet* e) override;