diff --git a/.gitignore b/.gitignore index 9a4dd72e2..c6908518c 100644 --- a/.gitignore +++ b/.gitignore @@ -119,3 +119,6 @@ _build/ # environment .env +.idea/ +cmake-build-debug/ +log_*.txt diff --git a/Networking/CryptoPlayer.cpp b/Networking/CryptoPlayer.cpp index 43b2ada5c..623e7c589 100644 --- a/Networking/CryptoPlayer.cpp +++ b/Networking/CryptoPlayer.cpp @@ -92,14 +92,18 @@ CryptoPlayer::CryptoPlayer(const Names& Nms, const string& id_base) : receivers[i] = 0; continue; } + if (N.get_name(i).empty()) continue; - senders[i] = new Sender(i < my_num() ? sockets[i] : other_sockets[i]); - receivers[i] = new Receiver(i < my_num() ? other_sockets[i] : sockets[i]); +// senders[i] = new Sender(i < my_num() ? sockets[i] : other_sockets[i]); +// receivers[i] = new Receiver(i < my_num() ? other_sockets[i] : sockets[i]); + senders[i] = new Sender(i < my_num() ? sockets[i] : other_sockets[i], "P" + to_string(my_num()), "P" + to_string(i)); + receivers[i] = new Receiver(i < my_num() ? other_sockets[i] : sockets[i], "P" + to_string(i), "P" + to_string(my_num())); } } void CryptoPlayer::connect(int i, vector* plaintext_sockets) { + if (N.get_name(i).empty()) return; sockets[i] = new ssl_socket(io_service, ctx, plaintext_sockets[0][i], "P" + to_string(i), "P" + to_string(my_num()), i < my_num()); other_sockets[i] = new ssl_socket(io_service, ctx, plaintext_sockets[1][i], @@ -187,6 +191,8 @@ void CryptoPlayer::send_receive_all_no_stats(const vector>& channel for (int offset = 1; offset < num_players(); offset++) { int other = get_player(offset); + if (N.get_name(other).empty()) continue; + // TODO: send to offline nodes bool receive = channels[other][my_num()]; if (channels[my_num()][other]) this->senders[other]->request(to_send[other]); @@ -196,6 +202,8 @@ void CryptoPlayer::send_receive_all_no_stats(const vector>& channel for (int offset = 1; offset < num_players(); offset++) { int other = get_player(offset); + if (N.get_name(other).empty()) continue; + // TODO: send to offline nodes bool receive = channels[other][my_num()]; if (channels[my_num()][other]) this->senders[other]->wait(to_send[other]); @@ -212,6 +220,7 @@ void CryptoPlayer::partial_broadcast(const vector& my_senders, for (int offset = 1; offset < num_players(); offset++) { int other = get_player(offset); + if (N.get_name(other).empty()) continue; bool receive = my_senders[other]; if (my_receivers[other]) { @@ -224,6 +233,7 @@ void CryptoPlayer::partial_broadcast(const vector& my_senders, for (int offset = 1; offset < num_players(); offset++) { int other = get_player(offset); + if (N.get_name(other).empty()) continue; bool receive = my_senders[other]; if (my_receivers[other]) this->senders[other]->wait(os[my_num()]); @@ -237,6 +247,7 @@ void CryptoPlayer::Broadcast_Receive_no_stats(vector& os) const for (int offset = 1; offset < num_players(); offset++) { int other = get_player(offset); + if (N.get_name(other).empty()) continue; this->senders[other]->request(os[my_num()]); receivers[other]->request(os[other]); } @@ -244,6 +255,7 @@ void CryptoPlayer::Broadcast_Receive_no_stats(vector& os) const for (int offset = 1; offset < num_players(); offset++) { int other = get_player(offset); + if (N.get_name(other).empty()) continue; this->senders[other]->wait(os[my_num()]); receivers[other]->wait(os[other]); } diff --git a/Networking/Player.cpp b/Networking/Player.cpp index a7935f305..06f7303c8 100644 --- a/Networking/Player.cpp +++ b/Networking/Player.cpp @@ -280,6 +280,7 @@ void PlainPlayer::setup_sockets(const vector& names, sockets.resize(nplayers); // Set up the client side for (int i=player_no; i& names, send_to_self_socket = sockets[player_no]; // Setting up the server side for (int i=0; i<=player_no; i++) { + if (names[i].empty()) continue; auto id=id_base+"P"+to_string(i); #ifdef DEBUG_NETWORKING fprintf(stderr, @@ -311,6 +313,7 @@ void PlainPlayer::setup_sockets(const vector& names, } for (int i = 0; i < nplayers; i++) { + if (names[i].empty()) continue; // timeout of 5 minutes struct timeval tv; tv.tv_sec = 300; @@ -359,7 +362,7 @@ void Player::send_all(const octetStream& o) const { TimeScope ts(comm_stats["Sending to all"].add(o)); for (int i=0; i::Broadcast_Receive_no_stats(vector& o) const for (int i=1; i& o) const { unchecked_broadcast(o); { for (int i=0; i::Receiver(T socket) : socket(socket), thread(0) start(); } +template +Receiver::Receiver(T socket, string sender, string receiver) : socket(socket), sender(sender), receiver(receiver), cnt(0), thread(0) +{ + start(); +} + template Receiver::~Receiver() { @@ -55,7 +61,8 @@ void Receiver::run() timer.start(); RunningTimer mytimer; #endif - os->Receive(socket); + if (sender.empty()) os->Receive(socket); + else os->Receive(sender, receiver, ++cnt); #ifdef VERBOSE_SSL cout << "receiving " << os->get_length() * 1e-6 << " MB on " << socket << " took " << mytimer.elapsed() << ", total " diff --git a/Networking/Receiver.h b/Networking/Receiver.h index 7695d8265..10ca7131f 100644 --- a/Networking/Receiver.h +++ b/Networking/Receiver.h @@ -16,6 +16,9 @@ template class Receiver { T socket; + string sender; + string receiver; + int cnt; WaitQueue in; WaitQueue out; pthread_t thread; @@ -33,6 +36,7 @@ class Receiver Timer timer; Receiver(T socket); + Receiver(T socket, string sender, string receiver); ~Receiver(); void request(octetStream& os); diff --git a/Networking/Sender.cpp b/Networking/Sender.cpp index 4e4b98810..4cfde12f8 100644 --- a/Networking/Sender.cpp +++ b/Networking/Sender.cpp @@ -22,6 +22,12 @@ Sender::Sender(T socket) : socket(socket), thread(0) start(); } +template +Sender::Sender(T socket, string sender, string receiver) : socket(socket), sender(sender), receiver(receiver), cnt(0), thread(0) +{ + start(); +} + template Sender::~Sender() { @@ -51,7 +57,8 @@ void Sender::run() timer.start(); RunningTimer mytimer; #endif - os->Send(socket); + if (sender.empty()) os->Send(socket); + else os->Send(sender, receiver, ++cnt); #ifdef VERBOSE_SSL cout << "sending " << os->get_length() * 1e-6 << " MB on " << socket << " took " << mytimer.elapsed() << ", total " diff --git a/Networking/Sender.h b/Networking/Sender.h index e5c026414..c16fc9135 100644 --- a/Networking/Sender.h +++ b/Networking/Sender.h @@ -16,6 +16,9 @@ template class Sender { T socket; + string sender; + string receiver; + int cnt; WaitQueue in; WaitQueue out; pthread_t thread; @@ -33,6 +36,7 @@ class Sender Timer timer; Sender(T socket); + Sender(T socket, string sender, string receiver); ~Sender(); void request(const octetStream& os); diff --git a/Networking/Server.cpp b/Networking/Server.cpp index f9ff3e897..55d2b590c 100644 --- a/Networking/Server.cpp +++ b/Networking/Server.cpp @@ -67,7 +67,8 @@ void Server::send_names() addresses.store(ports); for (int i=0; i +#include +#include +#include +#include +#include +#include +#include +#include "picosha2.h" + +using namespace std; + +// dummy helper functions +void _save(const string &key, const vector &payload) +{ + // preprocess the key to be fixed length + std::string hash = ""; + picosha2::hash256_hex_string(key.begin(), key.end(), hash); // hash now has length=64 + // next, store it in a temporary file + std::ofstream ofs; + ofs.open(hash + ".comm.bin", std::ofstream::out | std::ofstream::trunc); + ofs.write((char *)payload.data(), payload.size()); + ofs.close(); +} +vector _load(const string &key) +{ + // preprocess the key to be fixed length + std::string hash = ""; + picosha2::hash256_hex_string(key.begin(), key.end(), hash); // hash now has length=64 + // next, check if the file exists and wait until it exists + while (true) + { + std::ifstream ifs; + ifs.open(hash + ".comm.bin", std::ifstream::in); + if (ifs.good()) + { + ifs.seekg(0, std::ios::end); + size_t size = ifs.tellg(); + vector payload(size); + ifs.seekg(0, std::ios::beg); + ifs.read((char *)payload.data(), size); + ifs.close(); + return payload; + } + ifs.close(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } +} +// exposed dummy functions +void set_variable(const string &task_id, + const string &key, + const vector &payload, + const string &sender, + const vector &receivers) +{ + for (auto &receiver : receivers) + { + _save(task_id + "." + sender + "." + receiver + "." + key, payload); + } +} +vector get_variable(const string &task_id, + const string &key, + const string &sender, + const string &receiver) +{ + return _load(task_id + "." + sender + "." + receiver + "." + key); +} + +#endif // COLINK_VT_DUMMY_H \ No newline at end of file diff --git a/Networking/colink-vt-dummy.h b/Networking/colink-vt-dummy.h new file mode 100644 index 000000000..16eb3dc5b --- /dev/null +++ b/Networking/colink-vt-dummy.h @@ -0,0 +1,30 @@ +#ifndef COLINK_VT_DUMMY_H +#define COLINK_VT_DUMMY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "picosha2.h" + +using namespace std; + +// dummy helper functions +void _save(const string &key, const vector &payload); +vector _load(const string &key); +// exposed dummy functions +void set_variable(const string &task_id, + const string &key, + const vector &payload, + const string &sender, + const vector &receivers); +vector get_variable(const string &task_id, + const string &key, + const string &sender, + const string &receiver); + +#endif // COLINK_VT_DUMMY_H \ No newline at end of file diff --git a/Networking/picosha2.h b/Networking/picosha2.h new file mode 100644 index 000000000..bb5d4421b --- /dev/null +++ b/Networking/picosha2.h @@ -0,0 +1,379 @@ +/* +The MIT License (MIT) + +Copyright (C) 2017 okdshin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +Github Link: https://github.com/okdshin/PicoSHA2/blob/master/picosha2.h +*/ +#ifndef PICOSHA2_H +#define PICOSHA2_H +// picosha2:20140213 + +#ifndef PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR +#define PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR \ + 1048576 //=1024*1024: default is 1MB memory +#endif + +#include +#include +#include +#include +#include +#include +namespace picosha2 { +typedef unsigned long word_t; +typedef unsigned char byte_t; + +static const size_t k_digest_size = 32; + +namespace detail { +inline byte_t mask_8bit(byte_t x) { return x & 0xff; } + +inline word_t mask_32bit(word_t x) { return x & 0xffffffff; } + +const word_t add_constant[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; + +const word_t initial_message_digest[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, + 0xa54ff53a, 0x510e527f, 0x9b05688c, + 0x1f83d9ab, 0x5be0cd19}; + +inline word_t ch(word_t x, word_t y, word_t z) { return (x & y) ^ ((~x) & z); } + +inline word_t maj(word_t x, word_t y, word_t z) { + return (x & y) ^ (x & z) ^ (y & z); +} + +inline word_t rotr(word_t x, std::size_t n) { + assert(n < 32); + return mask_32bit((x >> n) | (x << (32 - n))); +} + +inline word_t bsig0(word_t x) { return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22); } + +inline word_t bsig1(word_t x) { return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25); } + +inline word_t shr(word_t x, std::size_t n) { + assert(n < 32); + return x >> n; +} + +inline word_t ssig0(word_t x) { return rotr(x, 7) ^ rotr(x, 18) ^ shr(x, 3); } + +inline word_t ssig1(word_t x) { return rotr(x, 17) ^ rotr(x, 19) ^ shr(x, 10); } + +template +void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last) { + assert(first + 64 == last); + static_cast(last); // for avoiding unused-variable warning + word_t w[64]; + std::fill(w, w + 64, 0); + for (std::size_t i = 0; i < 16; ++i) { + w[i] = (static_cast(mask_8bit(*(first + i * 4))) << 24) | + (static_cast(mask_8bit(*(first + i * 4 + 1))) << 16) | + (static_cast(mask_8bit(*(first + i * 4 + 2))) << 8) | + (static_cast(mask_8bit(*(first + i * 4 + 3)))); + } + for (std::size_t i = 16; i < 64; ++i) { + w[i] = mask_32bit(ssig1(w[i - 2]) + w[i - 7] + ssig0(w[i - 15]) + + w[i - 16]); + } + + word_t a = *message_digest; + word_t b = *(message_digest + 1); + word_t c = *(message_digest + 2); + word_t d = *(message_digest + 3); + word_t e = *(message_digest + 4); + word_t f = *(message_digest + 5); + word_t g = *(message_digest + 6); + word_t h = *(message_digest + 7); + + for (std::size_t i = 0; i < 64; ++i) { + word_t temp1 = h + bsig1(e) + ch(e, f, g) + add_constant[i] + w[i]; + word_t temp2 = bsig0(a) + maj(a, b, c); + h = g; + g = f; + f = e; + e = mask_32bit(d + temp1); + d = c; + c = b; + b = a; + a = mask_32bit(temp1 + temp2); + } + *message_digest += a; + *(message_digest + 1) += b; + *(message_digest + 2) += c; + *(message_digest + 3) += d; + *(message_digest + 4) += e; + *(message_digest + 5) += f; + *(message_digest + 6) += g; + *(message_digest + 7) += h; + for (std::size_t i = 0; i < 8; ++i) { + *(message_digest + i) = mask_32bit(*(message_digest + i)); + } +} + +} // namespace detail + +template +void output_hex(InIter first, InIter last, std::ostream& os) { + os.setf(std::ios::hex, std::ios::basefield); + while (first != last) { + os.width(2); + os.fill('0'); + os << static_cast(*first); + ++first; + } + os.setf(std::ios::dec, std::ios::basefield); +} + +template +void bytes_to_hex_string(InIter first, InIter last, std::string& hex_str) { + std::ostringstream oss; + output_hex(first, last, oss); + hex_str.assign(oss.str()); +} + +template +void bytes_to_hex_string(const InContainer& bytes, std::string& hex_str) { + bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str); +} + +template +std::string bytes_to_hex_string(InIter first, InIter last) { + std::string hex_str; + bytes_to_hex_string(first, last, hex_str); + return hex_str; +} + +template +std::string bytes_to_hex_string(const InContainer& bytes) { + std::string hex_str; + bytes_to_hex_string(bytes, hex_str); + return hex_str; +} + +class hash256_one_by_one { + public: + hash256_one_by_one() { init(); } + + void init() { + buffer_.clear(); + std::fill(data_length_digits_, data_length_digits_ + 4, 0); + std::copy(detail::initial_message_digest, + detail::initial_message_digest + 8, h_); + } + + template + void process(RaIter first, RaIter last) { + add_to_data_length(static_cast(std::distance(first, last))); + std::copy(first, last, std::back_inserter(buffer_)); + std::size_t i = 0; + for (; i + 64 <= buffer_.size(); i += 64) { + detail::hash256_block(h_, buffer_.begin() + i, + buffer_.begin() + i + 64); + } + buffer_.erase(buffer_.begin(), buffer_.begin() + i); + } + + void finish() { + byte_t temp[64]; + std::fill(temp, temp + 64, 0); + std::size_t remains = buffer_.size(); + std::copy(buffer_.begin(), buffer_.end(), temp); + temp[remains] = 0x80; + + if (remains > 55) { + std::fill(temp + remains + 1, temp + 64, 0); + detail::hash256_block(h_, temp, temp + 64); + std::fill(temp, temp + 64 - 4, 0); + } else { + std::fill(temp + remains + 1, temp + 64 - 4, 0); + } + + write_data_bit_length(&(temp[56])); + detail::hash256_block(h_, temp, temp + 64); + } + + template + void get_hash_bytes(OutIter first, OutIter last) const { + for (const word_t* iter = h_; iter != h_ + 8; ++iter) { + for (std::size_t i = 0; i < 4 && first != last; ++i) { + *(first++) = detail::mask_8bit( + static_cast((*iter >> (24 - 8 * i)))); + } + } + } + + private: + void add_to_data_length(word_t n) { + word_t carry = 0; + data_length_digits_[0] += n; + for (std::size_t i = 0; i < 4; ++i) { + data_length_digits_[i] += carry; + if (data_length_digits_[i] >= 65536u) { + carry = data_length_digits_[i] >> 16; + data_length_digits_[i] &= 65535u; + } else { + break; + } + } + } + void write_data_bit_length(byte_t* begin) { + word_t data_bit_length_digits[4]; + std::copy(data_length_digits_, data_length_digits_ + 4, + data_bit_length_digits); + + // convert byte length to bit length (multiply 8 or shift 3 times left) + word_t carry = 0; + for (std::size_t i = 0; i < 4; ++i) { + word_t before_val = data_bit_length_digits[i]; + data_bit_length_digits[i] <<= 3; + data_bit_length_digits[i] |= carry; + data_bit_length_digits[i] &= 65535u; + carry = (before_val >> (16 - 3)) & 65535u; + } + + // write data_bit_length + for (int i = 3; i >= 0; --i) { + (*begin++) = static_cast(data_bit_length_digits[i] >> 8); + (*begin++) = static_cast(data_bit_length_digits[i]); + } + } + std::vector buffer_; + word_t data_length_digits_[4]; // as 64bit integer (16bit x 4 integer) + word_t h_[8]; +}; + +inline void get_hash_hex_string(const hash256_one_by_one& hasher, + std::string& hex_str) { + byte_t hash[k_digest_size]; + hasher.get_hash_bytes(hash, hash + k_digest_size); + return bytes_to_hex_string(hash, hash + k_digest_size, hex_str); +} + +inline std::string get_hash_hex_string(const hash256_one_by_one& hasher) { + std::string hex_str; + get_hash_hex_string(hasher, hex_str); + return hex_str; +} + +namespace impl { +template +void hash256_impl(RaIter first, RaIter last, OutIter first2, OutIter last2, int, + std::random_access_iterator_tag) { + hash256_one_by_one hasher; + // hasher.init(); + hasher.process(first, last); + hasher.finish(); + hasher.get_hash_bytes(first2, last2); +} + +template +void hash256_impl(InputIter first, InputIter last, OutIter first2, + OutIter last2, int buffer_size, std::input_iterator_tag) { + std::vector buffer(buffer_size); + hash256_one_by_one hasher; + // hasher.init(); + while (first != last) { + int size = buffer_size; + for (int i = 0; i != buffer_size; ++i, ++first) { + if (first == last) { + size = i; + break; + } + buffer[i] = *first; + } + hasher.process(buffer.begin(), buffer.begin() + size); + } + hasher.finish(); + hasher.get_hash_bytes(first2, last2); +} +} + +template +void hash256(InIter first, InIter last, OutIter first2, OutIter last2, + int buffer_size = PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR) { + picosha2::impl::hash256_impl( + first, last, first2, last2, buffer_size, + typename std::iterator_traits::iterator_category()); +} + +template +void hash256(InIter first, InIter last, OutContainer& dst) { + hash256(first, last, dst.begin(), dst.end()); +} + +template +void hash256(const InContainer& src, OutIter first, OutIter last) { + hash256(src.begin(), src.end(), first, last); +} + +template +void hash256(const InContainer& src, OutContainer& dst) { + hash256(src.begin(), src.end(), dst.begin(), dst.end()); +} + +template +void hash256_hex_string(InIter first, InIter last, std::string& hex_str) { + byte_t hashed[k_digest_size]; + hash256(first, last, hashed, hashed + k_digest_size); + std::ostringstream oss; + output_hex(hashed, hashed + k_digest_size, oss); + hex_str.assign(oss.str()); +} + +template +std::string hash256_hex_string(InIter first, InIter last) { + std::string hex_str; + hash256_hex_string(first, last, hex_str); + return hex_str; +} + +inline void hash256_hex_string(const std::string& src, std::string& hex_str) { + hash256_hex_string(src.begin(), src.end(), hex_str); +} + +template +void hash256_hex_string(const InContainer& src, std::string& hex_str) { + hash256_hex_string(src.begin(), src.end(), hex_str); +} + +template +std::string hash256_hex_string(const InContainer& src) { + return hash256_hex_string(src.begin(), src.end()); +} +templatevoid hash256(std::ifstream& f, OutIter first, OutIter last){ + hash256(std::istreambuf_iterator(f), std::istreambuf_iterator(), first,last); + +} +}// namespace picosha2 +#endif // PICOSHA2_H \ No newline at end of file diff --git a/Processor/Machine.hpp b/Processor/Machine.hpp index d72a57849..b27127137 100644 --- a/Processor/Machine.hpp +++ b/Processor/Machine.hpp @@ -431,8 +431,12 @@ void Machine::run(const string &progname) { bundle.mine.store(comm_stats.sent); P.Broadcast_Receive_no_stats(bundle); size_t global = 0; - for (auto &os : bundle) - global += os.get_int(8); + for (int i = 0; i < P.num_players(); i++) { + if (P.N.get_name(i).empty()) continue; + global += bundle[i].get_int(8); + } +// for (auto &os : bundle) +// global += os.get_int(8); cerr << "Global data sent = " << global / 1e6 << " MB (all parties)" << endl; #ifdef VERBOSE_OPTIONS diff --git a/Protocols/MaliciousShamirMC.hpp b/Protocols/MaliciousShamirMC.hpp index 7f66215d5..c8805c32f 100644 --- a/Protocols/MaliciousShamirMC.hpp +++ b/Protocols/MaliciousShamirMC.hpp @@ -21,11 +21,22 @@ void MaliciousShamirMC::init_open(const Player& P, int n) reconstructions.resize(2 * threshold + 2); for (int i = threshold + 1; i <= 2 * threshold + 1; i++) { - reconstructions[i].resize(i); - for (int j = 0; j < i; j++) - reconstructions[i][j] = - Shamir::get_rec_factor(P.get_player(j), - P.num_players(), P.my_num(), i); + int cnt = 0; + for (int j = 0; j < i; j++, cnt++) { + while (P.N.get_name(P.get_player(cnt)).empty()) cnt++; + } + reconstructions[i].resize(cnt); + for (int j = 0; j < cnt; j++) { + if (P.N.get_name(P.get_player(j)).empty()) continue; + int _i = P.get_player(j); + reconstructions[i][j] = 1; + for (int k = 0; k < cnt; k++) { + if (P.N.get_name(P.get_player(k)).empty()) continue; + int other = positive_modulo(P.my_num() + k, P.num_players()); + if (_i != other) + reconstructions[i][j] *= open_type(other + 1) / (open_type(other + 1) - open_type(_i + 1)); + } + } } } @@ -37,8 +48,14 @@ typename T::open_type MaliciousShamirMC::finalize_raw() { int threshold = ShamirMachine::s().threshold; shares.resize(2 * threshold + 1); - for (size_t j = 0; j < shares.size(); j++) - shares[j].unpack((*this->os)[this->player->get_player(j)]); + int idx = 0, ofs = 0; + for (size_t j = 0; j < shares.size(); j++) { + do { + idx = this->player->get_player(ofs); + ++ofs; + } while (this->player->N.get_name(idx).empty()); + shares[j].unpack((*this->os)[idx]); + } return reconstruct(shares); } @@ -48,15 +65,25 @@ typename T::open_type MaliciousShamirMC::reconstruct( { int threshold = ShamirMachine::s().threshold; typename T::open_type value = 0; - for (int j = 0; j < threshold + 1; j++) - value += shares[j] * reconstructions[threshold + 1][j]; + for (int j = 0, ofs = 0, idx = this->player->get_player(ofs); j < threshold + 1; j++, ofs++, idx = this->player->get_player(ofs)) { + while (this->player->N.get_name(idx).empty()) { + ofs++; + idx = this->player->get_player(ofs); + } + value += shares[j] * reconstructions[threshold + 1][ofs]; + } for (size_t j = threshold + 2; j <= shares.size(); j++) { typename T::open_type check = 0; - for (size_t k = 0; k < j; k++) - check += shares[k] * reconstructions[j][k]; + for (size_t k = 0, ofs = 0, idx = this->player->get_player(ofs); k < j; k++, ofs++, idx = this->player->get_player(ofs)) { + while (this->player->N.get_name(idx).empty()) { + ofs++; + idx = this->player->get_player(ofs); + } + check += shares[k] * reconstructions[j][ofs]; + } if (check != value) throw mac_fail("inconsistent Shamir secret sharing"); } return value; -} +} \ No newline at end of file diff --git a/Protocols/Shamir.hpp b/Protocols/Shamir.hpp index fe1cd6be3..ca49a57d5 100644 --- a/Protocols/Shamir.hpp +++ b/Protocols/Shamir.hpp @@ -253,12 +253,17 @@ vector Shamir::get_randoms(PRNG& G, int t) { inputs.clear(); for (int j = 0; j < P.num_players(); j++) - inputs.push_back(input.finalize(j)); + if (!P.N.get_name(j).empty()) inputs.push_back(input.finalize(j)); for (size_t j = 0; j < hyper.size(); j++) { random.push_back({}); + int idx = 0; for (int k = 0; k < P.num_players(); k++) - random.back() += hyper[j][k] * inputs[k]; + if (!P.N.get_name(k).empty()) { + // TODO: not sure how to deal with hyper + random.back() += hyper[j][k] * inputs[idx]; + idx++; + } } } return random; diff --git a/Protocols/ShamirInput.hpp b/Protocols/ShamirInput.hpp index 6d9992ad7..6d7f1a7ec 100644 --- a/Protocols/ShamirInput.hpp +++ b/Protocols/ShamirInput.hpp @@ -123,6 +123,7 @@ template void IndividualInput::finalize_other(int player, T& target, octetStream& o, int n_bits) { + if (P.N.get_name(player).empty()) return; (void) player; target.unpack(o, n_bits); } diff --git a/Protocols/ShamirMC.hpp b/Protocols/ShamirMC.hpp index 7238aa5ef..14687510a 100644 --- a/Protocols/ShamirMC.hpp +++ b/Protocols/ShamirMC.hpp @@ -90,10 +90,29 @@ template void ShamirMC::exchange(const Player& P) { vector my_senders(P.num_players()), my_receivers(P.num_players()); +// for (int i = 0; i < P.num_players(); i++) +// { +// my_senders[i] = P.get_offset(i) <= threshold; +// my_receivers[i] = P.get_offset(i) >= P.num_players() - threshold; +// } +// for (int i = 0, ofs = 0, idx = P.get_player(ofs); i <= threshold; i++) { +// my_senders[idx] = 1; +// do { +// ofs++; +// idx = P.get_player(ofs); +// } while (P.N.get_name(idx).empty()); +// } +// for (int i = 0, ofs = P.num_players() - 1, idx = P.get_player(ofs); i < P.num_players() - threshold; i++, ofs--, idx = P.get_player(ofs)) { +// while (P.N.get_name(idx).empty()) { +// ofs--; +// idx = P.get_player(ofs); +// } +// my_receivers[idx] = 1; +// } for (int i = 0; i < P.num_players(); i++) { - my_senders[i] = P.get_offset(i) <= threshold; - my_receivers[i] = P.get_offset(i) >= P.num_players() - threshold; + my_senders[i] = true; + my_receivers[i] = true; } P.partial_broadcast(my_senders, my_receivers, *os); } diff --git a/Tools/Subroutines.hpp b/Tools/Subroutines.hpp index d4065090f..139d9e0cc 100644 --- a/Tools/Subroutines.hpp +++ b/Tools/Subroutines.hpp @@ -27,7 +27,7 @@ void Create_Random(T& ans,const Player& P) ans.assign_zero(); for (int i = 0; i < P.num_players(); i++) - { if (i != P.my_num()) + { if (i != P.my_num() && !P.N.get_name(i).empty()) { if (!Open(ee,Comm_e[i],Open_e[i],i)) { throw invalid_commitment(); } e[i].unpack(ee); diff --git a/Tools/octetStream.cpp b/Tools/octetStream.cpp index 2955becbf..0425be7dc 100644 --- a/Tools/octetStream.cpp +++ b/Tools/octetStream.cpp @@ -14,6 +14,8 @@ #include "Tools/time-func.h" #include "Tools/FlexBuffer.h" +#include "Networking/data.h" +#include "Networking/colink-vt-dummy.h" void octetStream::reset() { @@ -265,3 +267,37 @@ void octetStreams::reset(const Player& P) template void octetStream::exchange(int, int, octetStream&) const; template void octetStream::exchange(ssl_socket*, ssl_socket*, octetStream&) const; + + +void octetStream::Send(string sender, string receiver, int cnt) const +{ + octet blen[LENGTH_SIZE]; + encode_length(blen, len, LENGTH_SIZE); + vector vlen(blen, blen + LENGTH_SIZE); + set_variable("T0", "len" + sender + receiver + to_string(cnt), vlen, sender, {receiver}); + vector vdata(data, data + len); + set_variable("T0", "data" + sender + receiver + to_string(cnt), vdata, sender, {receiver}); +} + +void octetStream::Receive(string sender, string receiver, int cnt) +{ + auto vlen = get_variable("T0", "len" + sender + receiver + to_string(cnt), sender, receiver); + while (vlen.size() != LENGTH_SIZE) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + vlen = get_variable("T0", "len" + sender + receiver + to_string(cnt), sender, receiver); + } + octet blen[LENGTH_SIZE]; + std::copy(vlen.begin(), vlen.end(), blen); + size_t nlen = decode_length(blen, LENGTH_SIZE); + len=0; + resize_min(nlen); + len=nlen; + + vector vdata = get_variable("T0", "data" + sender + receiver + to_string(cnt), sender, receiver); + while (vdata.size() != len) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + vdata = get_variable("T0", "data" + sender + receiver + to_string(cnt), sender, receiver); + } + std::copy(vdata.begin(), vdata.end(), data); + reset_read_head(); +} diff --git a/Tools/octetStream.h b/Tools/octetStream.h index 96af81917..1b8093c0d 100644 --- a/Tools/octetStream.h +++ b/Tools/octetStream.h @@ -215,9 +215,11 @@ class octetStream /// Send on ``socket_num`` template void Send(T socket_num) const; + void Send(string sender, string receiver, int cnt) const; /// Receive on ``socket_num``, overwriting current content template void Receive(T socket_num); + void Receive(string sender, string receiver, int cnt); /// Input from stream, overwriting current content void input(istream& s); diff --git a/docker-compose.yml b/docker-compose.yml index 85e31476e..59e9ab2e6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,8 @@ services: cryptoplayers: 3 gfp_mod_sz: 4 compile_options: "-v -C --field=256" - src: average + src: tutorial + platform: "linux/amd64" environment: PREP_DIR: ${PREP_DIR} PRIME: ${PRIME} @@ -24,3 +25,15 @@ services: - ./Makefile:/usr/src/MP-SPDZ/Makefile - ./Programs/Source:/usr/src/MP-SPDZ/Programs/Source - ./Scripts:/usr/src/MP-SPDZ/Scripts + - ./Networking:/usr/src/MP-SPDZ/Networking + - ./Machines:/usr/src/MP-SPDZ/Machines + - ./Protocols:/usr/src/MP-SPDZ/Protocols + - ./Processor:/usr/src/MP-SPDZ/Processor + - ./Math:/usr/src/MP-SPDZ/Math + - ./Tools:/usr/src/MP-SPDZ/Tools + - ./log_0.txt:/usr/src/MP-SPDZ/log_0.txt + - ./log_1.txt:/usr/src/MP-SPDZ/log_1.txt + - ./log_2.txt:/usr/src/MP-SPDZ/log_2.txt + - ./log_3.txt:/usr/src/MP-SPDZ/log_3.txt + - ./mal-shamir-offline.x:/usr/src/MP-SPDZ/mal-shamir-offline.x + command: tail -F anything diff --git a/mal-shamir-offline.yml b/mal-shamir-offline.yml index f43adf70b..94f23bb1d 100644 --- a/mal-shamir-offline.yml +++ b/mal-shamir-offline.yml @@ -7,7 +7,8 @@ services: context: . dockerfile: Dockerfile args: - program: mal-shamir-offline.x + machine: mal-shamir-offline.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler @@ -23,7 +24,8 @@ services: context: . dockerfile: Dockerfile args: - program: mal-shamir-offline.x + machine: mal-shamir-offline.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler @@ -39,7 +41,8 @@ services: context: . dockerfile: Dockerfile args: - program: mal-shamir-offline.x + machine: mal-shamir-offline.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler @@ -55,7 +58,8 @@ services: context: . dockerfile: Dockerfile args: - program: mal-shamir-offline.x + machine: mal-shamir-offline.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler diff --git a/malicious-shamir-party.yml b/malicious-shamir-party.yml index 9767ddca0..493c32282 100644 --- a/malicious-shamir-party.yml +++ b/malicious-shamir-party.yml @@ -7,7 +7,8 @@ services: context: . dockerfile: Dockerfile args: - program: malicious-shamir-party.x + machine: malicious-shamir-party.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler @@ -24,7 +25,8 @@ services: context: . dockerfile: Dockerfile args: - program: malicious-shamir-party.x + machine: malicious-shamir-party.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler @@ -41,7 +43,8 @@ services: context: . dockerfile: Dockerfile args: - program: malicious-shamir-party.x + machine: malicious-shamir-party.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler @@ -58,7 +61,8 @@ services: context: . dockerfile: Dockerfile args: - program: malicious-shamir-party.x + machine: malicious-shamir-party.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler diff --git a/random-shamir.yml b/random-shamir.yml index 8a7e14ea3..57977bee9 100644 --- a/random-shamir.yml +++ b/random-shamir.yml @@ -7,7 +7,8 @@ services: context: . dockerfile: Dockerfile args: - program: random-shamir.x + machine: random-shamir.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler @@ -15,7 +16,7 @@ services: - ./Makefile:/usr/src/MP-SPDZ/Makefile - ./Programs/Source:/usr/src/MP-SPDZ/Programs/Source - ./Scripts:/usr/src/MP-SPDZ/Scripts - - /tmp/shamir/p0:${PREP_DIR} +# - /tmp/shamir/p0:${PREP_DIR} command: | random-shamir.x -i 0 -N 4 -T 1 --nshares 10000 --prep-dir ${PREP_DIR} --host player0 @@ -25,7 +26,8 @@ services: context: . dockerfile: Dockerfile args: - program: random-shamir.x + machine: random-shamir.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler @@ -33,7 +35,7 @@ services: - ./Makefile:/usr/src/MP-SPDZ/Makefile - ./Programs/Source:/usr/src/MP-SPDZ/Programs/Source - ./Scripts:/usr/src/MP-SPDZ/Scripts - - /tmp/shamir/p1:${PREP_DIR} +# - /tmp/shamir/p1:${PREP_DIR} command: | random-shamir.x -i 1 -N 4 -T 1 --nshares 10000 --prep-dir ${PREP_DIR} --host player0 @@ -43,7 +45,8 @@ services: context: . dockerfile: Dockerfile args: - program: random-shamir.x + machine: random-shamir.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler @@ -51,7 +54,7 @@ services: - ./Makefile:/usr/src/MP-SPDZ/Makefile - ./Programs/Source:/usr/src/MP-SPDZ/Programs/Source - ./Scripts:/usr/src/MP-SPDZ/Scripts - - /tmp/shamir/p2:${PREP_DIR} +# - /tmp/shamir/p2:${PREP_DIR} command: | random-shamir.x -i 2 -N 4 -T 1 --nshares 10000 --prep-dir ${PREP_DIR} --host player0 @@ -61,7 +64,8 @@ services: context: . dockerfile: Dockerfile args: - program: random-shamir.x + machine: random-shamir.x + platform: "linux/amd64" working_dir: /usr/src/MP-SPDZ volumes: - ./Compiler:/usr/src/MP-SPDZ/Compiler @@ -69,6 +73,6 @@ services: - ./Makefile:/usr/src/MP-SPDZ/Makefile - ./Programs/Source:/usr/src/MP-SPDZ/Programs/Source - ./Scripts:/usr/src/MP-SPDZ/Scripts - - /tmp/shamir/p3:${PREP_DIR} +# - /tmp/shamir/p3:${PREP_DIR} command: | random-shamir.x -i 3 -N 4 -T 1 --nshares 10000 --prep-dir ${PREP_DIR} --host player0