From f6ed227073e4e4dccfb1f3f6ad2104b048facb78 Mon Sep 17 00:00:00 2001 From: armin Date: Wed, 25 Apr 2018 23:37:19 +0200 Subject: [PATCH] Success/Failure for work packages Repeat working, send succ/fail msg for work package, added succ/fail facility --- bfclient/.gitignore | 3 +- bfclient/src/bf/Brainflyer.cpp | 47 +++++++++----- bfclient/src/bf/Brainflyer.h | 2 +- bfclient/src/bfclient.cpp | 6 +- bfclient/src/comm/Comm.cpp | 65 +++++++++++++++++-- bfclient/src/comm/Comm.h | 3 +- bfclient/src/comm/Work.cpp | 4 ++ bfclient/src/comm/Work.h | 6 +- bfclient/src/util/bytestr.cpp | 4 ++ bfclient/src/util/bytestr.h | 2 + cnc/src/main/java/org/btcollider/cnc/CnC.java | 2 +- .../org/btcollider/cnc/comm/ClientWorker.java | 46 ++++++++++--- .../org/btcollider/cnc/keysrv/KeyServer.java | 27 +++++--- 13 files changed, 166 insertions(+), 51 deletions(-) diff --git a/bfclient/.gitignore b/bfclient/.gitignore index ca5cc90..0b190ab 100644 --- a/bfclient/.gitignore +++ b/bfclient/.gitignore @@ -1,3 +1,4 @@ /Debug/ /Release/ -.clang-format \ No newline at end of file +.clang-format +/RelOpt/ diff --git a/bfclient/src/bf/Brainflyer.cpp b/bfclient/src/bf/Brainflyer.cpp index 7b3ecf6..8eba8a7 100644 --- a/bfclient/src/bf/Brainflyer.cpp +++ b/bfclient/src/bf/Brainflyer.cpp @@ -39,18 +39,26 @@ void Brainflyer::operator()() { comm::Work work; - try { - work = comm.getWork(); - } catch (runtime_error& e) { - log("Failed to retrieve work: ", e.what()); - return; - } + while (true) { + try { + work = comm.getWork(); + } catch (runtime_error& e) { + log("Failed to retrieve work: ", e.what()); + return; + } - log("Got work", work.repr()); - performWork(work); + if (work.isEmpty()) { // no more work available + log("No more work available. Shutting down."); + return; + } + + log("Got work", work.repr()); + performWork(work); + comm.sendResult(work); + } } -void Brainflyer::performWork(comm::Work work) { +void Brainflyer::performWork(comm::Work& work) { // brainflayer compatibility args int nopt_mod = 1; @@ -72,25 +80,28 @@ void Brainflyer::performWork(comm::Work work) { long keys = 0; while (!work_end) { secp256k1_ec_pubkey_batch_incr(4096, nopt_mod, pub_batch, priv_batch, priv); - + keys += 4096; memcpy(priv, priv_batch[4096 - 1], 32); // set next starting key - int i = checkBatch(pub_batch, 4096); + size_t ch_batch_size = + work.total >= keys ? 4096 : work.total - (keys - 4096); + int i = checkBatch(pub_batch, ch_batch_size); if (i != -1) { - util::bytestr b_priv(priv_batch[i], 32); + work.key = util::bytestr(priv_batch[i], 32); log("Key found", util::bytestr(priv_batch[i], 32)); } + work_end = true; for (int i = 0; i < 32; i++) { - if (priv[i] > priv_to[i]) { - work_end = true; - break; - } else if (priv[i] < priv_to[i]) { + if (priv[i] < priv_to[i]) { work_end = false; break; - } // equal: continue + } else if (priv[i] > priv_to[i]) { // greater: work_end reached + break; + } // equal: work_end reached } - keys += 4096; + + log(keys, "checked"); } log(keys, "checked"); diff --git a/bfclient/src/bf/Brainflyer.h b/bfclient/src/bf/Brainflyer.h index ee5a9df..d86590a 100644 --- a/bfclient/src/bf/Brainflyer.h +++ b/bfclient/src/bf/Brainflyer.h @@ -31,7 +31,7 @@ class Brainflyer { int checkBatch(unsigned char (*pub_batch)[65], size_t batch_size); void dumpBatch(unsigned char (*pub_batch)[65], unsigned char (*priv_batch)[32]); - void performWork(comm::Work work); + void performWork(comm::Work& work); /* * Log facilities diff --git a/bfclient/src/bfclient.cpp b/bfclient/src/bfclient.cpp index ab236ee..e50200f 100644 --- a/bfclient/src/bfclient.cpp +++ b/bfclient/src/bfclient.cpp @@ -17,10 +17,10 @@ using namespace std; #define BATCH_MAX 4096 -#define WIN_SIZE 16 +#define WIN_SIZE 21 int main() { - util::bytestr key("b907c3a2a3b27789dfb509b730dd47703c272868"); + util::bytestr key("db53d9bbd1f3a83b094eeca7dd970bd85b492fa2"); cout << "Initializing precomputation table" << endl; // init with window size 16, not reading from file @@ -35,7 +35,7 @@ int main() { thread* threads = new thread[numThreads]; cout << "Starting " << numThreads << " threads" << endl; - // numThreads = 1; + numThreads = 1; for (unsigned int i = 0; i < numThreads; i++) { threads[i] = thread{bf::Brainflyer(i, "127.0.0.1", 26765, key)}; } diff --git a/bfclient/src/comm/Comm.cpp b/bfclient/src/comm/Comm.cpp index e4bcff9..66eaea4 100644 --- a/bfclient/src/comm/Comm.cpp +++ b/bfclient/src/comm/Comm.cpp @@ -23,13 +23,7 @@ using namespace std; Comm::Comm(string host, int port) : port(port), host(host), sock(-1) {} Work Comm::getWork(void) { - if (sock < 0) { - if (!conn()) { - ostringstream o; - o << "Connection to " << host << ":" << port << " failed"; - throw runtime_error(o.str()); - } - } + checkConn(); const char cmd[] = "WRK\n"; if (send(sock, cmd, strlen(cmd), 0) < 0) { @@ -42,12 +36,69 @@ Work Comm::getWork(void) { throw runtime_error("Receiving of work failed"); } + buf[wrk_len] = '\0'; + + if (!strcmp(buf, "NIL\n")) return (Work()); + string ws = string(buf, wrk_len - 1); Work wrk(ws); return (wrk); } +void Comm::sendResult(Work work) { + checkConn(); + + const char cmd[] = "RES\n"; + if (send(sock, cmd, strlen(cmd), 0) < 0) { + throw runtime_error("Sending RES failed"); + } + + string res = work.from.toHex() + " " + work.to.toHex() + " " + "\n"; + if (send(sock, res.c_str(), res.size(), 0) < 0) { + throw runtime_error("Sending work result failed"); + } + + char buf[1024]; + ssize_t ack_len; + if ((ack_len = recv(sock, buf, 1024, 0)) < 0) { + throw runtime_error("Receiving ACK failed"); + } + + if (work.key.isEmpty()) { + if (send(sock, "NIL\n", 4, 0) < 0) { + throw runtime_error("Sending NIL ailed"); + } + } else { + if (send(sock, "SUC\n", 4, 0) < 0) { + throw runtime_error("Sending SUC failed"); + } + + if ((ack_len = recv(sock, buf, 1024, 0)) < 0) { + throw runtime_error("Receiving ACK failed"); + } + + string key = work.key.toHex() + "\n"; + if (send(sock, key.c_str(), key.length(), 0) < 0) { + throw runtime_error("Sending key failed"); + } + + if ((ack_len = recv(sock, buf, 1024, 0)) < 0) { + throw runtime_error("Receiving ACK failed"); + } + } +} + +void Comm::checkConn(void) { + if (sock < 0) { + if (!conn()) { + ostringstream o; + o << "Connection to " << host << ":" << port << " failed"; + throw runtime_error(o.str()); + } + } +} + /** * Connects socket to server * diff --git a/bfclient/src/comm/Comm.h b/bfclient/src/comm/Comm.h index 75e53ac..644ffaf 100644 --- a/bfclient/src/comm/Comm.h +++ b/bfclient/src/comm/Comm.h @@ -23,13 +23,14 @@ class Comm { int sock; bool conn(); - std::string retrieve(); + void checkConn(); void disconnect(); public: Comm(std::string host, int port); comm::Work getWork(); + void sendResult(comm::Work work); virtual ~Comm(); }; diff --git a/bfclient/src/comm/Work.cpp b/bfclient/src/comm/Work.cpp index 7980350..d01855e 100644 --- a/bfclient/src/comm/Work.cpp +++ b/bfclient/src/comm/Work.cpp @@ -15,6 +15,8 @@ namespace comm { using namespace std; +Work::Work() : total(0) {} + Work::Work(string work_s) { vector wrk_v = split(work_s, " "); assert(wrk_v.size() == 3); @@ -24,6 +26,8 @@ Work::Work(string work_s) { total = strtol(wrk_v.at(2).c_str(), nullptr, 10); } +bool Work::isEmpty() { return (total <= 0); } + vector Work::split(const string s, const string delimiter) { vector split_str; diff --git a/bfclient/src/comm/Work.h b/bfclient/src/comm/Work.h index 9f8301f..f6c505c 100644 --- a/bfclient/src/comm/Work.h +++ b/bfclient/src/comm/Work.h @@ -20,9 +20,13 @@ class Work { util::bytestr to; long total; - Work() = default; + util::bytestr key; + + Work(); Work(std::string work); + bool isEmpty(); + std::string repr(void); std::vector split(std::string s, std::string delimiter); diff --git a/bfclient/src/util/bytestr.cpp b/bfclient/src/util/bytestr.cpp index f7fab7c..f16a481 100644 --- a/bfclient/src/util/bytestr.cpp +++ b/bfclient/src/util/bytestr.cpp @@ -59,6 +59,10 @@ void bytestr::set(const byte* fromBytes, int len) { } } +bool bytestr::isEmpty(void){ + return bytes.empty(); +} + const byte& bytestr::operator[](const int index) const { return (bytes[index]); } diff --git a/bfclient/src/util/bytestr.h b/bfclient/src/util/bytestr.h index 09afc94..ce7ca64 100644 --- a/bfclient/src/util/bytestr.h +++ b/bfclient/src/util/bytestr.h @@ -31,6 +31,8 @@ class bytestr { void set(const string fromHex); void set(const byte* fromBytes, int len); + bool isEmpty(); + const byte& operator[](const int index) const; size_t size(void) const; diff --git a/cnc/src/main/java/org/btcollider/cnc/CnC.java b/cnc/src/main/java/org/btcollider/cnc/CnC.java index bd5364b..2f50b0b 100644 --- a/cnc/src/main/java/org/btcollider/cnc/CnC.java +++ b/cnc/src/main/java/org/btcollider/cnc/CnC.java @@ -18,7 +18,7 @@ public class CnC { public static final int MAX_BITS = 62; public static void main(String[] args) { - KeyServer.init(19, 3, 1); + KeyServer.init(54, 27, 18000000000l); CommServer server = new CommServer(PORT); try { server.listen(); diff --git a/cnc/src/main/java/org/btcollider/cnc/comm/ClientWorker.java b/cnc/src/main/java/org/btcollider/cnc/comm/ClientWorker.java index b8e8730..7ca1804 100644 --- a/cnc/src/main/java/org/btcollider/cnc/comm/ClientWorker.java +++ b/cnc/src/main/java/org/btcollider/cnc/comm/ClientWorker.java @@ -1,6 +1,8 @@ package org.btcollider.cnc.comm; import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; @@ -86,29 +88,57 @@ public class ClientWorker implements Runnable { ks.setInWork(kr); } - String work = Long.toHexString(kr.getStart()) + " " + Long.toHexString(kr.getEnd()) + " " + kr.getTotal(); - - out.println(work); - - log.debug("Work <{}> sent to {}", work, clientSocket.getInetAddress()); + if (kr == null) { + out.println("NIL"); + log.debug("Stop work sent to {}", clientSocket.getInetAddress()); + } + else { + String work = Long.toHexString(kr.getStart()) + " " + Long.toHexString(kr.getEnd()) + " " + kr.getTotal(); + out.println(work); + log.debug("Work <{}> sent to {}", work, clientSocket.getInetAddress()); + } } private void retrieveResult() { - String[] result; try { - result = in.readLine().split(" "); + String[] result = in.readLine().split(" "); KeyRange kr = new KeyRange(Long.parseLong(result[0], 16), Long.parseLong(result[1], 16)); synchronized (KeyServer.getInstance()) { KeyServer.getInstance().setSearched(kr); } - log.debug("Got result for {}", kr); + log.debug("Keyrange {} searched", kr); + + out.println("ACK"); + + String suc = in.readLine(); + switch (suc) { + case "NIL": + log.debug("Keyrange {} unsuccessful", kr); + break; + case "SUC": + log.info("Keyrange {} successful", kr); + out.println("ACK"); + suc = in.readLine(); + log.info("Found private key {}", suc); + writeKey(suc); + out.println("ACK"); + break; + } } catch (IOException e) { log.error("Couldn't read result", e); } } + + private void writeKey(String key) { + try(BufferedWriter writer = new BufferedWriter(new FileWriter("/home/armin/Desktop/cwkey"))){ + writer.write(key); + }catch(IOException e) { + log.error("Couldn't write key {} to keyfile", key, e); + } + } private void shutDown() { closeCommChannel(); diff --git a/cnc/src/main/java/org/btcollider/cnc/keysrv/KeyServer.java b/cnc/src/main/java/org/btcollider/cnc/keysrv/KeyServer.java index 5db180b..9bfd1df 100644 --- a/cnc/src/main/java/org/btcollider/cnc/keysrv/KeyServer.java +++ b/cnc/src/main/java/org/btcollider/cnc/keysrv/KeyServer.java @@ -51,7 +51,7 @@ public class KeyServer { public KeyRange getRange() { BitSet keyStart = new BitSet(CnC.MAX_BITS); - recCollectKey(root, keyStart, index); + if(!recCollectKey(root, keyStart, index)) return null; BitSet keyEnd = new BitSet(CnC.MAX_BITS); keyEnd.or(keyStart); // set keyEnd to keyStart @@ -78,6 +78,8 @@ public class KeyServer { } public void setInWork(KeyRange keyRange) { + if (keyRange == null) return; + markInWork(BitSet.valueOf(new long[] { keyRange.getStart() })); } @@ -201,7 +203,9 @@ public class KeyServer { assert depth > 0; KeyTree root = new KeyTree(true, null); + log.info("Starting recGenTree"); recGenKeyTree(root, depth - 1); + log.info("Ending recGenTree"); return root; } @@ -222,7 +226,7 @@ public class KeyServer { recGenKeyTree(right, depth - 1); } - private void recCollectKey(KeyTree kt, BitSet keyStart, int curIndex) { + private boolean recCollectKey(KeyTree kt, BitSet keyStart, int curIndex) { assert curIndex > 0; keyStart.set(curIndex, kt.getValue()); @@ -234,33 +238,36 @@ public class KeyServer { if (left.isLeaf() || right.isLeaf()) { assert left.isLeaf() && right.isLeaf(); // fully balanced binary tree by construction + + if (!right.isFree() && ! left.isFree()) return false; + // No choice finish if (!right.isFree()) keyStart.set(curIndex - 1, left.getValue()); else if (!left.isFree()) keyStart.set(curIndex - 1, right.getValue()); - else if (left.isLeaf() && right.isLeaf()) { // Randomized finish + else if (left.isFree() && right.isFree()) { // Randomized finish Random r = new Random(); boolean leftFirst = r.nextBoolean(); if(leftFirst) keyStart.set(curIndex - 1, left.getValue()); else keyStart.set(curIndex - 1, right.getValue()); - } - - return; + } + + return true; } // No choice depth-first traversal if (!left.isFree()) - recCollectKey(right, keyStart, curIndex - 1); + return recCollectKey(right, keyStart, curIndex - 1); else if (!right.isFree()) - recCollectKey(left, keyStart, curIndex - 1); + return recCollectKey(left, keyStart, curIndex - 1); else { // Randomized depth-first traversal Random r = new Random(); boolean leftFirst = r.nextBoolean(); if (leftFirst) - recCollectKey(left, keyStart, curIndex - 1); + return recCollectKey(left, keyStart, curIndex - 1); else - recCollectKey(right, keyStart, curIndex - 1); + return recCollectKey(right, keyStart, curIndex - 1); } }