diff --git a/CMakePresets.json b/CMakePresets.json index 4763fd46..5043240d 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -8,10 +8,11 @@ "generator": "Ninja", "binaryDir": "${sourceDir}/out/build/${presetName}", "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "FETCH_AUTO": true, "ENABLE_ALL_OT": true, - "ENABLE_SSE": false, - "ENABLE_AVX": false, + "ENABLE_SSE": true, + "ENABLE_AVX": true, "ENABLE_BITPOLYMUL": false, "LIBOTE_STD_VER": "17", "CMAKE_PREFIX_PATH": "${sourceDir}/../out/install", @@ -51,7 +52,7 @@ "VERBOSE_FETCH": true, "ENABLE_SSE": true, "ENABLE_AVX": true, - "ENABLE_ASAN": true, + "ENABLE_ASAN": false, "COPROTO_ENABLE_BOOST": true, "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", "CMAKE_PREFIX_PATH": "${sourceDir}/../out/install/${presetName}" diff --git a/cryptoTools b/cryptoTools index 5c1d2b5a..79f0d3e8 160000 --- a/cryptoTools +++ b/cryptoTools @@ -1 +1 @@ -Subproject commit 5c1d2b5afc1d8330f4d09d2b0aed6edd20479a69 +Subproject commit 79f0d3e8dc5af5b02bf04335c30193bbd5186edd diff --git a/libOTe/Tools/ExConvCode/ExConvCode.cpp b/libOTe/Tools/ExConvCode/ExConvCode.cpp index 20ac5647..23710d95 100644 --- a/libOTe/Tools/ExConvCode/ExConvCode.cpp +++ b/libOTe/Tools/ExConvCode/ExConvCode.cpp @@ -297,7 +297,11 @@ namespace osuCrypto u64 j = i + 1; if (width) { - auto xii = _mm_load_ps((float*)(xx + i)); + My__m128 xii; + if constexpr (std::is_same::value) + xii = _mm_load_ps((float*)(xx + i)); + else + xii = _mm_setzero_ps(); if (q + width > qe) { @@ -349,8 +353,15 @@ namespace osuCrypto u64 j = i + 1; if (width) { - auto xii0 = _mm_load_ps((float*)(xx0 + i)); - auto xii1 = _mm_load_ps((float*)(xx1 + i)); + My__m128 xii0, xii1; + if constexpr (std::is_same::value) + xii0 = _mm_load_ps((float*)(xx0 + i)); + else + xii0 = _mm_setzero_ps(); + if constexpr (std::is_same::value) + xii1 = _mm_load_ps((float*)(xx1 + i)); + else + xii1 = _mm_setzero_ps(); if (q + width > qe) { diff --git a/libOTe/Tools/Subfield/ExConvCode.h b/libOTe/Tools/Subfield/ExConvCode.h index c488a4b3..511993eb 100644 --- a/libOTe/Tools/Subfield/ExConvCode.h +++ b/libOTe/Tools/Subfield/ExConvCode.h @@ -90,56 +90,56 @@ namespace osuCrypto::Subfield template void dualEncode(span e, span w) { - if (e.size() != mCodeSize) - throw RTE_LOC; + if (e.size() != mCodeSize) + throw RTE_LOC; - if (w.size() != mMessageSize) - throw RTE_LOC; + if (w.size() != mMessageSize) + throw RTE_LOC; - if (mSystematic) - { - dualEncode(e); - memcpy(w.data(), e.data(), w.size() * sizeof(T)); - setTimePoint("ExConv.encode.memcpy"); - } - else - { + if (mSystematic) + { + dualEncode(e); + memcpy(w.data(), e.data(), w.size() * sizeof(T)); + setTimePoint("ExConv.encode.memcpy"); + } + else + { - setTimePoint("ExConv.encode.begin"); + setTimePoint("ExConv.encode.begin"); - accumulate(e); + accumulate(e); - setTimePoint("ExConv.encode.accumulate"); + setTimePoint("ExConv.encode.accumulate"); - mExpander.expand(e, w); - setTimePoint("ExConv.encode.expand"); - } + mExpander.expand(e, w); + setTimePoint("ExConv.encode.expand"); + } } // Compute e[0,...,k-1] = G * e. template void dualEncode(span e) { - if (e.size() != mCodeSize) - throw RTE_LOC; - - if (mSystematic) - { - auto d = e.subspan(mMessageSize); - setTimePoint("ExConv.encode.begin"); - accumulate(d); - setTimePoint("ExConv.encode.accumulate"); - mExpander.expand(d, e.subspan(0, mMessageSize)); - setTimePoint("ExConv.encode.expand"); - } - else - { - oc::AlignedUnVector w(mMessageSize); - dualEncode(e, w); - memcpy(e.data(), w.data(), w.size() * sizeof(T)); - setTimePoint("ExConv.encode.memcpy"); - - } + if (e.size() != mCodeSize) + throw RTE_LOC; + + if (mSystematic) + { + auto d = e.subspan(mMessageSize); + setTimePoint("ExConv.encode.begin"); + accumulate(d); + setTimePoint("ExConv.encode.accumulate"); + mExpander.expand(d, e.subspan(0, mMessageSize)); + setTimePoint("ExConv.encode.expand"); + } + else + { + oc::AlignedUnVector w(mMessageSize); + dualEncode(e, w); + memcpy(e.data(), w.data(), w.size() * sizeof(T)); + setTimePoint("ExConv.encode.memcpy"); + + } } @@ -147,144 +147,144 @@ namespace osuCrypto::Subfield template void dualEncode2(span e0, span e1) { - if (e0.size() != mCodeSize) - throw RTE_LOC; - if (e1.size() != mCodeSize) - throw RTE_LOC; - - if (mSystematic) - { - auto d0 = e0.subspan(mMessageSize); - auto d1 = e1.subspan(mMessageSize); - setTimePoint("ExConv.encode.begin"); - accumulate(d0, d1); - setTimePoint("ExConv.encode.accumulate"); - mExpander.expand( - d0, d1, - e0.subspan(0, mMessageSize), - e1.subspan(0, mMessageSize)); - setTimePoint("ExConv.encode.expand"); - } - else - { - //oc::AlignedUnVector w0(mMessageSize); - //dualEncode(e, w); - //memcpy(e.data(), w.data(), w.size() * sizeof(T)); - //setTimePoint("ExConv.encode.memcpy"); - - // not impl. - throw RTE_LOC; - - } + if (e0.size() != mCodeSize) + throw RTE_LOC; + if (e1.size() != mCodeSize) + throw RTE_LOC; + + if (mSystematic) + { + auto d0 = e0.subspan(mMessageSize); + auto d1 = e1.subspan(mMessageSize); + setTimePoint("ExConv.encode.begin"); + accumulate(d0, d1); + setTimePoint("ExConv.encode.accumulate"); + mExpander.expand( + d0, d1, + e0.subspan(0, mMessageSize), + e1.subspan(0, mMessageSize)); + setTimePoint("ExConv.encode.expand"); + } + else + { + //oc::AlignedUnVector w0(mMessageSize); + //dualEncode(e, w); + //memcpy(e.data(), w.data(), w.size() * sizeof(T)); + //setTimePoint("ExConv.encode.memcpy"); + + // not impl. + throw RTE_LOC; + + } } // get the expander matrix SparseMtx getB() const { - if (mSystematic) - { - PointList R(mMessageSize, mCodeSize); - auto B = mExpander.getB().points(); + if (mSystematic) + { + PointList R(mMessageSize, mCodeSize); + auto B = mExpander.getB().points(); + + for (auto p : B) + { + R.push_back(p.mRow, mMessageSize + p.mCol); + } + for (u64 i = 0; i < mMessageSize; ++i) + R.push_back(i, i); - for (auto p : B) + return R; + } + else { - R.push_back(p.mRow, mMessageSize + p.mCol); + return mExpander.getB(); } - for (u64 i = 0; i < mMessageSize; ++i) - R.push_back(i, i); - - return R; - } - else - { - return mExpander.getB(); - } } // Get the parity check version of the accumulator SparseMtx getAPar() const { - PRNG prng(mSeed ^ OneBlock); + PRNG prng(mSeed ^ OneBlock); - auto n = mCodeSize - mSystematic * mMessageSize; + auto n = mCodeSize - mSystematic * mMessageSize; - PointList AP(n, n);; - DenseMtx A = DenseMtx::Identity(n); + PointList AP(n, n);; + DenseMtx A = DenseMtx::Identity(n); - block rnd; - u8* __restrict ptr = (u8*)prng.mBuffer.data(); - auto qe = prng.mBuffer.size() * 128; - u64 q = 0; + block rnd; + u8* __restrict ptr = (u8*)prng.mBuffer.data(); + auto qe = prng.mBuffer.size() * 128; + u64 q = 0; - for (u64 i = 0; i < n; ++i) - { - accOne(AP, i, ptr, prng, rnd, q, qe, n); - } - return AP; + for (u64 i = 0; i < n; ++i) + { + accOne(AP, i, ptr, prng, rnd, q, qe, n); + } + return AP; } // get the accumulator matrix SparseMtx getA() const { - auto APar = getAPar(); + auto APar = getAPar(); - auto A = DenseMtx::Identity(mCodeSize); + auto A = DenseMtx::Identity(mCodeSize); - u64 offset = mSystematic ? mMessageSize : 0ull; + u64 offset = mSystematic ? mMessageSize : 0ull; - for (u64 i = 0; i < APar.rows(); ++i) - { - for (auto y : APar.col(i)) + for (u64 i = 0; i < APar.rows(); ++i) { - //std::cout << y << " "; - if (y != i) - { - auto ay = A.row(y + offset); - auto ai = A.row(i + offset); - ay ^= ai; - } + for (auto y : APar.col(i)) + { + //std::cout << y << " "; + if (y != i) + { + auto ay = A.row(y + offset); + auto ai = A.row(i + offset); + ay ^= ai; + } + } + + //std::cout << "\n" << A << std::endl; } - //std::cout << "\n" << A << std::endl; - } - - return A.sparse(); + return A.sparse(); } // Private functions ------------------------------------ inline static void refill(PRNG& prng) { - assert(prng.mBuffer.size() == 256); - //block b[8]; - for (u64 i = 0; i < 256; i += 8) - { - //auto idx = mPrng.mBuffer[i].get(); - block* __restrict b = prng.mBuffer.data() + i; - block* __restrict k = prng.mBuffer.data() + (u8)(i - 8); - //for (u64 j = 0; j < 8; ++j) - //{ - // b = b ^ mPrng.mBuffer.data()[idx[j]]; - //} - b[0] = AES::roundEnc(b[0], k[0]); - b[1] = AES::roundEnc(b[1], k[1]); - b[2] = AES::roundEnc(b[2], k[2]); - b[3] = AES::roundEnc(b[3], k[3]); - b[4] = AES::roundEnc(b[4], k[4]); - b[5] = AES::roundEnc(b[5], k[5]); - b[6] = AES::roundEnc(b[6], k[6]); - b[7] = AES::roundEnc(b[7], k[7]); - - b[0] = b[0] ^ k[0]; - b[1] = b[1] ^ k[1]; - b[2] = b[2] ^ k[2]; - b[3] = b[3] ^ k[3]; - b[4] = b[4] ^ k[4]; - b[5] = b[5] ^ k[5]; - b[6] = b[6] ^ k[6]; - b[7] = b[7] ^ k[7]; - } + assert(prng.mBuffer.size() == 256); + //block b[8]; + for (u64 i = 0; i < 256; i += 8) + { + //auto idx = mPrng.mBuffer[i].get(); + block* __restrict b = prng.mBuffer.data() + i; + block* __restrict k = prng.mBuffer.data() + (u8)(i - 8); + //for (u64 j = 0; j < 8; ++j) + //{ + // b = b ^ mPrng.mBuffer.data()[idx[j]]; + //} + b[0] = AES::roundEnc(b[0], k[0]); + b[1] = AES::roundEnc(b[1], k[1]); + b[2] = AES::roundEnc(b[2], k[2]); + b[3] = AES::roundEnc(b[3], k[3]); + b[4] = AES::roundEnc(b[4], k[4]); + b[5] = AES::roundEnc(b[5], k[5]); + b[6] = AES::roundEnc(b[6], k[6]); + b[7] = AES::roundEnc(b[7], k[7]); + + b[0] = b[0] ^ k[0]; + b[1] = b[1] ^ k[1]; + b[2] = b[2] ^ k[2]; + b[3] = b[3] ^ k[3]; + b[4] = b[4] ^ k[4]; + b[5] = b[5] ^ k[5]; + b[6] = b[6] ^ k[6]; + b[7] = b[7] ^ k[7]; + } } // generate the point list for accumulating row i. @@ -298,155 +298,155 @@ namespace osuCrypto::Subfield u64 qe, u64 size) const { - u64 j = i + 1; - pl.push_back(i, i); - - if (q + mAccumulatorSize > qe) - { - refill(prng); - ptr = (u8*)prng.mBuffer.data(); - q = 0; - } - - - for (u64 k = 0; k < mAccumulatorSize; k += 8, q += 8, j += 8) - { - assert(ptr < (u8*)(prng.mBuffer.data() + prng.mBuffer.size())); - rnd = block::allSame(*ptr); - ++ptr; - - //std::cout << "r " << rnd << std::endl; - auto b0 = rnd; - auto b1 = rnd.slli_epi32<1>(); - auto b2 = rnd.slli_epi32<2>(); - auto b3 = rnd.slli_epi32<3>(); - auto b4 = rnd.slli_epi32<4>(); - auto b5 = rnd.slli_epi32<5>(); - auto b6 = rnd.slli_epi32<6>(); - auto b7 = rnd.slli_epi32<7>(); - //rnd = rnd.mm_slli_epi32<8>(); - - if (j + 0 < size && b0.get(0) < 0) pl.push_back(j + 0, i); - if (j + 1 < size && b1.get(0) < 0) pl.push_back(j + 1, i); - if (j + 2 < size && b2.get(0) < 0) pl.push_back(j + 2, i); - if (j + 3 < size && b3.get(0) < 0) pl.push_back(j + 3, i); - if (j + 4 < size && b4.get(0) < 0) pl.push_back(j + 4, i); - if (j + 5 < size && b5.get(0) < 0) pl.push_back(j + 5, i); - if (j + 6 < size && b6.get(0) < 0) pl.push_back(j + 6, i); - if (j + 7 < size && b7.get(0) < 0) pl.push_back(j + 7, i); - } - - - //if (mWrapping) - { - if (j < size) - pl.push_back(j, i); - ++j; - } + u64 j = i + 1; + pl.push_back(i, i); + + if (q + mAccumulatorSize > qe) + { + refill(prng); + ptr = (u8*)prng.mBuffer.data(); + q = 0; + } + + + for (u64 k = 0; k < mAccumulatorSize; k += 8, q += 8, j += 8) + { + assert(ptr < (u8*)(prng.mBuffer.data() + prng.mBuffer.size())); + rnd = block::allSame(*ptr); + ++ptr; + + //std::cout << "r " << rnd << std::endl; + auto b0 = rnd; + auto b1 = rnd.slli_epi32<1>(); + auto b2 = rnd.slli_epi32<2>(); + auto b3 = rnd.slli_epi32<3>(); + auto b4 = rnd.slli_epi32<4>(); + auto b5 = rnd.slli_epi32<5>(); + auto b6 = rnd.slli_epi32<6>(); + auto b7 = rnd.slli_epi32<7>(); + //rnd = rnd.mm_slli_epi32<8>(); + + if (j + 0 < size && b0.get(0) < 0) pl.push_back(j + 0, i); + if (j + 1 < size && b1.get(0) < 0) pl.push_back(j + 1, i); + if (j + 2 < size && b2.get(0) < 0) pl.push_back(j + 2, i); + if (j + 3 < size && b3.get(0) < 0) pl.push_back(j + 3, i); + if (j + 4 < size && b4.get(0) < 0) pl.push_back(j + 4, i); + if (j + 5 < size && b5.get(0) < 0) pl.push_back(j + 5, i); + if (j + 6 < size && b6.get(0) < 0) pl.push_back(j + 6, i); + if (j + 7 < size && b7.get(0) < 0) pl.push_back(j + 7, i); + } + + + //if (mWrapping) + { + if (j < size) + pl.push_back(j, i); + ++j; + } } #ifdef ENABLE_SSE - using My__m128 = __m128; + using My__m128 = __m128; #else - using My__m128 = block; + using My__m128 = block; - inline My__m128 _mm_load_ps(float* b) { return *(block*)b; } + inline My__m128 _mm_load_ps(float* b) { return *(block*)b; } - // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_blendv_ps&ig_expand=557 - inline My__m128 _mm_blendv_ps(My__m128 a, My__m128 b, My__m128 mask) - { - My__m128 dst; - for (u64 j = 0; j < 4; ++j) + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_blendv_ps&ig_expand=557 + inline My__m128 _mm_blendv_ps(My__m128 a, My__m128 b, My__m128 mask) { - if (mask.get(j) < 0) - dst.set(j, b.get(j)); - else - dst.set(j, a.get(j)); + My__m128 dst; + for (u64 j = 0; j < 4; ++j) + { + if (mask.get(j) < 0) + dst.set(j, b.get(j)); + else + dst.set(j, a.get(j)); + } + return dst; } - return dst; - } - inline My__m128 _mm_setzero_ps() { return ZeroBlock; } + inline My__m128 _mm_setzero_ps() { return ZeroBlock; } #endif - template - OC_FORCEINLINE void accOneHelper( - T* __restrict xx, - My__m128 xii, - u64 j, u64 i, u64 size, - block* b - ) - { - My__m128 Zero = _mm_setzero_ps(); - - if constexpr (std::is_same::value) - { - My__m128 bb[8]; - bb[0] = _mm_load_ps((float*)&b[0]); - bb[1] = _mm_load_ps((float*)&b[1]); - bb[2] = _mm_load_ps((float*)&b[2]); - bb[3] = _mm_load_ps((float*)&b[3]); - bb[4] = _mm_load_ps((float*)&b[4]); - bb[5] = _mm_load_ps((float*)&b[5]); - bb[6] = _mm_load_ps((float*)&b[6]); - bb[7] = _mm_load_ps((float*)&b[7]); - - - bb[0] = _mm_blendv_ps(Zero, xii, bb[0]); - bb[1] = _mm_blendv_ps(Zero, xii, bb[1]); - bb[2] = _mm_blendv_ps(Zero, xii, bb[2]); - bb[3] = _mm_blendv_ps(Zero, xii, bb[3]); - bb[4] = _mm_blendv_ps(Zero, xii, bb[4]); - bb[5] = _mm_blendv_ps(Zero, xii, bb[5]); - bb[6] = _mm_blendv_ps(Zero, xii, bb[6]); - bb[7] = _mm_blendv_ps(Zero, xii, bb[7]); - - block tt[8]; - memcpy(tt, bb, 8 * 16); - -// if (!rangeCheck || j + 0 < size) xx[j + 0] = xx[j + 0] ^ tt[0]; -// if (!rangeCheck || j + 1 < size) xx[j + 1] = xx[j + 1] ^ tt[1]; -// if (!rangeCheck || j + 2 < size) xx[j + 2] = xx[j + 2] ^ tt[2]; -// if (!rangeCheck || j + 3 < size) xx[j + 3] = xx[j + 3] ^ tt[3]; -// if (!rangeCheck || j + 4 < size) xx[j + 4] = xx[j + 4] ^ tt[4]; -// if (!rangeCheck || j + 5 < size) xx[j + 5] = xx[j + 5] ^ tt[5]; -// if (!rangeCheck || j + 6 < size) xx[j + 6] = xx[j + 6] ^ tt[6]; -// if (!rangeCheck || j + 7 < size) xx[j + 7] = xx[j + 7] ^ tt[7]; - - if (!rangeCheck || j + 0 < size) xx[j + 0] = xx[j + 0] + tt[0]; - if (!rangeCheck || j + 1 < size) xx[j + 1] = xx[j + 1] + tt[1]; - if (!rangeCheck || j + 2 < size) xx[j + 2] = xx[j + 2] + tt[2]; - if (!rangeCheck || j + 3 < size) xx[j + 3] = xx[j + 3] + tt[3]; - if (!rangeCheck || j + 4 < size) xx[j + 4] = xx[j + 4] + tt[4]; - if (!rangeCheck || j + 5 < size) xx[j + 5] = xx[j + 5] + tt[5]; - if (!rangeCheck || j + 6 < size) xx[j + 6] = xx[j + 6] + tt[6]; - if (!rangeCheck || j + 7 < size) xx[j + 7] = xx[j + 7] + tt[7]; - } - else + template + OC_FORCEINLINE void accOneHelper( + T* __restrict xx, + My__m128 xii, + u64 j, u64 i, u64 size, + block* b + ) { -// if (!rangeCheck || j + 0 < size) xx[j + 0] = xx[j + 0] ^ bb0; -// if (!rangeCheck || j + 1 < size) xx[j + 1] = xx[j + 1] ^ bb1; -// if (!rangeCheck || j + 2 < size) xx[j + 2] = xx[j + 2] ^ bb2; -// if (!rangeCheck || j + 3 < size) xx[j + 3] = xx[j + 3] ^ bb3; -// if (!rangeCheck || j + 4 < size) xx[j + 4] = xx[j + 4] ^ bb4; -// if (!rangeCheck || j + 5 < size) xx[j + 5] = xx[j + 5] ^ bb5; -// if (!rangeCheck || j + 6 < size) xx[j + 6] = xx[j + 6] ^ bb6; -// if (!rangeCheck || j + 7 < size) xx[j + 7] = xx[j + 7] ^ bb7; - - if ((!rangeCheck || j + 0 < size) && b[0].get(0) < 0) xx[j + 0] = xx[j + 0] + xx[i]; - if ((!rangeCheck || j + 1 < size) && b[1].get(0) < 0) xx[j + 1] = xx[j + 1] + xx[i]; - if ((!rangeCheck || j + 2 < size) && b[2].get(0) < 0) xx[j + 2] = xx[j + 2] + xx[i]; - if ((!rangeCheck || j + 3 < size) && b[3].get(0) < 0) xx[j + 3] = xx[j + 3] + xx[i]; - if ((!rangeCheck || j + 4 < size) && b[4].get(0) < 0) xx[j + 4] = xx[j + 4] + xx[i]; - if ((!rangeCheck || j + 5 < size) && b[5].get(0) < 0) xx[j + 5] = xx[j + 5] + xx[i]; - if ((!rangeCheck || j + 6 < size) && b[6].get(0) < 0) xx[j + 6] = xx[j + 6] + xx[i]; - if ((!rangeCheck || j + 7 < size) && b[7].get(0) < 0) xx[j + 7] = xx[j + 7] + xx[i]; + My__m128 Zero = _mm_setzero_ps(); + + if constexpr (std::is_same::value) + { + My__m128 bb[8]; + bb[0] = _mm_load_ps((float*)&b[0]); + bb[1] = _mm_load_ps((float*)&b[1]); + bb[2] = _mm_load_ps((float*)&b[2]); + bb[3] = _mm_load_ps((float*)&b[3]); + bb[4] = _mm_load_ps((float*)&b[4]); + bb[5] = _mm_load_ps((float*)&b[5]); + bb[6] = _mm_load_ps((float*)&b[6]); + bb[7] = _mm_load_ps((float*)&b[7]); + + + bb[0] = _mm_blendv_ps(Zero, xii, bb[0]); + bb[1] = _mm_blendv_ps(Zero, xii, bb[1]); + bb[2] = _mm_blendv_ps(Zero, xii, bb[2]); + bb[3] = _mm_blendv_ps(Zero, xii, bb[3]); + bb[4] = _mm_blendv_ps(Zero, xii, bb[4]); + bb[5] = _mm_blendv_ps(Zero, xii, bb[5]); + bb[6] = _mm_blendv_ps(Zero, xii, bb[6]); + bb[7] = _mm_blendv_ps(Zero, xii, bb[7]); + + block tt[8]; + memcpy(tt, bb, 8 * 16); + + // if (!rangeCheck || j + 0 < size) xx[j + 0] = xx[j + 0] ^ tt[0]; + // if (!rangeCheck || j + 1 < size) xx[j + 1] = xx[j + 1] ^ tt[1]; + // if (!rangeCheck || j + 2 < size) xx[j + 2] = xx[j + 2] ^ tt[2]; + // if (!rangeCheck || j + 3 < size) xx[j + 3] = xx[j + 3] ^ tt[3]; + // if (!rangeCheck || j + 4 < size) xx[j + 4] = xx[j + 4] ^ tt[4]; + // if (!rangeCheck || j + 5 < size) xx[j + 5] = xx[j + 5] ^ tt[5]; + // if (!rangeCheck || j + 6 < size) xx[j + 6] = xx[j + 6] ^ tt[6]; + // if (!rangeCheck || j + 7 < size) xx[j + 7] = xx[j + 7] ^ tt[7]; + + if (!rangeCheck || j + 0 < size) xx[j + 0] = xx[j + 0] + tt[0]; + if (!rangeCheck || j + 1 < size) xx[j + 1] = xx[j + 1] + tt[1]; + if (!rangeCheck || j + 2 < size) xx[j + 2] = xx[j + 2] + tt[2]; + if (!rangeCheck || j + 3 < size) xx[j + 3] = xx[j + 3] + tt[3]; + if (!rangeCheck || j + 4 < size) xx[j + 4] = xx[j + 4] + tt[4]; + if (!rangeCheck || j + 5 < size) xx[j + 5] = xx[j + 5] + tt[5]; + if (!rangeCheck || j + 6 < size) xx[j + 6] = xx[j + 6] + tt[6]; + if (!rangeCheck || j + 7 < size) xx[j + 7] = xx[j + 7] + tt[7]; + } + else + { + // if (!rangeCheck || j + 0 < size) xx[j + 0] = xx[j + 0] ^ bb0; + // if (!rangeCheck || j + 1 < size) xx[j + 1] = xx[j + 1] ^ bb1; + // if (!rangeCheck || j + 2 < size) xx[j + 2] = xx[j + 2] ^ bb2; + // if (!rangeCheck || j + 3 < size) xx[j + 3] = xx[j + 3] ^ bb3; + // if (!rangeCheck || j + 4 < size) xx[j + 4] = xx[j + 4] ^ bb4; + // if (!rangeCheck || j + 5 < size) xx[j + 5] = xx[j + 5] ^ bb5; + // if (!rangeCheck || j + 6 < size) xx[j + 6] = xx[j + 6] ^ bb6; + // if (!rangeCheck || j + 7 < size) xx[j + 7] = xx[j + 7] ^ bb7; + + if ((!rangeCheck || j + 0 < size) && b[0].get(0) < 0) xx[j + 0] = xx[j + 0] + xx[i]; + if ((!rangeCheck || j + 1 < size) && b[1].get(0) < 0) xx[j + 1] = xx[j + 1] + xx[i]; + if ((!rangeCheck || j + 2 < size) && b[2].get(0) < 0) xx[j + 2] = xx[j + 2] + xx[i]; + if ((!rangeCheck || j + 3 < size) && b[3].get(0) < 0) xx[j + 3] = xx[j + 3] + xx[i]; + if ((!rangeCheck || j + 4 < size) && b[4].get(0) < 0) xx[j + 4] = xx[j + 4] + xx[i]; + if ((!rangeCheck || j + 5 < size) && b[5].get(0) < 0) xx[j + 5] = xx[j + 5] + xx[i]; + if ((!rangeCheck || j + 6 < size) && b[6].get(0) < 0) xx[j + 6] = xx[j + 6] + xx[i]; + if ((!rangeCheck || j + 7 < size) && b[7].get(0) < 0) xx[j + 7] = xx[j + 7] + xx[i]; + } } - } // accumulating row i. template @@ -458,44 +458,46 @@ namespace osuCrypto::Subfield u64& q, u64 qe, u64 size) { - u64 j = i + 1; - if (width) { - if (q + width > qe) { - refill(prng); - ptr = (u8 *) prng.mBuffer.data(); - q = 0; - + u64 j = i + 1; + if (width) { + if (q + width > qe) { + refill(prng); + ptr = (u8*)prng.mBuffer.data(); + q = 0; + + } + q += width; + + for (u64 k = 0; k < width; ++k, j += 8) { + assert(ptr < (u8*)(prng.mBuffer.data() + prng.mBuffer.size())); + block rnd = block::allSame(*(u8*)ptr++); + + block b[8]; + b[0] = rnd; + b[1] = rnd.slli_epi32<1>(); + b[2] = rnd.slli_epi32<2>(); + b[3] = rnd.slli_epi32<3>(); + b[4] = rnd.slli_epi32<4>(); + b[5] = rnd.slli_epi32<5>(); + b[6] = rnd.slli_epi32<6>(); + b[7] = rnd.slli_epi32<7>(); + + if constexpr (std::is_same::value) { + accOneHelper(xx, _mm_setzero_ps(), j, i, size, b); + } + else { + My__m128 xii;// = ::_mm_set_ps(0.0f, 0.0f, 0.0f, 0.0f); + memset(&xii, 0, sizeof(My__m128)); + accOneHelper(xx, xii, j, i, size, b); + } + } } - q += width; - - for (u64 k = 0; k < width; ++k, j += 8) { - assert(ptr < (u8 *) (prng.mBuffer.data() + prng.mBuffer.size())); - block rnd = block::allSame(*(u8 *) ptr++); - - block b[8]; - b[0] = rnd; - b[1] = rnd.slli_epi32<1>(); - b[2] = rnd.slli_epi32<2>(); - b[3] = rnd.slli_epi32<3>(); - b[4] = rnd.slli_epi32<4>(); - b[5] = rnd.slli_epi32<5>(); - b[6] = rnd.slli_epi32<6>(); - b[7] = rnd.slli_epi32<7>(); - - if constexpr (std::is_same::value) { - accOneHelper(xx, _mm_setzero_ps(), j, i, size, b); - } else { - My__m128 xii = _mm_set_ps(0.0f, 0.0f, 0.0f, 0.0f); - accOneHelper(xx, xii, j, i, size, b); - } - } - } - if (!rangeCheck || j < size) { -// auto xj = xx[j] ^ xx[i]; - auto xj = xx[j] + xx[i]; - xx[j] = xj; - } + if (!rangeCheck || j < size) { + // auto xj = xx[j] ^ xx[i]; + auto xj = xx[j] + xx[i]; + xx[j] = xj; + } } @@ -511,59 +513,61 @@ namespace osuCrypto::Subfield u64 qe, u64 size) { - u64 j = i + 1; - if (width) - { - - - if (q + width > qe) + u64 j = i + 1; + if (width) { - refill(prng); - ptr = (u8*)prng.mBuffer.data(); - q = 0; + + if (q + width > qe) + { + refill(prng); + ptr = (u8*)prng.mBuffer.data(); + q = 0; + + } + q += width; + + for (u64 k = 0; k < width; ++k, j += 8) + { + assert(ptr < (u8*)(prng.mBuffer.data() + prng.mBuffer.size())); + block rnd = block::allSame(*(u8*)ptr++); + + block b[8]; + b[0] = rnd; + b[1] = rnd.slli_epi32<1>(); + b[2] = rnd.slli_epi32<2>(); + b[3] = rnd.slli_epi32<3>(); + b[4] = rnd.slli_epi32<4>(); + b[5] = rnd.slli_epi32<5>(); + b[6] = rnd.slli_epi32<6>(); + b[7] = rnd.slli_epi32<7>(); + + if constexpr (std::is_same::value) { + auto xii0 = _mm_load_ps((float*)(xx0 + i)); + accOneHelper(xx0, xii0, j, i, size, b); + } + else { + accOneHelper(xx0, _mm_setzero_ps(), j, i, size, b); + } + if constexpr (std::is_same::value) { + auto xii1 = _mm_load_ps((float*)(xx1 + i)); + accOneHelper(xx1, xii1, j, i, size, b); + } + else { + accOneHelper(xx1, _mm_setzero_ps(), j, i, size, b); + } + } } - q += width; - for (u64 k = 0; k < width; ++k, j += 8) + if (!rangeCheck || j < size) { - assert(ptr < (u8*)(prng.mBuffer.data() + prng.mBuffer.size())); - block rnd = block::allSame(*(u8*)ptr++); - - block b[8]; - b[0] = rnd; - b[1] = rnd.slli_epi32<1>(); - b[2] = rnd.slli_epi32<2>(); - b[3] = rnd.slli_epi32<3>(); - b[4] = rnd.slli_epi32<4>(); - b[5] = rnd.slli_epi32<5>(); - b[6] = rnd.slli_epi32<6>(); - b[7] = rnd.slli_epi32<7>(); - - if constexpr (std::is_same::value) { - auto xii0 = _mm_load_ps((float*)(xx0 + i)); - accOneHelper(xx0, xii0, j, i, size, b); - } else { - accOneHelper(xx0, _mm_setzero_ps(), j, i, size, b); - } - if constexpr (std::is_same::value) { - auto xii1 = _mm_load_ps((float*)(xx1 + i)); - accOneHelper(xx1, xii1, j, i, size, b); - } else { - accOneHelper(xx1, _mm_setzero_ps(), j, i, size, b); - } + // auto xj0 = xx0[j] ^ xx0[i]; + // auto xj1 = xx1[j] ^ xx1[i]; + auto xj0 = xx0[j] + xx0[i]; + auto xj1 = xx1[j] + xx1[i]; + xx0[j] = xj0; + xx1[j] = xj1; } - } - - if (!rangeCheck || j < size) - { -// auto xj0 = xx0[j] ^ xx0[i]; -// auto xj1 = xx1[j] ^ xx1[i]; - auto xj0 = xx0[j] + xx0[i]; - auto xj1 = xx1[j] + xx1[i]; - xx0[j] = xj0; - xx1[j] = xj1; - } } @@ -571,17 +575,17 @@ namespace osuCrypto::Subfield template void accumulate(span x) { - PRNG prng(mSeed ^ OneBlock); + PRNG prng(mSeed ^ OneBlock); - u64 i = 0; - auto size = x.size(); - auto main = (u64)std::max(0, size - 1 - mAccumulatorSize); - u8* ptr = (u8*)prng.mBuffer.data(); - auto qe = prng.mBuffer.size() * 128 / 8; - u64 q = 0; - T* __restrict xx = x.data(); + u64 i = 0; + auto size = x.size(); + auto main = (u64)std::max(0, size - 1 - mAccumulatorSize); + u8* ptr = (u8*)prng.mBuffer.data(); + auto qe = prng.mBuffer.size() * 128 / 8; + u64 q = 0; + T* __restrict xx = x.data(); - { + { #define CASE(I) case I:\ for (; i < main; ++i)\ @@ -590,38 +594,38 @@ namespace osuCrypto::Subfield accOne(xx, i, ptr, prng, q, qe, size);\ break - switch (mAccumulatorSize / 8) - { - CASE(0); - CASE(1); - CASE(2); - CASE(3); - CASE(4); - default: - throw RTE_LOC; - break; - } + switch (mAccumulatorSize / 8) + { + CASE(0); + CASE(1); + CASE(2); + CASE(3); + CASE(4); + default: + throw RTE_LOC; + break; + } #undef CASE - } + } } // accumulate x onto itself. - template + template void accumulate(span x0, span x1) { - PRNG prng(mSeed ^ OneBlock); + PRNG prng(mSeed ^ OneBlock); - u64 i = 0; - auto size = x0.size(); - auto main = (u64)std::max(0, size - 1 - mAccumulatorSize); - u8* ptr = (u8*)prng.mBuffer.data(); - auto qe = prng.mBuffer.size() * 128 / 8; - u64 q = 0; - T0* __restrict xx0 = x0.data(); - T1* __restrict xx1 = x1.data(); + u64 i = 0; + auto size = x0.size(); + auto main = (u64)std::max(0, size - 1 - mAccumulatorSize); + u8* ptr = (u8*)prng.mBuffer.data(); + auto qe = prng.mBuffer.size() * 128 / 8; + u64 q = 0; + T0* __restrict xx0 = x0.data(); + T1* __restrict xx1 = x1.data(); - { + { #define CASE(I) case I:\ for (; i < main; ++i)\ @@ -630,19 +634,19 @@ namespace osuCrypto::Subfield accOne(xx0, xx1, i, ptr, prng, q, qe, size);\ break - switch (mAccumulatorSize / 8) - { - CASE(0); - CASE(1); - CASE(2); - CASE(3); - CASE(4); - default: - throw RTE_LOC; - break; - } + switch (mAccumulatorSize / 8) + { + CASE(0); + CASE(1); + CASE(2); + CASE(3); + CASE(4); + default: + throw RTE_LOC; + break; + } #undef CASE - } + } } }; } diff --git a/libOTe/Tools/Subfield/Subfield.h b/libOTe/Tools/Subfield/Subfield.h index 363abda2..a70465cf 100644 --- a/libOTe/Tools/Subfield/Subfield.h +++ b/libOTe/Tools/Subfield/Subfield.h @@ -1,179 +1,171 @@ #include "libOTe/Vole/Noisy/NoisyVoleSender.h" +#include "cryptoTools/Common/BitIterator.h" namespace osuCrypto::Subfield { -struct F128 { - block b; - F128() = default; - explicit F128(const block &b) : b(b) {} - OC_FORCEINLINE F128 operator+(const F128 &rhs) const { - F128 ret; - ret.b = b ^ rhs.b; - return ret; - } - OC_FORCEINLINE F128 operator-(const F128 &rhs) const { - F128 ret; - ret.b = b ^ rhs.b; - return ret; - } - OC_FORCEINLINE F128 operator*(const F128 &rhs) const { - F128 ret; - ret.b = b.gf128Mul(rhs.b); - return ret; - } - OC_FORCEINLINE bool operator==(const F128 &rhs) const { - return b == rhs.b; - } - OC_FORCEINLINE bool operator!=(const F128 &rhs) const { - return b != rhs.b; - } -}; - -using u128 = unsigned __int128; -union conv128 { - u128 u; - block m; -}; -OC_FORCEINLINE u128 fromBlock(const block &b) { - conv128 c{}; - c.m = b; - return c.u; -} -inline std::string u128ToString(u128 value) { - if (value == 0) { - return "0"; - } - - std::string result; - while (value > 0) { - uint64_t digit = value % 10; - result.push_back(static_cast('0' + digit)); - value /= 10; - } - reverse(result.begin(), result.end()); - return result; -} -struct TypeTrait128 { - using F = u128; - using G = u128; - - static OC_FORCEINLINE F fromBlock(const block &b) { - conv128 c{}; - c.m = b; - return c.u; - } - static OC_FORCEINLINE F pow(u64 power) { - u128 ret = 1; - ret <<= power; - return ret; - } -}; - -struct TypeTrait64 { - using F = u64; - using G = u64; - - union conv64 { - u64 u; - block m; - }; - - static OC_FORCEINLINE F fromBlock(const block &b) { - conv64 c{}; - c.m = b; - return c.u; - } - static OC_FORCEINLINE F pow(u64 power) { - u64 ret = 1; - ret <<= power; - return ret; - } -}; - -// array -template -struct Vec { - std::array v; - OC_FORCEINLINE Vec operator+(const Vec &rhs) const { - Vec ret; - for (u64 i = 0; i < N; ++i) { - ret.v[i] = v[i] + rhs.v[i]; - } - return ret; - } - - OC_FORCEINLINE Vec operator-(const Vec &rhs) const { - Vec ret; - for (u64 i = 0; i < N; ++i) { - ret.v[i] = v[i] - rhs.v[i]; - } - return ret; - } - - OC_FORCEINLINE Vec operator*(const T &rhs) const { - Vec ret; - for (u64 i = 0; i < N; ++i) { - ret.v[i] = v[i] * rhs; - } - return ret; - } - - OC_FORCEINLINE T operator[](u64 idx) const { - return v[idx]; - } - - OC_FORCEINLINE T &operator[](u64 idx) { - return v[idx]; - } - - OC_FORCEINLINE bool operator==(const Vec &rhs) const { - for (u64 i = 0; i < N; ++i) { - if (v[i] != rhs.v[i]) return false; - } - return true; - } - - OC_FORCEINLINE bool operator!=(const Vec &rhs) const { - return !(*this == rhs); - } -}; - -// TypeTraitVec for array of integers -template -struct TypeTraitVec { - using F = Vec; - using G = T; - static constexpr size_t bitsG = sizeof(T) * 8; - static constexpr size_t bitsF = sizeof(F) * 8; - static constexpr size_t bytesF = sizeof(F); - static constexpr size_t sizeBlocks = (bytesF + sizeof(block) - 1) / sizeof(block); - static constexpr size_t size = N; - union Buf { - F f; - block b[sizeBlocks]; - }; - - static OC_FORCEINLINE F fromBlock(const block &b) { - if (N * sizeof(T) <= sizeof(block)) { - F ret; - memcpy(ret.v.data(), &b, bytesF); - return ret; - } else { - Buf buf; - for (u64 i = 0; i < sizeBlocks; ++i) { - buf.b[i] = b + block(i, i); - } - mAesFixedKey.hashBlocks(buf.b, sizeBlocks, buf.b); - return buf.f; - } - } - - static OC_FORCEINLINE F pow(u64 power) { - F ret{}; - power = power % bitsF; - ret[power / bitsG] = 1 << (power % bitsG); - return ret; - } -}; + struct F128 { + block b; + F128() = default; + explicit F128(const block& b) : b(b) {} + OC_FORCEINLINE F128 operator+(const F128& rhs) const { + F128 ret; + ret.b = b ^ rhs.b; + return ret; + } + OC_FORCEINLINE F128 operator-(const F128& rhs) const { + F128 ret; + ret.b = b ^ rhs.b; + return ret; + } + OC_FORCEINLINE F128 operator*(const F128& rhs) const { + F128 ret; + ret.b = b.gf128Mul(rhs.b); + return ret; + } + OC_FORCEINLINE bool operator==(const F128& rhs) const { + return b == rhs.b; + } + OC_FORCEINLINE bool operator!=(const F128& rhs) const { + return b != rhs.b; + } + }; + + //using u128 = __int128; + //union conv128 { + // u128 u; + // block m; + //}; + //OC_FORCEINLINE u128 fromBlock(const block &b) { + // conv128 c{}; + // c.m = b; + // return c.u; + //} + //inline std::string u128ToString(u128 value) { + // if (value == 0) { + // return "0"; + // } + // + // std::string result; + // while (value > 0) { + // uint64_t digit = value % 10; + // result.push_back(static_cast('0' + digit)); + // value /= 10; + // } + // reverse(result.begin(), result.end()); + // return result; + //} + //struct TypeTrait128 { + // using F = u128; + // using G = u128; + // + // static OC_FORCEINLINE F fromBlock(const block &b) { + // conv128 c{}; + // c.m = b; + // return c.u; + // } + // static OC_FORCEINLINE F pow(u64 power) { + // u128 ret = 1; + // ret <<= power; + // return ret; + // } + //}; + + struct TypeTrait64 { + using F = u64; + using G = u64; + + static OC_FORCEINLINE F fromBlock(const block& b) { + return b.get()[0]; + } + static OC_FORCEINLINE F pow(u64 power) { + F ret = 1; + ret <<= power; + return ret; + } + }; + + // array + template + struct Vec { + std::array v; + OC_FORCEINLINE Vec operator+(const Vec& rhs) const { + Vec ret; + for (u64 i = 0; i < N; ++i) { + ret.v[i] = v[i] + rhs.v[i]; + } + return ret; + } + + OC_FORCEINLINE Vec operator-(const Vec& rhs) const { + Vec ret; + for (u64 i = 0; i < N; ++i) { + ret.v[i] = v[i] - rhs.v[i]; + } + return ret; + } + + OC_FORCEINLINE Vec operator*(const T& rhs) const { + Vec ret; + for (u64 i = 0; i < N; ++i) { + ret.v[i] = v[i] * rhs; + } + return ret; + } + + OC_FORCEINLINE T operator[](u64 idx) const { + return v[idx]; + } + + OC_FORCEINLINE T& operator[](u64 idx) { + return v[idx]; + } + + OC_FORCEINLINE bool operator==(const Vec& rhs) const { + for (u64 i = 0; i < N; ++i) { + if (v[i] != rhs.v[i]) return false; + } + return true; + } + + OC_FORCEINLINE bool operator!=(const Vec& rhs) const { + return !(*this == rhs); + } + }; + + // TypeTraitVec for array of integers + template + struct TypeTraitVec { + using F = Vec; + using G = T; + static constexpr size_t bitsG = sizeof(T) * 8; + static constexpr size_t bitsF = sizeof(F) * 8; + static constexpr size_t bytesF = sizeof(F); + static constexpr size_t sizeBlocks = (bytesF + sizeof(block) - 1) / sizeof(block); + static constexpr size_t size = N; + + static OC_FORCEINLINE F fromBlock(const block& b) { + F ret; + if (N * sizeof(T) <= sizeof(block)) { + memcpy(ret.v.data(), &b, bytesF); + return ret; + } + else { + std::array buf; + for (u64 i = 0; i < sizeBlocks; ++i) { + buf[i] = b + block(i, i); + } + mAesFixedKey.hashBlocks(buf.data(), buf.data()); + memcpy(&ret, &buf, sizeof(F)); + return ret; + } + } + + static OC_FORCEINLINE F pow(u64 power) { + F ret; + memset(&ret, 0, sizeof(ret)); + *BitIterator((u8*)&ret, power) = 1; + return ret; + } + }; } diff --git a/libOTe/Tools/Subfield/SubfieldPprf.h b/libOTe/Tools/Subfield/SubfieldPprf.h index 07654e1f..8d16903c 100644 --- a/libOTe/Tools/Subfield/SubfieldPprf.h +++ b/libOTe/Tools/Subfield/SubfieldPprf.h @@ -1,12 +1,11 @@ #pragma once -#include "out/build/linux/libOTe/config.h" -#include "cryptoTools/cryptoTools/Common/Defines.h" -#include "cryptoTools/cryptoTools/Common/BitVector.h" -#include "cryptoTools/cryptoTools/Common/Matrix.h" -#include "cryptoTools/cryptoTools/Common/Timer.h" -#include "cryptoTools/cryptoTools/Common/Aligned.h" -#include "cryptoTools/cryptoTools/Common/Range.h" -#include "cryptoTools/cryptoTools/Crypto/PRNG.h" +#include "cryptoTools/Common/Defines.h" +#include "cryptoTools/Common/BitVector.h" +#include "cryptoTools/Common/Matrix.h" +#include "cryptoTools/Common/Timer.h" +#include "cryptoTools/Common/Aligned.h" +#include "cryptoTools/Common/Range.h" +#include "cryptoTools/Crypto/PRNG.h" #include "libOTe/Tools/Coproto.h" #include "libOTe/Tools/SilentPprf.h" #include "SubfieldPprf.h" diff --git a/libOTe/Vole/Subfield/NoisyVoleReceiver.h b/libOTe/Vole/Subfield/NoisyVoleReceiver.h index 3b788120..f1ebbc32 100644 --- a/libOTe/Vole/Subfield/NoisyVoleReceiver.h +++ b/libOTe/Vole/Subfield/NoisyVoleReceiver.h @@ -35,71 +35,71 @@ namespace osuCrypto::Subfield { -template -class NoisySubfieldVoleReceiver : public TimerAdapter { - public: - using F = typename TypeTrait::F; - using G = typename TypeTrait::G; - task<> receive(span y, span z, PRNG& prng, - OtSender& ot, Socket& chl) { - MC_BEGIN(task<>, this, y, z, &prng, &ot, &chl, - otMsg = AlignedUnVector>{sizeof(F) * 8}); // todo: sizeof(F) * 8 + template + class NoisySubfieldVoleReceiver : public TimerAdapter { + public: + using F = typename TypeTrait::F; + using G = typename TypeTrait::G; + task<> receive(span y, span z, PRNG& prng, + OtSender& ot, Socket& chl) { + MC_BEGIN(task<>, this, y, z, &prng, &ot, &chl, + otMsg = AlignedUnVector>{ sizeof(F) * 8 }); // todo: sizeof(F) * 8 - setTimePoint("NoisyVoleReceiver.ot.begin"); + setTimePoint("NoisyVoleReceiver.ot.begin"); - MC_AWAIT(ot.send(otMsg, prng, chl)); + MC_AWAIT(ot.send(otMsg, prng, chl)); - setTimePoint("NoisyVoleReceiver.ot.end"); + setTimePoint("NoisyVoleReceiver.ot.end"); - MC_AWAIT(receive(y, z, prng, otMsg, chl)); + MC_AWAIT(receive(y, z, prng, otMsg, chl)); - MC_END(); - } + MC_END(); + } - task<> receive(span y, span z, PRNG& _, - span> otMsg, - Socket& chl) { - MC_BEGIN(task<>, this, y, z, otMsg, &chl, msg = Matrix{}, - prng = std::move(PRNG{}) - ); + task<> receive(span y, span z, PRNG& _, + span> otMsg, + Socket& chl) { + MC_BEGIN(task<>, this, y, z, otMsg, &chl, + msg = Matrix{}, + prng = std::move(PRNG{}) + ); - if (otMsg.size() != sizeof(F) * 8) throw RTE_LOC; - if (y.size() != z.size()) throw RTE_LOC; - if (z.size() == 0) throw RTE_LOC; + if (otMsg.size() != sizeof(F) * 8) throw RTE_LOC; + if (y.size() != z.size()) throw RTE_LOC; + if (z.size() == 0) throw RTE_LOC; - setTimePoint("NoisyVoleReceiver.begin"); + setTimePoint("NoisyVoleReceiver.begin"); - memset(z.data(), 0, sizeof(F) * z.size()); - msg.resize(otMsg.size(), z.size(), AllocType::Uninitialized); + memset(z.data(), 0, sizeof(F) * z.size()); + msg.resize(otMsg.size(), z.size(), AllocType::Uninitialized); - for (u64 ii = 0; ii < sizeof(F) * 8; ++ii) { - prng.SetSeed(otMsg[ii][0], z.size()); - auto& buffer = prng.mBuffer; - auto pow = TypeTrait::pow(ii); - for (u64 j = 0; j < (u64)y.size(); ++j) { - auto bufj = TypeTrait::fromBlock(buffer[j]); - z[j] = z[j] + bufj; - F yy = pow * y[j]; + for (u64 ii = 0; ii < sizeof(F) * 8; ++ii) { + prng.SetSeed(otMsg[ii][0], z.size()); + auto& buffer = prng.mBuffer; + auto pow = TypeTrait::pow(ii); + for (u64 j = 0; j < (u64)y.size(); ++j) { + auto bufj = TypeTrait::fromBlock(buffer[j]); + z[j] = z[j] + bufj; + F yy = pow * y[j]; - msg(ii, j) = yy + bufj; - } + msg(ii, j) = yy + bufj; + } - prng.SetSeed(otMsg[ii][1], z.size()); + prng.SetSeed(otMsg[ii][1], z.size()); - for (u64 j = 0; j < (u64)y.size(); ++j) { - // enc one message under the OT msg. - msg(ii, j) = msg(ii, j) + TypeTrait::fromBlock(buffer[j]); - } - } + for (u64 j = 0; j < (u64)y.size(); ++j) { + // enc one message under the OT msg. + msg(ii, j) = msg(ii, j) + TypeTrait::fromBlock(buffer[j]); + } + } - MC_AWAIT(chl.send(std::move(msg))); - // chl.asyncSend(std::move(msg)); - setTimePoint("NoisyVoleReceiver.done"); + MC_AWAIT(chl.send(std::move(msg))); + setTimePoint("NoisyVoleReceiver.done"); - MC_END(); - } + MC_END(); + } -}; + }; } // namespace osuCrypto #endif diff --git a/libOTe/Vole/Subfield/NoisyVoleSender.h b/libOTe/Vole/Subfield/NoisyVoleSender.h index c6393995..6590f56b 100644 --- a/libOTe/Vole/Subfield/NoisyVoleSender.h +++ b/libOTe/Vole/Subfield/NoisyVoleSender.h @@ -35,57 +35,62 @@ #include "libOTe/TwoChooseOne/OTExtInterface.h" namespace osuCrypto::Subfield { -template -class NoisySubfieldVoleSender : public TimerAdapter { - public: - using F = typename TypeTrait::F; - using G = typename TypeTrait::G; - task<> send(F x, span z, PRNG& prng, - OtReceiver& ot, Socket& chl) { - MC_BEGIN(task<>, this, x, z, &prng, &ot, &chl, - bv = BitVector((u8*)&x, sizeof(F) * 8), - otMsg = AlignedUnVector{sizeof(F) * 8}); // todo: sizeof(F) * 8 - - setTimePoint("NoisyVoleSender.ot.begin"); - - MC_AWAIT(ot.receive(bv, otMsg, prng, chl)); - setTimePoint("NoisyVoleSender.ot.end"); - - MC_AWAIT(send(x, z, prng, otMsg, chl)); - - MC_END(); - } - - task<> send(F x, span z, PRNG& _, - span otMsg, Socket& chl) { - MC_BEGIN(task<>, this, x, z, prng = std::move(PRNG{}), otMsg, &chl, msg = Matrix{}, - xb = BitVector{}); - - if (otMsg.size() != sizeof(F) * 8) throw RTE_LOC; - setTimePoint("NoisyVoleSender.main"); - - memset(z.data(), 0, sizeof(F) * z.size()); - msg.resize(otMsg.size(), z.size(), AllocType::Uninitialized); - - MC_AWAIT(chl.recv(msg)); - - setTimePoint("NoisyVoleSender.recvMsg"); - - xb = BitVector((u8*)&x, sizeof(F) * 8); - for (u64 i = 0; i < sizeof(F) * 8; ++i) { - prng.SetSeed(otMsg[i], z.size()); - - for (u64 j = 0; j < (u64)z.size(); ++j) { - F bufj = TypeTrait::fromBlock(prng.mBuffer[j]); - z[j] = z[j] + (xb[i] ? msg(i,j) - bufj : bufj); - } - } - setTimePoint("NoisyVoleSender.done"); - - MC_END(); - } - -}; + template + class NoisySubfieldVoleSender : public TimerAdapter { + public: + using F = typename TypeTrait::F; + using G = typename TypeTrait::G; + task<> send(F x, span z, PRNG& prng, + OtReceiver& ot, Socket& chl) { + MC_BEGIN(task<>, this, x, z, &prng, &ot, &chl, + bv = BitVector((u8*)&x, sizeof(F) * 8), + otMsg = AlignedUnVector{ sizeof(F) * 8 }); + + setTimePoint("NoisyVoleSender.ot.begin"); + + MC_AWAIT(ot.receive(bv, otMsg, prng, chl)); + setTimePoint("NoisyVoleSender.ot.end"); + + MC_AWAIT(send(x, z, prng, otMsg, chl)); + + MC_END(); + } + + task<> send(F x, span z, PRNG& _, + span otMsg, Socket& chl) { + MC_BEGIN(task<>, this, x, z, otMsg, &chl, + prng = std::move(PRNG{}), + msg = Matrix{}, + xb = BitVector{}); + + if (otMsg.size() != sizeof(F) * 8) + throw RTE_LOC; + setTimePoint("NoisyVoleSender.main"); + + memset(z.data(), 0, sizeof(F) * z.size()); + msg.resize(otMsg.size(), z.size(), AllocType::Uninitialized); + + MC_AWAIT(chl.recv(msg)); + + setTimePoint("NoisyVoleSender.recvMsg"); + + xb = BitVector((u8*)&x, sizeof(F) * 8); + for (u64 i = 0; i < sizeof(F) * 8; ++i) + { + prng.SetSeed(otMsg[i], z.size()); + + for (u64 j = 0; j < (u64)z.size(); ++j) + { + F bufj = TypeTrait::fromBlock(prng.mBuffer[j]); + z[j] = z[j] + (xb[i] ? msg(i, j) - bufj : bufj); + } + } + setTimePoint("NoisyVoleSender.done"); + + MC_END(); + } + + }; } // namespace osuCrypto #endif \ No newline at end of file diff --git a/libOTe/Vole/Subfield/SilentVoleReceiver.h b/libOTe/Vole/Subfield/SilentVoleReceiver.h index 398c4d80..12063309 100644 --- a/libOTe/Vole/Subfield/SilentVoleReceiver.h +++ b/libOTe/Vole/Subfield/SilentVoleReceiver.h @@ -53,10 +53,10 @@ namespace osuCrypto::Subfield // The number of OTs actually produced (at least the number requested). u64 mN = 0; - + // The length of the noisy vectors (2 * mN for the silver codes). u64 mN2 = 0; - + // We perform regular LPN, so this is the // size of the each chunk. u64 mSizePer = 0; @@ -73,17 +73,7 @@ namespace osuCrypto::Subfield // the sparse vector. MultType mMultType = DefaultMultType; -#ifdef ENABLE_INSECURE_SILVER - // The silver encoder. - SilverEncoder mEncoder; -#endif - ExConvCode mExConvEncoder; -// EACode mEAEncoder; - -#ifdef ENABLE_BITPOLYMUL -// QuasiCyclicCode mQuasiCyclicEncoder; -#endif // The multi-point punctured PRF for generating // the sparse vectors. @@ -104,10 +94,10 @@ namespace osuCrypto::Subfield BitVector mIknpSendBaseChoice, mGapBaseChoice; - SilentSecType mMalType = SilentSecType::SemiHonest; + SilentSecType mMalType = SilentSecType::SemiHonest; block mMalCheckSeed, mMalCheckX, mDeltaShare; - + AlignedVector mNoiseDeltaShare; AlignedVector mNoiseValues; @@ -117,140 +107,129 @@ namespace osuCrypto::Subfield SoftSpokenMalOtReceiver mOtExtRecver; #endif -// // sets the Iknp base OTs that are then used to extend -// void setBaseOts( -// span> baseSendOts); -// -// // return the number of base OTs IKNP needs -// u64 baseOtCount() const; + // // sets the Iknp base OTs that are then used to extend + // void setBaseOts( + // span> baseSendOts); + // + // // return the number of base OTs IKNP needs + // u64 baseOtCount() const; u64 baseVoleCount() const { return mNumPartitions + mGapOts.size() + 1 * (mMalType == SilentSecType::Malicious); } -// // returns true if the IKNP base OTs are currently set. -// bool hasBaseOts() const; -// - // returns true if the silent base OTs are set. + // // returns true if the IKNP base OTs are currently set. + // bool hasBaseOts() const; + // + // returns true if the silent base OTs are set. bool hasSilentBaseOts() const { return mGen.hasBaseOts(); }; -// -// // Generate the IKNP base OTs -// task<> genBaseOts(PRNG& prng, Socket& chl) ; + // + // // Generate the IKNP base OTs + // task<> genBaseOts(PRNG& prng, Socket& chl) ; // Generate the silent base OTs. If the Iknp // base OTs are set then we do an IKNP extend, // otherwise we perform a base OT protocol to // generate the needed OTs. task<> genSilentBaseOts(PRNG& prng, Socket& chl) - { - using BaseOT = DefaultBaseOT; - - - MC_BEGIN(task<>, this, &prng, &chl, - choice = BitVector{}, - bb = BitVector{}, - msg = AlignedUnVector{}, - baseVole = std::vector{}, - baseOt = BaseOT{}, - chl2 = Socket{}, - prng2 = std::move(PRNG{}), - noiseVals = std::vector{}, - noiseDeltaShares = std::vector{}, - nv = NoisySubfieldVoleReceiver{} - - ); - - setTimePoint("SilentVoleReceiver.genSilent.begin"); - if (isConfigured() == false) - throw std::runtime_error("configure must be called first"); - - choice = sampleBaseChoiceBits(prng); - msg.resize(choice.size()); - - // sample the noise vector noiseVals such that we will compute - // - // C = (000 noiseVals[0] 0000 ... 000 noiseVals[p] 000) - // - // and then we want secret shares of C * delta. As a first step - // we will compute secret shares of - // - // delta * noiseVals - // - // and store our share in voleDeltaShares. This party will then - // compute their share of delta * C as what comes out of the PPRF - // plus voleDeltaShares[i] added to the appreciate spot. Similarly, the - // other party will program the PPRF to output their share of delta * noiseVals. - // - noiseVals = sampleBaseVoleVals(prng); - noiseDeltaShares.resize(noiseVals.size()); - if (mTimer) - nv.setTimer(*mTimer); - - if (mBaseType == SilentBaseType::BaseExtend) - { + { + using BaseOT = DefaultBaseOT; + + + MC_BEGIN(task<>, this, &prng, &chl, + choice = BitVector{}, + bb = BitVector{}, + msg = AlignedUnVector{}, + baseVole = std::vector{}, + baseOt = BaseOT{}, + chl2 = Socket{}, + prng2 = std::move(PRNG{}), + noiseVals = std::vector{}, + noiseDeltaShares = std::vector{}, + nv = NoisySubfieldVoleReceiver{} + + ); + + setTimePoint("SilentVoleReceiver.genSilent.begin"); + if (isConfigured() == false) + throw std::runtime_error("configure must be called first"); + + choice = sampleBaseChoiceBits(prng); + msg.resize(choice.size()); + + // sample the noise vector noiseVals such that we will compute + // + // C = (000 noiseVals[0] 0000 ... 000 noiseVals[p] 000) + // + // and then we want secret shares of C * delta. As a first step + // we will compute secret shares of + // + // delta * noiseVals + // + // and store our share in voleDeltaShares. This party will then + // compute their share of delta * C as what comes out of the PPRF + // plus voleDeltaShares[i] added to the appreciate spot. Similarly, the + // other party will program the PPRF to output their share of delta * noiseVals. + // + noiseVals = sampleBaseVoleVals(prng); + noiseDeltaShares.resize(noiseVals.size()); + if (mTimer) + nv.setTimer(*mTimer); + + if (mBaseType == SilentBaseType::BaseExtend) + { #ifdef ENABLE_SOFTSPOKEN_OT - if (mOtExtSender.hasBaseOts() == false) - { - msg.resize(msg.size() + mOtExtSender.baseOtCount()); - bb.resize(mOtExtSender.baseOtCount()); - bb.randomize(prng); - choice.append(bb); - - MC_AWAIT(mOtExtRecver.receive(choice, msg, prng, chl)); - - mOtExtSender.setBaseOts( - span(msg).subspan( - msg.size() - mOtExtSender.baseOtCount(), - mOtExtSender.baseOtCount()), - bb); - - msg.resize(msg.size() - mOtExtSender.baseOtCount()); - MC_AWAIT(nv.receive(noiseVals, noiseDeltaShares, prng, mOtExtSender, chl)); - } - else - { - chl2 = chl.fork(); - prng2.SetSeed(prng.get()); - - - MC_AWAIT( - macoro::when_all_ready( - nv.receive(noiseVals, noiseDeltaShares, prng2, mOtExtSender, chl2), - mOtExtRecver.receive(choice, msg, prng, chl) - )); - } + if (mOtExtSender.hasBaseOts() == false) + { + msg.resize(msg.size() + mOtExtSender.baseOtCount()); + bb.resize(mOtExtSender.baseOtCount()); + bb.randomize(prng); + choice.append(bb); + + MC_AWAIT(mOtExtRecver.receive(choice, msg, prng, chl)); + + mOtExtSender.setBaseOts( + span(msg).subspan( + msg.size() - mOtExtSender.baseOtCount(), + mOtExtSender.baseOtCount()), + bb); + + msg.resize(msg.size() - mOtExtSender.baseOtCount()); + MC_AWAIT(nv.receive(noiseVals, noiseDeltaShares, prng, mOtExtSender, chl)); + } + else + { + chl2 = chl.fork(); + prng2.SetSeed(prng.get()); + + + MC_AWAIT( + macoro::when_all_ready( + nv.receive(noiseVals, noiseDeltaShares, prng2, mOtExtSender, chl2), + mOtExtRecver.receive(choice, msg, prng, chl) + )); + } #else - throw std::runtime_error("soft spoken must be enabled"); + throw std::runtime_error("soft spoken must be enabled"); #endif - } - else - { - chl2 = chl.fork(); - prng2.SetSeed(prng.get()); - MC_AWAIT(baseOt.receive(choice, msg, prng, chl)); - MC_AWAIT(nv.receive(noiseVals, noiseDeltaShares, prng2, baseOt, chl2)); - -// MC_AWAIT( -// macoro::when_all_ready( -// nv.receive(noiseVals, noiseDeltaShares, prng2, baseOt, chl2), -// baseOt.receive(choice, msg, prng, chl) -// )); - } - - - - - setSilentBaseOts(msg, noiseDeltaShares); + } + else + { + chl2 = chl.fork(); + prng2.SetSeed(prng.get()); + MC_AWAIT(baseOt.receive(choice, msg, prng, chl)); + MC_AWAIT(nv.receive(noiseVals, noiseDeltaShares, prng2, baseOt, chl2)); + } - setTimePoint("SilentVoleReceiver.genSilent.done"); + setSilentBaseOts(msg, noiseDeltaShares); + setTimePoint("SilentVoleReceiver.genSilent.done"); + MC_END(); + }; - MC_END(); - }; - // configure the silent OT extension. This sets // the parameters and figures out how many base OT // will be needed. These can then be ganerated for @@ -260,75 +239,24 @@ namespace osuCrypto::Subfield SilentBaseType type = SilentBaseType::BaseExtend, u64 secParam = 128) { - mState = State::Configured; - u64 gap = 0; - mBaseType = type; - - switch (mMultType) - { -// case osuCrypto::MultType::QuasiCyclic: -// { -// u64 p, s; -// QuasiCyclicConfigure(numOTs, secParam, -// 2, -// mMultType, -// mRequestedNumOTs, -// mNumPartitions, -// mSizePer, -// mN2, -// mN, -// p, -// s -// ); -//#ifdef ENABLE_BITPOLYMUL -// mQuasiCyclicEncoder.init(p, s); -//#else -// throw std::runtime_error("ENABLE_BITPOLYMUL not defined."); -//#endif -// break; -// } -//#ifdef ENABLE_INSECURE_SILVER -// case osuCrypto::MultType::slv5: -// case osuCrypto::MultType::slv11: -// -// SilverConfigure(numOTs, secParam, -// mMultType, -// mRequestedNumOTs, -// mNumPartitions, -// mSizePer, -// mN2, -// mN, -// gap, -// mEncoder); -// -// break; -//#endif -// case osuCrypto::MultType::ExAcc7: -// case osuCrypto::MultType::ExAcc11: -// case osuCrypto::MultType::ExAcc21: -// case osuCrypto::MultType::ExAcc40: -// EAConfigure(numOTs, secParam, -// mMultType, -// mRequestedNumOTs, -// mNumPartitions, -// mSizePer, -// mN2, -// mN, -// mEAEncoder); -// -// break; + mState = State::Configured; + u64 gap = 0; + mBaseType = type; + + switch (mMultType) + { case osuCrypto::MultType::ExConv7x24: case osuCrypto::MultType::ExConv21x24: - SubfieldExConvConfigure(numOTs, 128, mMultType, mRequestedNumOTs, mNumPartitions, mSizePer, mN2, mN, mExConvEncoder); - break; + SubfieldExConvConfigure(numOTs, 128, mMultType, mRequestedNumOTs, mNumPartitions, mSizePer, mN2, mN, mExConvEncoder); + break; default: - throw RTE_LOC; - break; - } + throw RTE_LOC; + break; + } - mGapOts.resize(gap); - mGen.configure(mSizePer, mNumPartitions); + mGapOts.resize(gap); + mGen.configure(mSizePer, mNumPartitions); } // return true if this instance has been configured. @@ -338,10 +266,10 @@ namespace osuCrypto::Subfield // protocol will needs. u64 silentBaseOtCount() const { - if (isConfigured() == false) - throw std::runtime_error("configure must be called first"); + if (isConfigured() == false) + throw std::runtime_error("configure must be called first"); - return mGen.baseOtCount() + mGapOts.size(); + return mGen.baseOtCount() + mGapOts.size(); } @@ -351,84 +279,84 @@ namespace osuCrypto::Subfield // and then pass the OT messages back using setSilentBaseOts(...). BitVector sampleBaseChoiceBits(PRNG& prng) { - if (isConfigured() == false) - throw std::runtime_error("configure(...) must be called first"); + if (isConfigured() == false) + throw std::runtime_error("configure(...) must be called first"); - auto choice = mGen.sampleChoiceBits(mN2, getPprfFormat(), prng); + auto choice = mGen.sampleChoiceBits(mN2, getPprfFormat(), prng); - mGapBaseChoice.resize(mGapOts.size()); - mGapBaseChoice.randomize(prng); - choice.append(mGapBaseChoice); + mGapBaseChoice.resize(mGapOts.size()); + mGapBaseChoice.randomize(prng); + choice.append(mGapBaseChoice); - return choice; + return choice; } std::vector sampleBaseVoleVals(PRNG& prng) { - if (isConfigured() == false) - throw RTE_LOC; - if (mGapBaseChoice.size() != mGapOts.size()) - throw std::runtime_error("sampleBaseChoiceBits must be called before sampleBaseVoleVals. " LOCATION); - - // sample the values of the noisy coordinate of c - // and perform a noicy vole to get x+y = mD * c - auto w = mNumPartitions + mGapOts.size(); - //std::vector y(w); - mNoiseValues.resize(w); - prng.get(mNoiseValues.data(), mNoiseValues.size()); - - mS.resize(mNumPartitions); - mGen.getPoints(mS, getPprfFormat()); - - // todo - std::vector tmp = mS; - std::sort(tmp.begin(), tmp.end()); - - auto j = mNumPartitions * mSizePer; - - for (u64 i = 0; i < (u64)mGapBaseChoice.size(); ++i) - { - if (mGapBaseChoice[i]) + if (isConfigured() == false) + throw RTE_LOC; + if (mGapBaseChoice.size() != mGapOts.size()) + throw std::runtime_error("sampleBaseChoiceBits must be called before sampleBaseVoleVals. " LOCATION); + + // sample the values of the noisy coordinate of c + // and perform a noicy vole to get x+y = mD * c + auto w = mNumPartitions + mGapOts.size(); + //std::vector y(w); + mNoiseValues.resize(w); + prng.get(mNoiseValues.data(), mNoiseValues.size()); + + mS.resize(mNumPartitions); + mGen.getPoints(mS, getPprfFormat()); + + // todo + std::vector tmp = mS; + std::sort(tmp.begin(), tmp.end()); + + auto j = mNumPartitions * mSizePer; + + for (u64 i = 0; i < (u64)mGapBaseChoice.size(); ++i) { - mS.push_back(j + i); + if (mGapBaseChoice[i]) + { + mS.push_back(j + i); + } } - } -// if (mMalType == SilentSecType::Malicious) -// { -// -// mMalCheckSeed = prng.get(); -// mMalCheckX = ZeroBlock; -// auto yIter = mNoiseValues.begin(); -// -// for (u64 i = 0; i < mNumPartitions; ++i) -// { -// auto s = mS[i]; -// auto xs = mMalCheckSeed.gf128Pow(s + 1); -// mMalCheckX = mMalCheckX ^ xs.gf128Mul(*yIter); -// ++yIter; -// } -// -// auto sIter = mS.begin() + mNumPartitions; -// for (u64 i = 0; i < mGapBaseChoice.size(); ++i) -// { -// if (mGapBaseChoice[i]) -// { -// auto s = *sIter; -// auto xs = mMalCheckSeed.gf128Pow(s + 1); -// mMalCheckX = mMalCheckX ^ xs.gf128Mul(*yIter); -// ++sIter; -// } -// ++yIter; -// } -// -// -// std::vector y(mNoiseValues.begin(), mNoiseValues.end()); -// y.push_back(mMalCheckX); -// return y; -// } - - return std::vector(mNoiseValues.begin(), mNoiseValues.end()); + // if (mMalType == SilentSecType::Malicious) + // { + // + // mMalCheckSeed = prng.get(); + // mMalCheckX = ZeroBlock; + // auto yIter = mNoiseValues.begin(); + // + // for (u64 i = 0; i < mNumPartitions; ++i) + // { + // auto s = mS[i]; + // auto xs = mMalCheckSeed.gf128Pow(s + 1); + // mMalCheckX = mMalCheckX ^ xs.gf128Mul(*yIter); + // ++yIter; + // } + // + // auto sIter = mS.begin() + mNumPartitions; + // for (u64 i = 0; i < mGapBaseChoice.size(); ++i) + // { + // if (mGapBaseChoice[i]) + // { + // auto s = *sIter; + // auto xs = mMalCheckSeed.gf128Pow(s + 1); + // mMalCheckX = mMalCheckX ^ xs.gf128Mul(*yIter); + // ++sIter; + // } + // ++yIter; + // } + // + // + // std::vector y(mNoiseValues.begin(), mNoiseValues.end()); + // y.push_back(mMalCheckX); + // return y; + // } + + return std::vector(mNoiseValues.begin(), mNoiseValues.end()); } // Set the externally generated base OTs. This choice @@ -436,27 +364,27 @@ namespace osuCrypto::Subfield void setSilentBaseOts(span recvBaseOts, span noiseDeltaShare) { - if (isConfigured() == false) - throw std::runtime_error("configure(...) must be called first."); + if (isConfigured() == false) + throw std::runtime_error("configure(...) must be called first."); - if (static_cast(recvBaseOts.size()) != silentBaseOtCount()) - throw std::runtime_error("wrong number of silent base OTs"); + if (static_cast(recvBaseOts.size()) != silentBaseOtCount()) + throw std::runtime_error("wrong number of silent base OTs"); - auto genOts = recvBaseOts.subspan(0, mGen.baseOtCount()); - auto gapOts = recvBaseOts.subspan(mGen.baseOtCount(), mGapOts.size()); + auto genOts = recvBaseOts.subspan(0, mGen.baseOtCount()); + auto gapOts = recvBaseOts.subspan(mGen.baseOtCount(), mGapOts.size()); - mGen.setBase(genOts); - std::copy(gapOts.begin(), gapOts.end(), mGapOts.begin()); + mGen.setBase(genOts); + std::copy(gapOts.begin(), gapOts.end(), mGapOts.begin()); -// if (mMalType == SilentSecType::Malicious) -// { -// mDeltaShare = noiseDeltaShare.back(); -// noiseDeltaShare = noiseDeltaShare.subspan(0, noiseDeltaShare.size() - 1); -// } + // if (mMalType == SilentSecType::Malicious) + // { + // mDeltaShare = noiseDeltaShare.back(); + // noiseDeltaShare = noiseDeltaShare.subspan(0, noiseDeltaShare.size() - 1); + // } - mNoiseDeltaShare = AlignedVector(noiseDeltaShare.begin(), noiseDeltaShare.end()); + mNoiseDeltaShare = AlignedVector(noiseDeltaShare.begin(), noiseDeltaShare.end()); - mState = State::HasBase; + mState = State::HasBase; } // Perform the actual OT extension. If silent @@ -466,19 +394,19 @@ namespace osuCrypto::Subfield task<> silentReceive( span c, span b, - PRNG & prng, - Socket & chl) + PRNG& prng, + Socket& chl) { - MC_BEGIN(task<>, this, c, b, &prng, &chl); - if (c.size() != b.size()) - throw RTE_LOC; + MC_BEGIN(task<>, this, c, b, &prng, &chl); + if (c.size() != b.size()) + throw RTE_LOC; - MC_AWAIT(silentReceiveInplace(c.size(), prng, chl)); + MC_AWAIT(silentReceiveInplace(c.size(), prng, chl)); - std::memcpy(c.data(), mC.data(), c.size() * sizeof(G)); - std::memcpy(b.data(), mA.data(), b.size() * sizeof(F)); - clear(); - MC_END(); + std::memcpy(c.data(), mC.data(), c.size() * sizeof(G)); + std::memcpy(b.data(), mA.data(), b.size() * sizeof(F)); + clear(); + MC_END(); } // Perform the actual OT extension. If silent @@ -490,187 +418,136 @@ namespace osuCrypto::Subfield PRNG& prng, Socket& chl) { - MC_BEGIN(task<>, this, n, &prng, &chl, - gapVals = std::vector{}, - myHash = std::array{}, - theirHash = std::array{} - ); - gTimer.setTimePoint("SilentVoleReceiver.ot.enter"); - - if (isConfigured() == false) - { - // first generate 128 normal base OTs - configure(n, SilentBaseType::BaseExtend); -// configure(n, SilentBaseType::Base); - } - - if (mRequestedNumOTs != n) - throw std::invalid_argument("n does not match the requested number of OTs via configure(...). " LOCATION); - - if (hasSilentBaseOts() == false) - { - MC_AWAIT(genSilentBaseOts(prng, chl)); - } - - // allocate mA - mA.resize(0); - mA.resize(mN2); - - setTimePoint("SilentVoleReceiver.alloc"); - - // allocate the space for mC - mC.resize(0); - mC.resize(mN2, AllocType::Zeroed); - setTimePoint("SilentVoleReceiver.alloc.zero"); - - // derandomize the random OTs for the gap - // to have the desired correlation. - gapVals.resize(mGapOts.size()); - - if(gapVals.size()) - MC_AWAIT(chl.recv(gapVals)); - - for (auto g : rng(mGapOts.size())) - { - auto aa = mA.subspan(mNumPartitions * mSizePer); - auto cc = mC.subspan(mNumPartitions * mSizePer); - - auto noise = mNoiseValues.subspan(mNumPartitions); - auto noiseShares = mNoiseDeltaShare.subspan(mNumPartitions); - - if (mGapBaseChoice[g]) - { - cc[g] = noise[g]; - aa[g] = gapVals[g] - TypeTrait::fromBlock(AES(mGapOts[g]).ecbEncBlock(ZeroBlock)) - noiseShares[g]; - } - else - { - aa[g] = TypeTrait::fromBlock(mGapOts[g]); - } - } - - setTimePoint("SilentVoleReceiver.recvGap"); - - - - if (mTimer) - mGen.setTimer(*mTimer); - // expand the seeds into mA - MC_AWAIT(mGen.expand(chl, prng, mA.subspan(0, mNumPartitions * mSizePer), PprfOutputFormat::Interleaved, true, mNumThreads)); - - setTimePoint("SilentVoleReceiver.expand.pprf_transpose"); - - // populate the noisy coordinates of mC and - // update mA to be a secret share of mC * delta - for (u64 i = 0; i < mNumPartitions; ++i) - { - auto pnt = mS[i]; - mC[pnt] = mNoiseValues[i]; - mA[pnt] = mA[pnt] - mNoiseDeltaShare[i]; - } - - - if (mDebug) - { - MC_AWAIT(checkRT(chl)); - setTimePoint("SilentVoleReceiver.expand.checkRT"); - } - - -// if (mMalType == SilentSecType::Malicious) -// { -// MC_AWAIT(chl.send(std::move(mMalCheckSeed))); -// -// myHash = ferretMalCheck(mDeltaShare, mNoiseValues); -// -// MC_AWAIT(chl.recv(theirHash)); -// -// if (theirHash != myHash) -// throw RTE_LOC; -// } + MC_BEGIN(task<>, this, n, &prng, &chl, + gapVals = std::vector{}, + myHash = std::array{}, + theirHash = std::array{} + ); + gTimer.setTimePoint("SilentVoleReceiver.ot.enter"); + + if (isConfigured() == false) + { + // first generate 128 normal base OTs + configure(n, SilentBaseType::BaseExtend); + // configure(n, SilentBaseType::Base); + } - switch (mMultType) - { -// case osuCrypto::MultType::QuasiCyclic: -// -//#ifdef ENABLE_BITPOLYMUL -// if (mTimer) -// mQuasiCyclicEncoder.setTimer(getTimer()); -// -// // compress both mA and mC in place. -// mQuasiCyclicEncoder.dualEncode(mA.subspan(0, mQuasiCyclicEncoder.size())); -// mQuasiCyclicEncoder.dualEncode(mC.subspan(0, mQuasiCyclicEncoder.size())); -//#else -// throw std::runtime_error("ENABLE_BITPOLYMUL not defined."); -//#endif -// -// setTimePoint("SilentVoleReceiver.expand.mQuasiCyclicEncoder.a"); -// break; -//#ifdef ENABLE_INSECURE_SILVER -// case osuCrypto::MultType::slv5: -// case osuCrypto::MultType::slv11: -// if (mTimer) -// mEncoder.setTimer(getTimer()); -// -// // compress both mA and mC in place. -// mEncoder.dualEncode2(mA, mC); -// setTimePoint("SilentVoleReceiver.expand.cirTransEncode.a"); -// break; -//#endif -// case osuCrypto::MultType::ExAcc7: -// case osuCrypto::MultType::ExAcc11: -// case osuCrypto::MultType::ExAcc21: -// case osuCrypto::MultType::ExAcc40: -// { -// if (mTimer) -// mEAEncoder.setTimer(getTimer()); -// -// AlignedUnVector -// A2(mEAEncoder.mMessageSize), -// C2(mEAEncoder.mMessageSize); -// -// // compress both mA and mC in place. -// mEAEncoder.dualEncode2( -// mA.subspan(0, mEAEncoder.mCodeSize), A2, -// mC.subspan(0, mEAEncoder.mCodeSize), C2); -// -// std::swap(mA, A2); -// std::swap(mC, C2); -// -// setTimePoint("SilentVoleReceiver.expand.cirTransEncode.a"); -// break; -// } - case osuCrypto::MultType::ExConv7x24: - case osuCrypto::MultType::ExConv21x24: - if (mTimer) { - mExConvEncoder.setTimer(getTimer()); - } - -// mExConvEncoder.dualEncode(mA.subspan(0, mExConvEncoder.mCodeSize)); -// mExConvEncoder.dualEncode(mC.subspan(0, mExConvEncoder.mCodeSize)); - mExConvEncoder.dualEncode2( - mA.subspan(0, mExConvEncoder.mCodeSize), - mC.subspan(0, mExConvEncoder.mCodeSize) - ); - - break; - default: - throw RTE_LOC; - break; - } - - // resize the buffers down to only contain the real elements. - mA.resize(mRequestedNumOTs); - mC.resize(mRequestedNumOTs); - - mNoiseValues = {}; - mNoiseDeltaShare = {}; - - // make the protocol as done and that - // mA,mC are ready to be consumed. - mState = State::Default; - - MC_END(); + if (mRequestedNumOTs != n) + throw std::invalid_argument("n does not match the requested number of OTs via configure(...). " LOCATION); + + if (hasSilentBaseOts() == false) + { + MC_AWAIT(genSilentBaseOts(prng, chl)); + } + + // allocate mA + mA.resize(0); + mA.resize(mN2); + + setTimePoint("SilentVoleReceiver.alloc"); + + // allocate the space for mC + mC.resize(0); + mC.resize(mN2, AllocType::Zeroed); + setTimePoint("SilentVoleReceiver.alloc.zero"); + + // derandomize the random OTs for the gap + // to have the desired correlation. + gapVals.resize(mGapOts.size()); + + if (gapVals.size()) + MC_AWAIT(chl.recv(gapVals)); + + for (auto g : rng(mGapOts.size())) + { + auto aa = mA.subspan(mNumPartitions * mSizePer); + auto cc = mC.subspan(mNumPartitions * mSizePer); + + auto noise = mNoiseValues.subspan(mNumPartitions); + auto noiseShares = mNoiseDeltaShare.subspan(mNumPartitions); + + if (mGapBaseChoice[g]) + { + cc[g] = noise[g]; + aa[g] = gapVals[g] - TypeTrait::fromBlock(AES(mGapOts[g]).ecbEncBlock(ZeroBlock)) - noiseShares[g]; + } + else + { + aa[g] = TypeTrait::fromBlock(mGapOts[g]); + } + } + + setTimePoint("SilentVoleReceiver.recvGap"); + + + + if (mTimer) + mGen.setTimer(*mTimer); + // expand the seeds into mA + MC_AWAIT(mGen.expand(chl, prng, mA.subspan(0, mNumPartitions * mSizePer), PprfOutputFormat::Interleaved, true, mNumThreads)); + + setTimePoint("SilentVoleReceiver.expand.pprf_transpose"); + + // populate the noisy coordinates of mC and + // update mA to be a secret share of mC * delta + for (u64 i = 0; i < mNumPartitions; ++i) + { + auto pnt = mS[i]; + mC[pnt] = mNoiseValues[i]; + mA[pnt] = mA[pnt] - mNoiseDeltaShare[i]; + } + + + if (mDebug) + { + MC_AWAIT(checkRT(chl)); + setTimePoint("SilentVoleReceiver.expand.checkRT"); + } + + + // if (mMalType == SilentSecType::Malicious) + // { + // MC_AWAIT(chl.send(std::move(mMalCheckSeed))); + // + // myHash = ferretMalCheck(mDeltaShare, mNoiseValues); + // + // MC_AWAIT(chl.recv(theirHash)); + // + // if (theirHash != myHash) + // throw RTE_LOC; + // } + + switch (mMultType) + { + case osuCrypto::MultType::ExConv7x24: + case osuCrypto::MultType::ExConv21x24: + if (mTimer) { + mExConvEncoder.setTimer(getTimer()); + } + + mExConvEncoder.dualEncode2( + mA.subspan(0, mExConvEncoder.mCodeSize), + mC.subspan(0, mExConvEncoder.mCodeSize) + ); + + break; + default: + throw RTE_LOC; + break; + } + + // resize the buffers down to only contain the real elements. + mA.resize(mRequestedNumOTs); + mC.resize(mRequestedNumOTs); + + mNoiseValues = {}; + mNoiseDeltaShare = {}; + + // make the protocol as done and that + // mA,mC are ready to be consumed. + mState = State::Default; + + MC_END(); } @@ -678,36 +555,36 @@ namespace osuCrypto::Subfield // internal. task<> checkRT(Socket& chl) const { - MC_BEGIN(task<>, this, &chl, - B = AlignedVector(mA.size()), - sparseNoiseDelta = std::vector(mA.size()), - noiseDeltaShare2 = std::vector(), - delta = F{} - ); - //std::vector mB(mA.size()); - MC_AWAIT(chl.recv(delta)); - MC_AWAIT(chl.recv(B)); - MC_AWAIT(chl.recvResize(noiseDeltaShare2)); - - for (u64 i = 0; i < mA.size(); i++) { - F left = delta * mC[i]; - F right = mA[i] - B[i]; - if (left != right) { + MC_BEGIN(task<>, this, &chl, + B = AlignedVector(mA.size()), + sparseNoiseDelta = std::vector(mA.size()), + noiseDeltaShare2 = std::vector(), + delta = F{} + ); + //std::vector mB(mA.size()); + MC_AWAIT(chl.recv(delta)); + MC_AWAIT(chl.recv(B)); + MC_AWAIT(chl.recvResize(noiseDeltaShare2)); + + for (u64 i = 0; i < mA.size(); i++) { + F left = delta * mC[i]; + F right = mA[i] - B[i]; + if (left != right) { throw RTE_LOC; - } - } - - //check that at locations mS[0],...,mS[..] - // that we hold a sharing mA, mB of - // - // delta * mC = delta * (00000 noiseDeltaShare2[0] 0000 .... 0000 noiseDeltaShare2[m] 0000) - // - // where noiseDeltaShare2[i] is at position mS[i] of mC - // - // That is, I hold mA, mC s.t. - // - // delta * mC = mA + mB - // + } + } + + //check that at locations mS[0],...,mS[..] + // that we hold a sharing mA, mB of + // + // delta * mC = delta * (00000 noiseDeltaShare2[0] 0000 .... 0000 noiseDeltaShare2[m] 0000) + // + // where noiseDeltaShare2[i] is at position mS[i] of mC + // + // That is, I hold mA, mC s.t. + // + // delta * mC = mA + mB + // // if (noiseDeltaShare2.size() != mNoiseDeltaShare.size()) // throw RTE_LOC; @@ -858,7 +735,7 @@ namespace osuCrypto::Subfield // std::cout << "debug check ok" << std::endl; //} - MC_END(); + MC_END(); } std::array ferretMalCheck( @@ -866,29 +743,29 @@ namespace osuCrypto::Subfield span y) { - block xx = mMalCheckSeed; - block sum0 = ZeroBlock; - block sum1 = ZeroBlock; - - - for (u64 i = 0; i < (u64)mA.size(); ++i) - { - block low, high; - xx.gf128Mul(mA[i], low, high); - sum0 = sum0 ^ low; - sum1 = sum1 ^ high; - //mySum = mySum ^ xx.gf128Mul(mA[i]); - - // xx = mMalCheckSeed^{i+1} - xx = xx.gf128Mul(mMalCheckSeed); - } - block mySum = sum0.gf128Reduce(sum1); - - std::array myHash; - RandomOracle ro(32); - ro.Update(mySum ^ deltaShare); - ro.Final(myHash); - return myHash; + block xx = mMalCheckSeed; + block sum0 = ZeroBlock; + block sum1 = ZeroBlock; + + + for (u64 i = 0; i < (u64)mA.size(); ++i) + { + block low, high; + xx.gf128Mul(mA[i], low, high); + sum0 = sum0 ^ low; + sum1 = sum1 ^ high; + //mySum = mySum ^ xx.gf128Mul(mA[i]); + + // xx = mMalCheckSeed^{i+1} + xx = xx.gf128Mul(mMalCheckSeed); + } + block mySum = sum0.gf128Reduce(sum1); + + std::array myHash; + RandomOracle ro(32); + ro.Update(mySum ^ deltaShare); + ro.Final(myHash); + return myHash; } PprfOutputFormat getPprfFormat() @@ -898,11 +775,11 @@ namespace osuCrypto::Subfield void clear() { - mS = {}; - mA = {}; - mC = {}; - mGen.clear(); - mGapBaseChoice = {}; + mS = {}; + mA = {}; + mC = {}; + mGen.clear(); + mGapBaseChoice = {}; } }; } diff --git a/libOTe/Vole/Subfield/SilentVoleSender.h b/libOTe/Vole/Subfield/SilentVoleSender.h index c497d8e1..94cef7eb 100644 --- a/libOTe/Vole/Subfield/SilentVoleSender.h +++ b/libOTe/Vole/Subfield/SilentVoleSender.h @@ -28,7 +28,8 @@ namespace osuCrypto::Subfield { - static void SubfieldExConvConfigure( + + inline void SubfieldExConvConfigure( u64 numOTs, u64 secParam, MultType mMultType, u64& mRequestedNumOTs, @@ -39,34 +40,35 @@ namespace osuCrypto::Subfield ExConvCode& mEncoder ) { - u64 a = 24; - auto mScaler = 2; - u64 w; - double minDist; - switch (mMultType) - { + u64 a = 24; + auto mScaler = 2; + u64 w; + double minDist; + switch (mMultType) + { case osuCrypto::MultType::ExConv7x24: - w = 7; - minDist = 0.1; - break; + w = 7; + minDist = 0.1; + break; case osuCrypto::MultType::ExConv21x24: - w = 21; - minDist = 0.15; - break; + w = 21; + minDist = 0.15; + break; default: - throw RTE_LOC; - break; - } + throw RTE_LOC; + break; + } - mRequestedNumOTs = numOTs; - mNumPartitions = getRegNoiseWeight(minDist, secParam); - mSizePer = roundUpTo((numOTs * mScaler + mNumPartitions - 1) / mNumPartitions, 8); - mN2 = mSizePer * mNumPartitions; - mN = mN2 / mScaler; + mRequestedNumOTs = numOTs; + mNumPartitions = getRegNoiseWeight(minDist, secParam); + mSizePer = roundUpTo((numOTs * mScaler + mNumPartitions - 1) / mNumPartitions, 8); + mN2 = mSizePer * mNumPartitions; + mN = mN2 / mScaler; - mEncoder.config(numOTs, numOTs * mScaler, w, a, true); + mEncoder.config(numOTs, numOTs * mScaler, w, a, true); } + template class SilentSubfieldVoleSender : public TimerAdapter { @@ -96,7 +98,6 @@ namespace osuCrypto::Subfield u64 mNumThreads = 1; std::vector> mGapOts; SilentBaseType mBaseType; - //block mDelta; std::vector mNoiseDeltaShares; SilentSecType mMalType = SilentSecType::SemiHonest; @@ -111,15 +112,7 @@ namespace osuCrypto::Subfield SilverEncoder mEncoder; #endif ExConvCode mExConvEncoder; -// EACode mEAEncoder; -#ifdef ENABLE_BITPOLYMUL -// QuasiCyclicCode mQuasiCyclicEncoder; -#endif - - //span mB; - //u64 mBackingSize = 0; - //std::unique_ptr mBacking; AlignedUnVector mB; ///////////////////////////////////////////////////// @@ -158,78 +151,78 @@ namespace osuCrypto::Subfield // generate the needed OTs. task<> genSilentBaseOts(PRNG& prng, Socket& chl, cp::optional delta = {}) { - using BaseOT = DefaultBaseOT; + using BaseOT = DefaultBaseOT; - MC_BEGIN(task<>,this, delta, &prng, &chl, - msg = AlignedUnVector>(silentBaseOtCount()), - baseOt = BaseOT{}, - prng2 = std::move(PRNG{}), - xx = BitVector{}, - chl2 = Socket{}, - nv = NoisySubfieldVoleSender{}, - noiseDeltaShares = std::vector{} - ); - setTimePoint("SilentVoleSender.genSilent.begin"); + MC_BEGIN(task<>, this, delta, &prng, &chl, + msg = AlignedUnVector>(silentBaseOtCount()), + baseOt = BaseOT{}, + prng2 = std::move(PRNG{}), + xx = BitVector{}, + chl2 = Socket{}, + nv = NoisySubfieldVoleSender{}, + noiseDeltaShares = std::vector{} + ); + setTimePoint("SilentVoleSender.genSilent.begin"); - if (isConfigured() == false) - throw std::runtime_error("configure must be called first"); + if (isConfigured() == false) + throw std::runtime_error("configure must be called first"); - delta = delta.value_or(TypeTrait::fromBlock(prng.get())); - xx.append((u8*)&delta, sizeof (F) * 8); + delta = delta.value_or(TypeTrait::fromBlock(prng.get())); + xx.append((u8*)&delta, sizeof(F) * 8); - // compute the correlation for the noisy coordinates. - noiseDeltaShares.resize(baseVoleCount()); + // compute the correlation for the noisy coordinates. + noiseDeltaShares.resize(baseVoleCount()); - if (mBaseType == SilentBaseType::BaseExtend) - { + if (mBaseType == SilentBaseType::BaseExtend) + { #ifdef ENABLE_SOFTSPOKEN_OT - if (mOtExtRecver.hasBaseOts() == false) - { - msg.resize(msg.size() + mOtExtRecver.baseOtCount()); - MC_AWAIT(mOtExtSender.send(msg, prng, chl)); - - mOtExtRecver.setBaseOts( - span>(msg).subspan( - msg.size() - mOtExtRecver.baseOtCount(), - mOtExtRecver.baseOtCount())); - msg.resize(msg.size() - mOtExtRecver.baseOtCount()); - - MC_AWAIT(nv.send(*delta, noiseDeltaShares, prng, mOtExtRecver, chl)); - } - else - { - chl2 = chl.fork(); - prng2.SetSeed(prng.get()); - - MC_AWAIT( - macoro::when_all_ready( - nv.send(*delta, noiseDeltaShares, prng2, mOtExtRecver, chl2), - mOtExtSender.send(msg, prng, chl))); - } + if (mOtExtRecver.hasBaseOts() == false) + { + msg.resize(msg.size() + mOtExtRecver.baseOtCount()); + MC_AWAIT(mOtExtSender.send(msg, prng, chl)); + + mOtExtRecver.setBaseOts( + span>(msg).subspan( + msg.size() - mOtExtRecver.baseOtCount(), + mOtExtRecver.baseOtCount())); + msg.resize(msg.size() - mOtExtRecver.baseOtCount()); + + MC_AWAIT(nv.send(*delta, noiseDeltaShares, prng, mOtExtRecver, chl)); + } + else + { + chl2 = chl.fork(); + prng2.SetSeed(prng.get()); + + MC_AWAIT( + macoro::when_all_ready( + nv.send(*delta, noiseDeltaShares, prng2, mOtExtRecver, chl2), + mOtExtSender.send(msg, prng, chl))); + } #else #endif - } - else - { - chl2 = chl.fork(); - prng2.SetSeed(prng.get()); - MC_AWAIT(baseOt.send(msg, prng, chl)); - MC_AWAIT(nv.send(*delta, noiseDeltaShares, prng2, baseOt, chl2)); -// MC_AWAIT( -// macoro::when_all_ready( -// nv.send(*delta, noiseDeltaShares, prng2, baseOt, chl2), -// baseOt.send(msg, prng, chl))); - } - - - setSilentBaseOts(msg, noiseDeltaShares); - setTimePoint("SilentVoleSender.genSilent.done"); - MC_END(); + } + else + { + chl2 = chl.fork(); + prng2.SetSeed(prng.get()); + MC_AWAIT(baseOt.send(msg, prng, chl)); + MC_AWAIT(nv.send(*delta, noiseDeltaShares, prng2, baseOt, chl2)); + // MC_AWAIT( + // macoro::when_all_ready( + // nv.send(*delta, noiseDeltaShares, prng2, baseOt, chl2), + // baseOt.send(msg, prng, chl))); + } + + + setSilentBaseOts(msg, noiseDeltaShares); + setTimePoint("SilentVoleSender.genSilent.done"); + MC_END(); } // configure the silent OT extension. This sets @@ -241,76 +234,25 @@ namespace osuCrypto::Subfield SilentBaseType type = SilentBaseType::BaseExtend, u64 secParam = 128) { - mBaseType = type; - u64 gap = 0; - - switch (mMultType) - { -// case osuCrypto::MultType::QuasiCyclic: -// { -// u64 p, s; -// -// QuasiCyclicConfigure(numOTs, secParam, -// 2, -// mMultType, -// mRequestedNumOTs, -// mNumPartitions, -// mSizePer, -// mN2, -// mN, -// p, -// s -// ); -//#ifdef ENABLE_BITPOLYMUL -// mQuasiCyclicEncoder.init(p, s); -//#else -// throw std::runtime_error("ENABLE_BITPOLYMUL not defined."); -//#endif -// break; -// } -//#ifdef ENABLE_INSECURE_SILVER -// case osuCrypto::MultType::slv5: -// case osuCrypto::MultType::slv11: -// -// SilverConfigure(numOTs, secParam, -// mMultType, -// mRequestedNumOTs, -// mNumPartitions, -// mSizePer, -// mN2, -// mN, -// gap, -// mEncoder); -// break; -//#endif -// case osuCrypto::MultType::ExAcc7: -// case osuCrypto::MultType::ExAcc11: -// case osuCrypto::MultType::ExAcc21: -// case osuCrypto::MultType::ExAcc40: -// -// EAConfigure(numOTs, secParam, -// mMultType, -// mRequestedNumOTs, -// mNumPartitions, -// mSizePer, -// mN2, -// mN, -// mEAEncoder); -// break; + mBaseType = type; + u64 gap = 0; + + switch (mMultType) + { case osuCrypto::MultType::ExConv7x24: case osuCrypto::MultType::ExConv21x24: - SubfieldExConvConfigure(numOTs, 128, mMultType, mRequestedNumOTs, mNumPartitions, mSizePer, mN2, mN, mExConvEncoder); - break; + SubfieldExConvConfigure(numOTs, 128, mMultType, mRequestedNumOTs, mNumPartitions, mSizePer, mN2, mN, mExConvEncoder); + break; default: - throw RTE_LOC; - break; - } + throw RTE_LOC; + break; + } - mGapOts.resize(gap); - mGen.configure(mSizePer, mNumPartitions); + mGapOts.resize(gap); + mGen.configure(mSizePer, mNumPartitions); - mState = State::Configured; + mState = State::Configured; } // return true if this instance has been configured. @@ -320,10 +262,10 @@ namespace osuCrypto::Subfield // protocol will needs. u64 silentBaseOtCount() const { - if (isConfigured() == false) - throw std::runtime_error("configure must be called first"); + if (isConfigured() == false) + throw std::runtime_error("configure must be called first"); - return mGen.baseOtCount() + mGapOts.size(); + return mGen.baseOtCount() + mGapOts.size(); } // Set the externally generated base OTs. This choice @@ -331,21 +273,21 @@ namespace osuCrypto::Subfield void setSilentBaseOts( span> sendBaseOts, span noiseDeltaShares) - { - if ((u64)sendBaseOts.size() != silentBaseOtCount()) - throw RTE_LOC; + { + if ((u64)sendBaseOts.size() != silentBaseOtCount()) + throw RTE_LOC; - if (noiseDeltaShares.size() != baseVoleCount()) - throw RTE_LOC; + if (noiseDeltaShares.size() != baseVoleCount()) + throw RTE_LOC; - auto genOt = sendBaseOts.subspan(0, mGen.baseOtCount()); - auto gapOt = sendBaseOts.subspan(genOt.size(), mGapOts.size()); + auto genOt = sendBaseOts.subspan(0, mGen.baseOtCount()); + auto gapOt = sendBaseOts.subspan(genOt.size(), mGapOts.size()); - mGen.setBase(genOt); - std::copy(gapOt.begin(), gapOt.end(), mGapOts.begin()); - mNoiseDeltaShares.resize(noiseDeltaShares.size()); - std::copy(noiseDeltaShares.begin(), noiseDeltaShares.end(), mNoiseDeltaShares.begin()); - } + mGen.setBase(genOt); + std::copy(gapOt.begin(), gapOt.end(), mGapOts.begin()); + mNoiseDeltaShares.resize(noiseDeltaShares.size()); + std::copy(noiseDeltaShares.begin(), noiseDeltaShares.end(), mNoiseDeltaShares.begin()); + } // The native OT extension interface of silent // OT. The receiver does not get to specify @@ -358,15 +300,15 @@ namespace osuCrypto::Subfield PRNG& prng, Socket& chl) { - MC_BEGIN(task<>,this, delta, b, &prng, &chl); + MC_BEGIN(task<>, this, delta, b, &prng, &chl); - MC_AWAIT(silentSendInplace(delta, b.size(), prng, chl)); + MC_AWAIT(silentSendInplace(delta, b.size(), prng, chl)); - std::memcpy(b.data(), mB.data(), b.size() * sizeof(F)); - clear(); + std::memcpy(b.data(), mB.data(), b.size() * sizeof(F)); + clear(); - setTimePoint("SilentVoleSender.expand.ldpc.msgCpy"); - MC_END(); + setTimePoint("SilentVoleSender.expand.ldpc.msgCpy"); + MC_END(); } // The native OT extension interface of silent @@ -380,37 +322,35 @@ namespace osuCrypto::Subfield PRNG& prng, Socket& chl) { - MC_BEGIN(task<>,this, delta, n, &prng, &chl, - gapVals = std::vector{}, - deltaShare = block{}, - X = block{}, - hash = std::array{}, - noiseShares = span{}, - mbb = span{} - ); - setTimePoint("SilentVoleSender.ot.enter"); - - - if (isConfigured() == false) - { - // first generate 128 normal base OTs - configure(n, SilentBaseType::BaseExtend); -// configure(n, SilentBaseType::Base); - } - - if (mRequestedNumOTs != n) - throw std::invalid_argument("n does not match the requested number of OTs via configure(...). " LOCATION); - - if (mGen.hasBaseOts() == false) - { - // recvs data - MC_AWAIT(genSilentBaseOts(prng, chl, delta)); - } - - //mDelta = delta; - - setTimePoint("SilentVoleSender.start"); - //gTimer.setTimePoint("SilentVoleSender.iknp.base2"); + MC_BEGIN(task<>, this, delta, n, &prng, &chl, + gapVals = std::vector{}, + deltaShare = block{}, + X = block{}, + hash = std::array{}, + noiseShares = span{}, + mbb = span{} + ); + setTimePoint("SilentVoleSender.ot.enter"); + + + if (isConfigured() == false) + { + // first generate 128 normal base OTs + configure(n, SilentBaseType::BaseExtend); + // configure(n, SilentBaseType::Base); + } + + if (mRequestedNumOTs != n) + throw std::invalid_argument("n does not match the requested number of OTs via configure(...). " LOCATION); + + if (mGen.hasBaseOts() == false) + { + // recvs data + MC_AWAIT(genSilentBaseOts(prng, chl, delta)); + } + + setTimePoint("SilentVoleSender.start"); + //gTimer.setTimePoint("SilentVoleSender.iknp.base2"); // if (mMalType == SilentSecType::Malicious) // { @@ -419,154 +359,116 @@ namespace osuCrypto::Subfield // } // allocate B - mB.resize(0); - mB.resize(mN2); - - // derandomize the random OTs for the gap - // to have the desired correlation. - gapVals.resize(mGapOts.size()); - for (u64 i = mNumPartitions * mSizePer, j = 0; i < mN2; ++i, ++j) - { - auto t = TypeTrait::fromBlock(mGapOts[j][0]); - auto v = t + mNoiseDeltaShares[mNumPartitions + j]; - gapVals[j] = TypeTrait::fromBlock(AES(mGapOts[j][1]).ecbEncBlock(ZeroBlock)) + v; - mB[i] = t; - } - - if(gapVals.size()) - MC_AWAIT(chl.send(std::move(gapVals))); - - - if (mTimer) - mGen.setTimer(*mTimer); - - // program the output the PPRF to be secret shares of - // our secret share of delta * noiseVals. The receiver - // can then manually add their shares of this to the - // output of the PPRF at the correct locations. - noiseShares = span(mNoiseDeltaShares.data(), mNumPartitions); - mbb = mB.subspan(0, mNumPartitions * mSizePer); - MC_AWAIT(mGen.expand(chl, noiseShares, prng, mbb, - PprfOutputFormat::Interleaved, true, mNumThreads)); - - setTimePoint("SilentVoleSender.expand.pprf_transpose"); - if (mDebug) - { - MC_AWAIT(checkRT(chl, delta)); - setTimePoint("SilentVoleSender.expand.checkRT"); - } + mB.resize(0); + mB.resize(mN2); + + // derandomize the random OTs for the gap + // to have the desired correlation. + gapVals.resize(mGapOts.size()); + for (u64 i = mNumPartitions * mSizePer, j = 0; i < mN2; ++i, ++j) + { + auto t = TypeTrait::fromBlock(mGapOts[j][0]); + auto v = t + mNoiseDeltaShares[mNumPartitions + j]; + gapVals[j] = TypeTrait::fromBlock(AES(mGapOts[j][1]).ecbEncBlock(ZeroBlock)) + v; + mB[i] = t; + } + + if (gapVals.size()) + MC_AWAIT(chl.send(std::move(gapVals))); + + + if (mTimer) + mGen.setTimer(*mTimer); + + // program the output the PPRF to be secret shares of + // our secret share of delta * noiseVals. The receiver + // can then manually add their shares of this to the + // output of the PPRF at the correct locations. + noiseShares = span(mNoiseDeltaShares.data(), mNumPartitions); + mbb = mB.subspan(0, mNumPartitions * mSizePer); + MC_AWAIT(mGen.expand(chl, noiseShares, prng, mbb, + PprfOutputFormat::Interleaved, true, mNumThreads)); + + setTimePoint("SilentVoleSender.expand.pprf_transpose"); + if (mDebug) + { + MC_AWAIT(checkRT(chl, delta)); + setTimePoint("SilentVoleSender.expand.checkRT"); + } + + + // if (mMalType == SilentSecType::Malicious) + // { + // MC_AWAIT(chl.recv(X)); + // hash = ferretMalCheck(X, deltaShare); + // MC_AWAIT(chl.send(std::move(hash))); + // } + + switch (mMultType) + { + case osuCrypto::MultType::ExConv7x24: + case osuCrypto::MultType::ExConv21x24: + if (mTimer) { + mExConvEncoder.setTimer(getTimer()); + } + mExConvEncoder.dualEncode(mB.subspan(0, mExConvEncoder.mCodeSize)); + break; + default: + throw RTE_LOC; + break; + } -// if (mMalType == SilentSecType::Malicious) -// { -// MC_AWAIT(chl.recv(X)); -// hash = ferretMalCheck(X, deltaShare); -// MC_AWAIT(chl.send(std::move(hash))); -// } + mB.resize(mRequestedNumOTs); - switch (mMultType) - { -// case osuCrypto::MultType::QuasiCyclic: -// -//#ifdef ENABLE_BITPOLYMUL -// -// if (mTimer) -// mQuasiCyclicEncoder.setTimer(getTimer()); -// -// mQuasiCyclicEncoder.dualEncode(mB.subspan(0, mQuasiCyclicEncoder.size())); -//#else -// throw std::runtime_error("ENABLE_BITPOLYMUL not defined."); -//#endif -// setTimePoint("SilentVoleSender.expand.QuasiCyclic"); -// break; -//#ifdef ENABLE_INSECURE_SILVER -// case osuCrypto::MultType::slv5: -// case osuCrypto::MultType::slv11: -// -// if (mTimer) -// mEncoder.setTimer(getTimer()); -// -// mEncoder.dualEncode(mB); -// setTimePoint("SilentVoleSender.expand.Silver"); -// break; -//#endif -// case osuCrypto::MultType::ExAcc7: -// case osuCrypto::MultType::ExAcc11: -// case osuCrypto::MultType::ExAcc21: -// case osuCrypto::MultType::ExAcc40: -// { -// if (mTimer) -// mEAEncoder.setTimer(getTimer()); -// AlignedUnVector B2(mEAEncoder.mMessageSize); -// mEAEncoder.dualEncode(mB.subspan(0,mEAEncoder.mCodeSize), B2); -// std::swap(mB, B2); -// -// setTimePoint("SilentVoleSender.expand.Silver"); -// break; -// } - case osuCrypto::MultType::ExConv7x24: - case osuCrypto::MultType::ExConv21x24: - if (mTimer) { - mExConvEncoder.setTimer(getTimer()); - } - mExConvEncoder.dualEncode(mB.subspan(0, mExConvEncoder.mCodeSize)); - break; - default: - throw RTE_LOC; - break; - } - - - mB.resize(mRequestedNumOTs); - - mState = State::Default; - mNoiseDeltaShares.clear(); - - MC_END(); + mState = State::Default; + mNoiseDeltaShares.clear(); + + MC_END(); } bool mDebug = false; task<> checkRT(Socket& chl, F delta) const { - MC_BEGIN(task<>,this, &chl, delta); - MC_AWAIT(chl.send(delta)); - MC_AWAIT(chl.send(mB)); - MC_AWAIT(chl.send(mNoiseDeltaShares)); - MC_END(); + MC_BEGIN(task<>, this, &chl, delta); + MC_AWAIT(chl.send(delta)); + MC_AWAIT(chl.send(mB)); + MC_AWAIT(chl.send(mNoiseDeltaShares)); + MC_END(); } - std::array ferretMalCheck(block X, block deltaShare) + std::array ferretMalCheck(block X, block deltaShare) { - auto xx = X; - block sum0 = ZeroBlock; - block sum1 = ZeroBlock; - for (u64 i = 0; i < (u64)mB.size(); ++i) - { - block low, high; - xx.gf128Mul(mB[i], low, high); - sum0 = sum0 ^ low; - sum1 = sum1 ^ high; + auto xx = X; + block sum0 = ZeroBlock; + block sum1 = ZeroBlock; + for (u64 i = 0; i < (u64)mB.size(); ++i) + { + block low, high; + xx.gf128Mul(mB[i], low, high); + sum0 = sum0 ^ low; + sum1 = sum1 ^ high; - xx = xx.gf128Mul(X); - } + xx = xx.gf128Mul(X); + } - block mySum = sum0.gf128Reduce(sum1); + block mySum = sum0.gf128Reduce(sum1); - std::array myHash; - RandomOracle ro(32); - ro.Update(mySum ^ deltaShare); - ro.Final(myHash); + std::array myHash; + RandomOracle ro(32); + ro.Update(mySum ^ deltaShare); + ro.Final(myHash); - return myHash; - //chl.send(myHash); + return myHash; + //chl.send(myHash); } void clear() { - mB = {}; - mGen.clear(); + mB = {}; + mGen.clear(); } }; diff --git a/libOTe_Tests/CMakeLists.txt b/libOTe_Tests/CMakeLists.txt index d219908b..2ab6a2ab 100644 --- a/libOTe_Tests/CMakeLists.txt +++ b/libOTe_Tests/CMakeLists.txt @@ -21,4 +21,4 @@ if(MSVC) else() target_compile_options(libOTe_Tests PRIVATE $<$:-std=c++${LIBOTE_STD_VER}>) -endif() \ No newline at end of file +endif() \ No newline at end of file diff --git a/libOTe_Tests/Subfield_Tests.cpp b/libOTe_Tests/Subfield_Tests.cpp index 85aa78f0..a057e168 100644 --- a/libOTe_Tests/Subfield_Tests.cpp +++ b/libOTe_Tests/Subfield_Tests.cpp @@ -11,481 +11,481 @@ namespace osuCrypto::Subfield { -using tests_libOTe::eval; + using tests_libOTe::eval; -void Subfield_ExConvCode_encode_test(const oc::CLP& cmd) -{ - { - u64 n = 1024; - ExConvCode code; - code.config(n / 2, n, 7, 24, true); - - PRNG prng(ZeroBlock); - F128 delta = prng.get(); - std::vector y(n), z0(n), z1(n); - prng.get(y.data(), y.size()); - prng.get(z0.data(), z0.size()); - for (u64 i = 0; i < n; ++i) - { - z1[i] = z0[i] + delta * y[i]; - } - - assert(std::is_trivial::value); - - code.dualEncode(z1); - code.dualEncode(z0); - code.dualEncode(y); - - for (u64 i = 0; i < n; ++i) - { - F128 left = delta * y[i]; - F128 right = z1[i] - z0[i]; - if (left != right) - throw RTE_LOC; - } - } - - { - u64 n = 1024; - ExConvCode code; - code.config(n / 2, n, 7, 24, true); - - PRNG prng(ZeroBlock); - u128 delta = fromBlock(prng.get()); - std::vector y(n), z0(n), z1(n); - prng.get(y.data(), y.size()); - prng.get(z0.data(), z0.size()); - for (u64 i = 0; i < n; ++i) - { - z1[i] = z0[i] + delta * y[i]; - } - - code.dualEncode(z1); - code.dualEncode2(z0, y); - - for (u64 i = 0; i < n; ++i) - { - u128 left = delta * y[i]; - u128 right = z1[i] - z0[i]; - if (left != right) - throw RTE_LOC; - } - } - - { - u64 n = 1024; - ExConvCode code; - code.config(n / 2, n, 7, 24, true); - - PRNG prng(ZeroBlock); - u8 delta = 111; - std::vector y(n), z0(n), z1(n); - prng.get(y.data(), y.size()); - prng.get(z0.data(), z0.size()); - for (u64 i = 0; i < n; ++i) + void Subfield_ExConvCode_encode_test(const oc::CLP& cmd) { - z1[i] = z0[i] + delta * y[i]; - } - - code.dualEncode(z1); - code.dualEncode2(z0, y); + { + u64 n = 1024; + ExConvCode code; + code.config(n / 2, n, 7, 24, true); + + PRNG prng(ZeroBlock); + F128 delta = prng.get(); + std::vector y(n), z0(n), z1(n); + prng.get(y.data(), y.size()); + prng.get(z0.data(), z0.size()); + for (u64 i = 0; i < n; ++i) + { + z1[i] = z0[i] + delta * y[i]; + } + + static_assert(std::is_trivial::value); + + code.dualEncode(z1); + code.dualEncode(z0); + code.dualEncode(y); + + for (u64 i = 0; i < n; ++i) + { + F128 left = delta * y[i]; + F128 right = z1[i] - z0[i]; + if (left != right) + throw RTE_LOC; + } + } - for (u64 i = 0; i < n; ++i) - { - u8 left = delta * y[i]; - u8 right = z1[i] - z0[i]; - if (left != right) - throw RTE_LOC; - } - } - - { - u64 n = 1024; - ExConvCode code; - code.config(n / 2, n, 7, 24, true); - - PRNG prng(ZeroBlock); - u64 delta = 111; - std::vector y(n), z0(n), z1(n); - prng.get(y.data(), y.size()); - prng.get(z0.data(), z0.size()); - for (u64 i = 0; i < n; ++i) - { - z1[i] = z0[i] + delta * y[i]; - } + //{ + // u64 n = 1024; + // ExConvCode code; + // code.config(n / 2, n, 7, 24, true); + + // PRNG prng(ZeroBlock); + // u128 delta = fromBlock(prng.get()); + // std::vector y(n), z0(n), z1(n); + // prng.get(y.data(), y.size()); + // prng.get(z0.data(), z0.size()); + // for (u64 i = 0; i < n; ++i) + // { + // z1[i] = z0[i] + delta * y[i]; + // } + + // code.dualEncode(z1); + // code.dualEncode2(z0, y); + + // for (u64 i = 0; i < n; ++i) + // { + // u128 left = delta * y[i]; + // u128 right = z1[i] - z0[i]; + // if (left != right) + // throw RTE_LOC; + // } + //} - code.dualEncode(z1); - code.dualEncode2(z0, y); + { + u64 n = 1024; + ExConvCode code; + code.config(n / 2, n, 7, 24, true); + + PRNG prng(ZeroBlock); + u8 delta = 111; + std::vector y(n), z0(n), z1(n); + prng.get(y.data(), y.size()); + prng.get(z0.data(), z0.size()); + for (u64 i = 0; i < n; ++i) + { + z1[i] = z0[i] + delta * y[i]; + } + + code.dualEncode(z1); + code.dualEncode2(z0, y); + + for (u64 i = 0; i < n; ++i) + { + u8 left = delta * y[i]; + u8 right = z1[i] - z0[i]; + if (left != right) + throw RTE_LOC; + } + } - for (u64 i = 0; i < n; ++i) - { - u64 left = delta * y[i]; - u64 right = z1[i] - z0[i]; - if (left != right) - throw RTE_LOC; + { + u64 n = 1024; + ExConvCode code; + code.config(n / 2, n, 7, 24, true); + + PRNG prng(ZeroBlock); + u64 delta = 111; + std::vector y(n), z0(n), z1(n); + prng.get(y.data(), y.size()); + prng.get(z0.data(), z0.size()); + for (u64 i = 0; i < n; ++i) + { + z1[i] = z0[i] + delta * y[i]; + } + + code.dualEncode(z1); + code.dualEncode2(z0, y); + + for (u64 i = 0; i < n; ++i) + { + u64 left = delta * y[i]; + u64 right = z1[i] - z0[i]; + if (left != right) + throw RTE_LOC; + } + } } - } -} -void Subfield_Tools_Pprf_test(const oc::CLP& cmd) { + void Subfield_Tools_Pprf_test(const oc::CLP& cmd) { #if defined(ENABLE_SILENTOT) || defined(ENABLE_SILENT_VOLE) - { - u64 domain = cmd.getOr("d", 16); - auto threads = cmd.getOr("t", 1); - u64 numPoints = cmd.getOr("s", 1) * 8; - - PRNG prng(ZeroBlock); - - auto sockets = cp::LocalAsyncSocket::makePair(); - - auto format = PprfOutputFormat::Interleaved; - SilentSubfieldPprfSender sender; - SilentSubfieldPprfReceiver recver; - - sender.configure(domain, numPoints); - recver.configure(domain, numPoints); - - auto numOTs = sender.baseOtCount(); - std::vector> sendOTs(numOTs); - std::vector recvOTs(numOTs); - BitVector recvBits = recver.sampleChoiceBits(domain * numPoints, format, prng); - //recvBits.randomize(prng); - - //recvBits[16] = 1; - prng.get(sendOTs.data(), sendOTs.size()); - for (u64 i = 0; i < numOTs; ++i) { - //recvBits[i] = 0; - recvOTs[i] = sendOTs[i][recvBits[i]]; - } - sender.setBase(sendOTs); - recver.setBase(recvOTs); - - //auto cols = (numPoints * domain + 127) / 128; - Matrix sOut2(numPoints * domain, 1); - Matrix rOut2(numPoints * domain, 1); - std::vector points(numPoints); - recver.getPoints(points, format); - - std::vector arr(numPoints); - prng.get(arr.data(), arr.size()); - auto p0 = sender.expand(sockets[0], arr, prng, sOut2, format, true, threads); - auto p1 = recver.expand(sockets[1], prng, rOut2, format, true, threads); - - eval(p0, p1); - for (u64 i = 0; i < numPoints; i++) { - u64 point = points[i]; - auto exp = sOut2(point) + arr[i]; - if (exp != rOut2(point)) { - throw RTE_LOC; - } - } - } + //{ + // u64 domain = cmd.getOr("d", 16); + // auto threads = cmd.getOr("t", 1); + // u64 numPoints = cmd.getOr("s", 1) * 8; + + // PRNG prng(ZeroBlock); + + // auto sockets = cp::LocalAsyncSocket::makePair(); + + // auto format = PprfOutputFormat::Interleaved; + // SilentSubfieldPprfSender sender; + // SilentSubfieldPprfReceiver recver; + + // sender.configure(domain, numPoints); + // recver.configure(domain, numPoints); + + // auto numOTs = sender.baseOtCount(); + // std::vector> sendOTs(numOTs); + // std::vector recvOTs(numOTs); + // BitVector recvBits = recver.sampleChoiceBits(domain * numPoints, format, prng); + // //recvBits.randomize(prng); + + // //recvBits[16] = 1; + // prng.get(sendOTs.data(), sendOTs.size()); + // for (u64 i = 0; i < numOTs; ++i) { + // //recvBits[i] = 0; + // recvOTs[i] = sendOTs[i][recvBits[i]]; + // } + // sender.setBase(sendOTs); + // recver.setBase(recvOTs); + + // //auto cols = (numPoints * domain + 127) / 128; + // Matrix sOut2(numPoints * domain, 1); + // Matrix rOut2(numPoints * domain, 1); + // std::vector points(numPoints); + // recver.getPoints(points, format); + + // std::vector arr(numPoints); + // prng.get(arr.data(), arr.size()); + // auto p0 = sender.expand(sockets[0], arr, prng, sOut2, format, true, threads); + // auto p1 = recver.expand(sockets[1], prng, rOut2, format, true, threads); + + // eval(p0, p1); + // for (u64 i = 0; i < numPoints; i++) { + // u64 point = points[i]; + // auto exp = sOut2(point) + arr[i]; + // if (exp != rOut2(point)) { + // throw RTE_LOC; + // } + // } + //} #else - throw UnitTestSkipped("ENABLE_SILENTOT not defined."); + throw UnitTestSkipped("ENABLE_SILENTOT not defined."); #endif -} + } -void Subfield_Noisy_Vole_test(const oc::CLP& cmd) { - { - Timer timer; - timer.setTimePoint("start"); - u64 n = cmd.getOr("n", 123); - block seed = block(0, cmd.getOr("seed", 0)); - PRNG prng(seed); + void Subfield_Noisy_Vole_test(const oc::CLP& cmd) { + //{ + // Timer timer; + // timer.setTimePoint("start"); + // u64 n = cmd.getOr("n", 123); + // block seed = block(0, cmd.getOr("seed", 0)); + // PRNG prng(seed); - u128 x = prng.get(); - std::vector y(n); - std::vector z0(n), z1(n); - prng.get(y.data(), y.size()); + // u128 x = prng.get(); + // std::vector y(n); + // std::vector z0(n), z1(n); + // prng.get(y.data(), y.size()); - NoisySubfieldVoleReceiver recv; - NoisySubfieldVoleSender send; + // NoisySubfieldVoleReceiver recv; + // NoisySubfieldVoleSender send; - recv.setTimer(timer); - send.setTimer(timer); + // recv.setTimer(timer); + // send.setTimer(timer); - auto chls = cp::LocalAsyncSocket::makePair(); - timer.setTimePoint("net"); + // auto chls = cp::LocalAsyncSocket::makePair(); + // timer.setTimePoint("net"); - BitVector recvChoice((u8*)&x, 128); - std::vector otRecvMsg(128); - std::vector> otSendMsg(128); - prng.get>(otSendMsg); - for (u64 i = 0; i < 128; ++i) - otRecvMsg[i] = otSendMsg[i][recvChoice[i]]; - timer.setTimePoint("ot"); + // BitVector recvChoice((u8*)&x, 128); + // std::vector otRecvMsg(128); + // std::vector> otSendMsg(128); + // prng.get>(otSendMsg); + // for (u64 i = 0; i < 128; ++i) + // otRecvMsg[i] = otSendMsg[i][recvChoice[i]]; + // timer.setTimePoint("ot"); - auto p0 = recv.receive(y, z0, prng, otSendMsg, chls[0]); - auto p1 = send.send(x, z1, prng, otRecvMsg, chls[1]); + // auto p0 = recv.receive(y, z0, prng, otSendMsg, chls[0]); + // auto p1 = send.send(x, z1, prng, otRecvMsg, chls[1]); - eval(p0, p1); + // eval(p0, p1); - for (u64 i = 0; i < n; ++i) - { - if (x * y[i] != (z1[i] - z0[i])) - { - throw RTE_LOC; - } - } - timer.setTimePoint("done"); + // for (u64 i = 0; i < n; ++i) + // { + // if (x * y[i] != (z1[i] - z0[i])) + // { + // throw RTE_LOC; + // } + // } + // timer.setTimePoint("done"); - //std::cout << timer << std::endl; - } + // //std::cout << timer << std::endl; + //} - { - Timer timer; - timer.setTimePoint("start"); - u64 n = cmd.getOr("n", 123); - block seed = block(0, cmd.getOr("seed", 0)); - PRNG prng(seed); - - u64 x = prng.get(); - std::vector y(n); - std::vector z0(n), z1(n); - prng.get(y.data(), y.size()); - - NoisySubfieldVoleReceiver recv; - NoisySubfieldVoleSender send; - - recv.setTimer(timer); - send.setTimer(timer); - - auto chls = cp::LocalAsyncSocket::makePair(); - timer.setTimePoint("net"); - - BitVector recvChoice((u8*)&x, 64); - std::vector otRecvMsg(64); - std::vector> otSendMsg(64); - prng.get>(otSendMsg); - for (u64 i = 0; i < 64; ++i) - otRecvMsg[i] = otSendMsg[i][recvChoice[i]]; - timer.setTimePoint("ot"); - - auto p0 = recv.receive(y, z0, prng, otSendMsg, chls[0]); - auto p1 = send.send(x, z1, prng, otRecvMsg, chls[1]); - - eval(p0, p1); - - for (u64 i = 0; i < n; ++i) - { - if (x * y[i] != (z1[i] - z0[i])) { - throw RTE_LOC; + Timer timer; + timer.setTimePoint("start"); + u64 n = cmd.getOr("n", 123); + block seed = block(0, cmd.getOr("seed", 0)); + PRNG prng(seed); + + u64 x = prng.get(); + std::vector y(n); + std::vector z0(n), z1(n); + prng.get(y.data(), y.size()); + + NoisySubfieldVoleReceiver recv; + NoisySubfieldVoleSender send; + + recv.setTimer(timer); + send.setTimer(timer); + + auto chls = cp::LocalAsyncSocket::makePair(); + timer.setTimePoint("net"); + + BitVector recvChoice((u8*)&x, 64); + std::vector otRecvMsg(64); + std::vector> otSendMsg(64); + prng.get>(otSendMsg); + for (u64 i = 0; i < 64; ++i) + otRecvMsg[i] = otSendMsg[i][recvChoice[i]]; + timer.setTimePoint("ot"); + + auto p0 = recv.receive(y, z0, prng, otSendMsg, chls[0]); + auto p1 = send.send(x, z1, prng, otRecvMsg, chls[1]); + + eval(p0, p1); + + for (u64 i = 0; i < n; ++i) + { + if (x * y[i] != (z1[i] - z0[i])) + { + throw RTE_LOC; + } + } + timer.setTimePoint("done"); + + //std::cout << timer << std::endl; } - } - timer.setTimePoint("done"); - //std::cout << timer << std::endl; - } - - { - Timer timer; - timer.setTimePoint("start"); - u64 n = cmd.getOr("n", 400); - block seed = block(0, cmd.getOr("seed", 0)); - PRNG prng(seed); - - constexpr size_t N = 10; - using TypeTrait = TypeTraitVec; - u64 bitsF = TypeTrait::bitsF; - using F = TypeTrait::F; - using G = TypeTrait::G; - - F x = TypeTrait::fromBlock(prng.get()); - std::vector y(n); - std::vector z0(n), z1(n); - prng.get(y.data(), y.size()); - - NoisySubfieldVoleReceiver recv; - NoisySubfieldVoleSender send; - - recv.setTimer(timer); - send.setTimer(timer); - - auto chls = cp::LocalAsyncSocket::makePair(); - timer.setTimePoint("net"); - - BitVector recvChoice((u8*)&x, bitsF); - std::vector otRecvMsg(bitsF); - std::vector> otSendMsg(bitsF); - prng.get>(otSendMsg); - for (u64 i = 0; i < bitsF; ++i) - otRecvMsg[i] = otSendMsg[i][recvChoice[i]]; - timer.setTimePoint("ot"); - - auto p0 = recv.receive(y, z0, prng, otSendMsg, chls[0]); - auto p1 = send.send(x, z1, prng, otRecvMsg, chls[1]); - - eval(p0, p1); -// std::cout << "transferred " << (chls[0].bytesSent() + chls[0].bytesReceived()) << std::endl; - timer.setTimePoint("verify"); - - for (u64 i = 0; i < n; ++i) - { - for (u64 j = 0; j < N; j++) { - G left = x[j] * y[i]; - G right = z1[i][j] - z0[i][j]; - if (left != right) - { - throw RTE_LOC; - } + { + Timer timer; + timer.setTimePoint("start"); + u64 n = cmd.getOr("n", 400); + block seed = block(0, cmd.getOr("seed", 0)); + PRNG prng(seed); + + constexpr size_t N = 3; + using TypeTrait = TypeTraitVec; + u64 bitsF = TypeTrait::bitsF; + using F = TypeTrait::F; + using G = TypeTrait::G; + + F x = TypeTrait::fromBlock(prng.get()); + std::vector y(n); + std::vector z0(n), z1(n); + prng.get(y.data(), y.size()); + + NoisySubfieldVoleReceiver recv; + NoisySubfieldVoleSender send; + + recv.setTimer(timer); + send.setTimer(timer); + + auto chls = cp::LocalAsyncSocket::makePair(); + timer.setTimePoint("net"); + + BitVector recvChoice((u8*)&x, bitsF); + std::vector otRecvMsg(bitsF); + std::vector> otSendMsg(bitsF); + prng.get>(otSendMsg); + for (u64 i = 0; i < bitsF; ++i) + otRecvMsg[i] = otSendMsg[i][recvChoice[i]]; + timer.setTimePoint("ot"); + + auto p0 = recv.receive(y, z0, prng, otSendMsg, chls[0]); + auto p1 = send.send(x, z1, prng, otRecvMsg, chls[1]); + + eval(p0, p1); + // std::cout << "transferred " << (chls[0].bytesSent() + chls[0].bytesReceived()) << std::endl; + timer.setTimePoint("verify"); + + for (u64 i = 0; i < n; ++i) + { + for (u64 j = 0; j < N; j++) { + G left = x[j] * y[i]; + G right = z1[i][j] - z0[i][j]; + if (left != right) + { + throw RTE_LOC; + } + } + } + timer.setTimePoint("done"); + + // std::cout << timer << std::endl; } - } - timer.setTimePoint("done"); - -// std::cout << timer << std::endl; } -} -void Subfield_Silent_Vole_test(const oc::CLP& cmd) { - using namespace oc::Subfield; + void Subfield_Silent_Vole_test(const oc::CLP& cmd) { + using namespace oc::Subfield; #if defined(ENABLE_SILENTOT) - Timer timer; - timer.setTimePoint("start"); - u64 n = cmd.getOr("n", 102043); - u64 nt = cmd.getOr("nt", std::thread::hardware_concurrency()); - block seed = block(0, cmd.getOr("seed", 0)); - - { - PRNG prng(seed); - u128 x = TypeTrait128::fromBlock(prng.get()); - std::vector c(n), z0(n), z1(n); - - SilentSubfieldVoleReceiver recv; - SilentSubfieldVoleSender send; - - recv.mMultType = MultType::ExConv7x24; - send.mMultType = MultType::ExConv7x24; - - recv.setTimer(timer); - send.setTimer(timer); - - recv.mDebug = true; - send.mDebug = true; - - auto chls = cp::LocalAsyncSocket::makePair(); - - timer.setTimePoint("net"); - - timer.setTimePoint("ot"); -// fakeBase(n, nt, prng, x, recv, send); - - auto p0 = send.silentSend(x, span(z0), prng, chls[0]); - auto p1 = recv.silentReceive(span(c), span(z1), prng, chls[1]); - - eval(p0, p1); - timer.setTimePoint("send"); - for (u64 i = 0; i < n; ++i) { - u128 left = c[i] * x; - u128 right = z1[i] - z0[i]; - if (left != right) { - std::cout << "bad " << i << "\n c[i] " << u128ToString(c[i]) << " * x " << u128ToString(x) << " = " - << u128ToString(left) << std::endl; - std::cout << "z0[i] " << u128ToString(z0[i]) << " ^ z1 " << u128ToString(z1[i]) << " = " - << u128ToString(right) << std::endl; - throw RTE_LOC; - } - } - } - - { - PRNG prng(seed); - u64 x = TypeTrait128::fromBlock(prng.get()); - std::vector c(n), z0(n), z1(n); - - SilentSubfieldVoleReceiver recv; - SilentSubfieldVoleSender send; - - recv.mMultType = MultType::ExConv7x24; - send.mMultType = MultType::ExConv7x24; - - recv.setTimer(timer); - send.setTimer(timer); - - recv.mDebug = true; - send.mDebug = true; - - auto chls = cp::LocalAsyncSocket::makePair(); - - timer.setTimePoint("net"); + Timer timer; + timer.setTimePoint("start"); + u64 n = cmd.getOr("n", 102043); + u64 nt = cmd.getOr("nt", std::thread::hardware_concurrency()); + block seed = block(0, cmd.getOr("seed", 0)); + + //{ + // PRNG prng(seed); + // u128 x = TypeTrait128::fromBlock(prng.get()); + // std::vector c(n), z0(n), z1(n); + + // SilentSubfieldVoleReceiver recv; + // SilentSubfieldVoleSender send; + + // recv.mMultType = MultType::ExConv7x24; + // send.mMultType = MultType::ExConv7x24; + + // recv.setTimer(timer); + // send.setTimer(timer); + + // recv.mDebug = true; + // send.mDebug = true; + + // auto chls = cp::LocalAsyncSocket::makePair(); + + // timer.setTimePoint("net"); + + // timer.setTimePoint("ot"); + // // fakeBase(n, nt, prng, x, recv, send); + + // auto p0 = send.silentSend(x, span(z0), prng, chls[0]); + // auto p1 = recv.silentReceive(span(c), span(z1), prng, chls[1]); + + // eval(p0, p1); + // timer.setTimePoint("send"); + // for (u64 i = 0; i < n; ++i) { + // u128 left = c[i] * x; + // u128 right = z1[i] - z0[i]; + // if (left != right) { + // std::cout << "bad " << i << "\n c[i] " << u128ToString(c[i]) << " * x " << u128ToString(x) << " = " + // << u128ToString(left) << std::endl; + // std::cout << "z0[i] " << u128ToString(z0[i]) << " ^ z1 " << u128ToString(z1[i]) << " = " + // << u128ToString(right) << std::endl; + // throw RTE_LOC; + // } + // } + //} + + //{ + // PRNG prng(seed); + // u64 x = TypeTrait128::fromBlock(prng.get()); + // std::vector c(n), z0(n), z1(n); + + // SilentSubfieldVoleReceiver recv; + // SilentSubfieldVoleSender send; + + // recv.mMultType = MultType::ExConv7x24; + // send.mMultType = MultType::ExConv7x24; + + // recv.setTimer(timer); + // send.setTimer(timer); + + // recv.mDebug = true; + // send.mDebug = true; + + // auto chls = cp::LocalAsyncSocket::makePair(); + + // timer.setTimePoint("net"); + + // timer.setTimePoint("ot"); + // // fakeBase(n, nt, prng, x, recv, send); + + // auto p0 = send.silentSend(x, span(z0), prng, chls[0]); + // auto p1 = recv.silentReceive(span(c), span(z1), prng, chls[1]); + + // eval(p0, p1); + // timer.setTimePoint("send"); + // for (u64 i = 0; i < n; ++i) { + // u64 left = c[i] * x; + // u64 right = z1[i] - z0[i]; + // if (left != right) { + // std::cout << "bad " << i << "\n c[i] " << c[i] << " * x " << x << " = " << left << std::endl; + // std::cout << "z0[i] " << z0[i] << " - z1 " << z1[i] << " = " << right << std::endl; + // throw RTE_LOC; + // } + // } + //} - timer.setTimePoint("ot"); -// fakeBase(n, nt, prng, x, recv, send); - - auto p0 = send.silentSend(x, span(z0), prng, chls[0]); - auto p1 = recv.silentReceive(span(c), span(z1), prng, chls[1]); - - eval(p0, p1); - timer.setTimePoint("send"); - for (u64 i = 0; i < n; ++i) { - u64 left = c[i] * x; - u64 right = z1[i] - z0[i]; - if (left != right) { - std::cout << "bad " << i << "\n c[i] " << c[i] << " * x " << x << " = " << left << std::endl; - std::cout << "z0[i] " << z0[i] << " - z1 " << z1[i] << " = " << right << std::endl; - throw RTE_LOC; - } - } - } - - { - PRNG prng(seed); - constexpr size_t N = 10; - using TypeTrait = TypeTraitVec; - using F = TypeTrait::F; - using G = TypeTrait::G; - F x = TypeTrait::fromBlock(prng.get()); - std::vector c(n); - std::vector z0(n), z1(n); - - SilentSubfieldVoleReceiver recv; - SilentSubfieldVoleSender send; - - recv.mMultType = MultType::ExConv7x24; - send.mMultType = MultType::ExConv7x24; - - recv.setTimer(timer); - send.setTimer(timer); - -// recv.mDebug = true; -// send.mDebug = true; - - auto chls = cp::LocalAsyncSocket::makePair(); - - timer.setTimePoint("net"); - - timer.setTimePoint("ot"); -// fakeBase(n, nt, prng, x, recv, send); - - auto p0 = send.silentSend(x, span(z0), prng, chls[0]); - auto p1 = recv.silentReceive(span(c), span(z1), prng, chls[1]); - - eval(p0, p1); -// std::cout << "transferred " << (chls[0].bytesSent() + chls[0].bytesReceived()) << std::endl; - timer.setTimePoint("verify"); - - timer.setTimePoint("send"); - for (u64 i = 0; i < n; i++) { - for (u64 j = 0; j < N; j++) { - G left = c[i] * x[j]; - G right = z1[i][j] - z0[i][j]; - if (left != right) { - std::cout << "bad " << i << "\n c[i] " << c[i] << " * x[j] " << x[j] << " = " << left << std::endl; - std::cout << "z0[i][j] " << z0[i][j] << " - z1 " << z1[i][j] << " = " << right << std::endl; - throw RTE_LOC; + { + PRNG prng(seed); + constexpr size_t N = 10; + using TypeTrait = TypeTraitVec; + using F = TypeTrait::F; + using G = TypeTrait::G; + F x = TypeTrait::fromBlock(prng.get()); + std::vector c(n); + std::vector z0(n), z1(n); + + SilentSubfieldVoleReceiver recv; + SilentSubfieldVoleSender send; + + recv.mMultType = MultType::ExConv7x24; + send.mMultType = MultType::ExConv7x24; + + recv.setTimer(timer); + send.setTimer(timer); + + // recv.mDebug = true; + // send.mDebug = true; + + auto chls = cp::LocalAsyncSocket::makePair(); + + timer.setTimePoint("net"); + + timer.setTimePoint("ot"); + // fakeBase(n, nt, prng, x, recv, send); + + auto p0 = send.silentSend(x, span(z0), prng, chls[0]); + auto p1 = recv.silentReceive(span(c), span(z1), prng, chls[1]); + + eval(p0, p1); + // std::cout << "transferred " << (chls[0].bytesSent() + chls[0].bytesReceived()) << std::endl; + timer.setTimePoint("verify"); + + timer.setTimePoint("send"); + for (u64 i = 0; i < n; i++) { + for (u64 j = 0; j < N; j++) { + G left = c[i] * x[j]; + G right = z1[i][j] - z0[i][j]; + if (left != right) { + std::cout << "bad " << i << "\n c[i] " << c[i] << " * x[j] " << x[j] << " = " << left << std::endl; + std::cout << "z0[i][j] " << z0[i][j] << " - z1 " << z1[i][j] << " = " << right << std::endl; + throw RTE_LOC; + } + } + } } - } - } - } - timer.setTimePoint("done"); -// std::cout << timer << std::endl; + timer.setTimePoint("done"); + // std::cout << timer << std::endl; #else - throw UnitTestSkipped("not defined." LOCATION); + throw UnitTestSkipped("not defined." LOCATION); #endif -} + } } \ No newline at end of file