diff --git a/frontend/ExampleTwoChooseOne.cpp b/frontend/ExampleTwoChooseOne.cpp index 01eeafb..f31a647 100644 --- a/frontend/ExampleTwoChooseOne.cpp +++ b/frontend/ExampleTwoChooseOne.cpp @@ -12,6 +12,8 @@ #include "libOTe/TwoChooseOne/Silent/SilentOtExtSender.h" #include "util.h" #include "coproto/Socket/AsioSocket.h" +#include "cryptoTools/Common/BitVector.h" +#include "cryptoTools/Crypto/PRNG.h" namespace osuCrypto { @@ -203,8 +205,6 @@ namespace osuCrypto } } - // make sure all messages have been sent. - cp::sync_wait(chl.flush()); } else { @@ -302,6 +302,8 @@ namespace osuCrypto } + // make sure all messages have been sent. + cp::sync_wait(chl.flush()); auto e = timer.setTimePoint("finish"); auto milli = std::chrono::duration_cast(e - s).count(); diff --git a/libOTe/Tools/ExConvCode/ExConvChecker.cpp b/libOTe/Tools/ExConvCode/ExConvChecker.cpp index 532d7c3..1f11950 100644 --- a/libOTe/Tools/ExConvCode/ExConvChecker.cpp +++ b/libOTe/Tools/ExConvCode/ExConvChecker.cpp @@ -127,6 +127,7 @@ namespace osuCrypto u64 awEnd = cmd.getOr("awEnd", 20); u64 bwBeing = cmd.getOr("bw", 3); u64 bwEnd = cmd.getOr("bwEnd", 11); + auto x2 = cmd.isSet("x2"); for (u64 aw = awBeing; aw < awEnd; aw += 2) { @@ -137,8 +138,8 @@ namespace osuCrypto u64 avg = 0; u64 gMin = n; std::mutex mtx; - u64 ticks = n * trials; - std::atomic done = 0; + u64 ticks = x2 ? k * k * trials : n * trials; + std::atomic done = 0; auto routine = [&](u64 i) { for (u64 j = i; j < trials; j += nt) { @@ -147,11 +148,25 @@ namespace osuCrypto encoder.config(k, n, bw, aw, sys, reg, block(21341234, j)); encoder.mAccTwice = accTwice; + //auto g = getGenerator(encoder); + //auto g2 = compress(g); + //auto G = getCompressedGenerator(encoder); + //if(std::equal(G.begin(), G.end(), g2.begin()) == false) + // throw RTE_LOC; + u64 min = 0; - if (cmd.isSet("x2")) - min = getGeneratorWeightx2(encoder, verbose); + if (x2) + { + min = getGeneratorWeightx2&>(encoder, verbose, done); + + } else - min = getGeneratorWeight&>(encoder, verbose, done); + { + //min = getGeneratorWeight&>(encoder, verbose, done); + min = getGeneratorWeight2&>(encoder, verbose, done); + //if(min != min2) + // throw RTE_LOC; + } std::lock_guard lock(mtx); gMin = std::min(gMin, min); @@ -166,24 +181,33 @@ namespace osuCrypto } //routine(nt - 1); u64 sleep = 1; + auto start = std::chrono::high_resolution_clock::now(); while (done != ticks) { std::this_thread::sleep_for(std::chrono::milliseconds(sleep)); sleep = std::min(1000, sleep * 2); + u64 curDone = done; + auto end = std::chrono::high_resolution_clock::now(); + auto dur = std::chrono::duration_cast(end - start).count(); + auto ticksPerSec = double(curDone) / dur * 1000; + + auto f = double(curDone) / ticks; + u64 g = f * 40; + u64 p = f * 100; - u64 d = double(done) * 40 / ticks; + u64 sec = p > 2 ? (ticks - curDone) / ticksPerSec : 0; - std::cout << "[" << std::string(d, '|') << std::string(40 - d, ' ') << "] " << double(done) * 100 / ticks << "%\r" << std::flush; + std::cout << "[" << std::string(g, '|') << std::string(40 - g, ' ') << "] " << p << "% "<< sec <<"s\r" << std::flush; } - std::cout < mVal; + + GetGeneratorBatch operator^(const GetGeneratorBatch& b) const + { + GetGeneratorBatch ret; + for (u64 i = 0; i < mVal.size(); ++i) + ret.mVal[i] = mVal[i] ^ b.mVal[i]; + return ret; + } + }; + } template @@ -40,6 +55,39 @@ namespace osuCrypto return g; } + template + Matrix getCompressedGenerator(Code& encoder) + { + auto k = encoder.mMessageSize; + auto n = encoder.mCodeSize;; + Matrix g(k, divCeil(n, 128)); + + u64 batchSize = sizeof(detail::GetGeneratorBatch) * 8; + std::vector x(n); + for (u64 i = 0; i < n; i += batchSize) + { + memset(x.data(), 0, sizeof(x[0]) * x.size()); + + for (u64 p = 0; p < batchSize; ++p) + { + *oc::BitIterator((u8*)&x[i + p], p) = 1; + } + + // encode a batch of batchSize=1024 unit vectors... + encoder.template dualEncode(x.data(), {}); + + u64 mk = divCeil(std::min(batchSize, n - i), 8); + auto i128 = i / 128; + + // x[j,p] is the (i+p)-th bit of the j-th codeword. + // We want g[j, i+p] = x[j,p] + for (u64 j = 0; j < k; ++j) + { + memcpy(g.data(j) + i128, &x[j], mk); + } + } + return g; + } inline Matrix compress(Matrix g) { Matrix G(g.rows(), divCeil(g.cols(), 128)); @@ -73,20 +121,21 @@ namespace osuCrypto return G; } - template - u64 getGeneratorWeightx2(Code& encoder, bool verbose) + template + u64 getGeneratorWeightx2(Code& encoder, bool verbose, Count c = {}) { auto k = encoder.mMessageSize; auto n = encoder.mCodeSize; - auto g = getGenerator(encoder); - auto G = compress(g); + auto G = getCompressedGenerator(encoder); + //auto G = compress(g); u64 min = n; auto N = G.cols(); for (u64 i = 0; i < k; ++i) { for (u64 i2 = 0; i2 < k; ++i2) - { + { + ++c; auto gg = G.data(i); u64 weight = 0; if (i == i2) @@ -111,33 +160,33 @@ namespace osuCrypto } } - if (verbose) - { - std::cout << i << " \n"; - for (u64 j = 0; j < n; ++j) - { - if (g(i, j)) - std::cout << Color::Green << "1" << Color::Default; - else - std::cout << "0"; - } - std::cout << "\n"; + //if (verbose) + //{ + // std::cout << i << " \n"; + // for (u64 j = 0; j < n; ++j) + // { + // if (g(i, j)) + // std::cout << Color::Green << "1" << Color::Default; + // else + // std::cout << "0"; + // } + // std::cout << "\n"; - if (i != i2) - { + // if (i != i2) + // { - std::cout << i2 << " \n"; - for (u64 j = 0; j < n; ++j) - { - if (g(i2, j)) - std::cout << Color::Green << "1" << Color::Default; - else - std::cout << "0"; - } - std::cout << "\n"; - } + // std::cout << i2 << " \n"; + // for (u64 j = 0; j < n; ++j) + // { + // if (g(i2, j)) + // std::cout << Color::Green << "1" << Color::Default; + // else + // std::cout << "0"; + // } + // std::cout << "\n"; + // } - } + //} min = std::min(min, weight); } } @@ -167,4 +216,63 @@ namespace osuCrypto return *std::min_element(weights.begin(), weights.end()); } + + template + u64 getGeneratorWeight2(Code& encoder, bool verbose, Count c = {}) + { + auto k = encoder.mMessageSize; + auto n = encoder.mCodeSize; + //auto g = getGenerator(encoder); + + std::vector weights(k); + //for (u64 i = 0; i < n; ++i) + //{ + // std::vector x(n); + // x[i] = 1; + // encoder.template dualEncode(x.data(), {}); + + // for (u64 j = 0; j < k; ++j) + // { + // weights[j] += x[j]; + // } + // ++c; + //} + //Matrix g(k, divCeil(n, 128)); + + u64 batchSize = sizeof(detail::GetGeneratorBatch) * 8; + std::vector x(n); + for (u64 i = 0; i < n; i += batchSize) + { + memset(x.data(), 0, sizeof(x[0]) * x.size()); + u64 min = std::min(batchSize, n - 1); + + for (u64 p = 0; p < min; ++p) + { + *oc::BitIterator((u8*)&x[i + p], p) = 1; + } + + // encode a batch of batchSize=1024 unit vectors... + encoder.template dualEncode(x.data(), {}); + + u64 mk = divCeil(min, 8); + auto i128 = i / 128; + + // x[j,p] is the (i+p)-th bit of the j-th codeword. + // We want g[j, i+p] = x[j,p] + for (u64 j = 0; j < k; ++j) + { + for (u64 b = 0; b < x[j].mVal.size(); ++b) + { + weights[j] += + popcount(x[j].mVal[b].get(0)) + + popcount(x[j].mVal[b].get(1)); + } + } + + c += min; + } + + return *std::min_element(weights.begin(), weights.end()); + } + } \ No newline at end of file