From f931e50c90db5529b878fb6b2711269c7aa373a0 Mon Sep 17 00:00:00 2001 From: Peter Rindal Date: Mon, 4 Oct 2021 16:25:53 -0700 Subject: [PATCH] removed silver --- .github/workflows/build-test.yml | 267 ++ .gitignore | 11 + .travis.yml | 24 - CMakeLists.txt | 184 +- KyberOT/KyberOT.vcxproj | 276 -- KyberOT/KyberOT.vcxproj.filters | 163 -- KyberOT/Makefile_old | 95 - LICENSE | 29 +- README.md | 262 +- SimplestOT/CMakeLists.txt | 22 - SimplestOT/SimplestOT.vcxproj | 323 --- SimplestOT/SimplestOT.vcxproj.filters | 202 -- build.py | 43 + buildAll.ps1 | 30 - cmake/Config.cmake.in | 33 + cmake/buildOptions.cmake | 138 + cmake/install.cmake | 106 + cmake/libOTeConfig.cmake | 15 + cmake/libOTeConfigVersion.cmake | 3 + cmake/libOTeDepHelper.cmake | 40 + cmake/libOTeFindBuildDir.cmake | 35 + copySourceToLinux.ps1 | 20 - cryptoTools | 2 +- frontend/ExampleBase.h | 77 + frontend/ExampleNChooseOne.h | 235 ++ frontend/ExampleSilent.h | 265 ++ frontend/ExampleTwoChooseOne.h | 217 ++ frontend/benchmark.h | 84 + frontend/frontend.vcxproj | 162 -- frontend/frontend.vcxproj.filters | 33 - frontend/main.cpp | 1156 ++------ frontend/util.cpp | 195 +- frontend/util.h | 152 +- libOTe.sln | 163 -- libOTe/Base/BaseOT.h | 19 +- libOTe/Base/MasnyRindal.cpp | 127 +- libOTe/Base/McRosRoy.h | 195 ++ libOTe/Base/McRosRoyTwist.h | 262 ++ libOTe/Base/SimplestOT.cpp | 109 +- libOTe/Base/SimplestOT.h | 6 +- libOTe/Base/naor-pinkas.cpp | 181 +- libOTe/Base/naor-pinkas.h | 22 +- libOTe/CMakeLists.txt | 33 +- libOTe/NChooseK/AknOtReceiver.cpp | 6 +- libOTe/NChooseK/AknOtSender.cpp | 2 +- libOTe/NChooseOne/Kkrt/KkrtNcoOtReceiver.cpp | 7 +- libOTe/NChooseOne/Kkrt/KkrtNcoOtSender.cpp | 8 +- libOTe/NChooseOne/Oos/OosNcoOtReceiver.cpp | 7 +- libOTe/NChooseOne/Oos/OosNcoOtReceiver.h | 3 +- libOTe/NChooseOne/Oos/OosNcoOtSender.cpp | 8 +- libOTe/NChooseOne/RR17/Rr17NcoOtReceiver.cpp | 4 + libOTe/NChooseOne/RR17/Rr17NcoOtSender.cpp | 5 +- libOTe/Tools/DefaultCurve.h | 32 + libOTe/Tools/LDPC/Mtx.cpp | 1547 +++++++++++ libOTe/Tools/LDPC/Mtx.h | 566 ++++ libOTe/Tools/LDPC/Util.cpp | 396 +++ libOTe/Tools/LDPC/Util.h | 29 + libOTe/Tools/LinearCode.cpp | 2 +- libOTe/Tools/Popf/EKEPopf.h | 71 + libOTe/Tools/Popf/FeistelMulPopf.h | 97 + libOTe/Tools/Popf/FeistelMulRistPopf.h | 102 + libOTe/Tools/Popf/FeistelPopf.h | 104 + libOTe/Tools/Popf/FeistelRistPopf.h | 116 + libOTe/Tools/Popf/MRPopf.h | 81 + libOTe/Tools/SilentPprf.cpp | 718 +++-- libOTe/Tools/SilentPprf.h | 63 +- libOTe/Tools/Tools.cpp | 99 +- libOTe/Tools/Tools.h | 4 + libOTe/Tools/bitpolymul.cpp | 127 +- libOTe/Tools/bitpolymul.h | 41 +- libOTe/Tools/bitpolymul/bc.cpp | 308 --- libOTe/Tools/bitpolymul/bc.h | 46 - libOTe/Tools/bitpolymul/bc_to_gen_code.h | 49 - .../Tools/bitpolymul/bc_to_lch_gen_code.cpp | 485 ---- .../Tools/bitpolymul/bc_to_mono_gen_code.cpp | 484 ---- libOTe/Tools/bitpolymul/bitmat_prod.h | 360 --- libOTe/Tools/bitpolymul/bpmDefines.h | 90 - libOTe/Tools/bitpolymul/btfy.cpp | 1049 -------- libOTe/Tools/bitpolymul/btfy.h | 43 - libOTe/Tools/bitpolymul/encode.cpp | 352 --- libOTe/Tools/bitpolymul/encode.h | 47 - libOTe/Tools/bitpolymul/gf2128_cantor_iso.h | 2351 ----------------- libOTe/Tools/bitpolymul/gf264_cantor_iso.h | 2149 --------------- libOTe/Tools/bitpolymul/gfext_aesni.h | 275 -- libOTe/Tools/bitpolymul/ska.h | 29 - libOTe/Tools/bitpolymul/transpose.h | 402 --- libOTe/Tools/bitpolymul/transpose_bit.h | 50 - libOTe/Tools/bitpolymul/trunc_btfy_tab.h | 1068 -------- libOTe/Tools/bitpolymul/trunc_btfy_tab_64.h | 298 --- libOTe/TwoChooseOne/IknpDotExtReceiver.cpp | 251 -- libOTe/TwoChooseOne/IknpDotExtReceiver.h | 84 - libOTe/TwoChooseOne/IknpDotExtSender.cpp | 217 -- libOTe/TwoChooseOne/IknpDotExtSender.h | 88 - libOTe/TwoChooseOne/IknpOtExtReceiver.cpp | 87 +- libOTe/TwoChooseOne/IknpOtExtReceiver.h | 7 +- libOTe/TwoChooseOne/IknpOtExtSender.cpp | 110 +- libOTe/TwoChooseOne/IknpOtExtSender.h | 4 +- libOTe/TwoChooseOne/KosDotExtReceiver.h | 2 + libOTe/TwoChooseOne/KosDotExtSender.h | 1 + libOTe/TwoChooseOne/KosOtExtReceiver.cpp | 144 +- libOTe/TwoChooseOne/KosOtExtReceiver.h | 16 +- libOTe/TwoChooseOne/KosOtExtSender.cpp | 182 +- libOTe/TwoChooseOne/KosOtExtSender.h | 17 +- libOTe/TwoChooseOne/OTExtInterface.cpp | 28 +- libOTe/TwoChooseOne/OTExtInterface.h | 12 +- libOTe/TwoChooseOne/SilentOtExtReceiver.cpp | 769 +++--- libOTe/TwoChooseOne/SilentOtExtReceiver.h | 334 +-- libOTe/TwoChooseOne/SilentOtExtSender.cpp | 1189 +++++---- libOTe/TwoChooseOne/SilentOtExtSender.h | 182 +- libOTe/TwoChooseOne/TcoOtDefines.h | 5 + libOTe/Vole/NoisyVoleReceiver.cpp | 83 + libOTe/Vole/NoisyVoleReceiver.h | 29 + libOTe/Vole/NoisyVoleSender.cpp | 84 + libOTe/Vole/NoisyVoleSender.h | 31 + libOTe/config.h | 72 - libOTe/config.h.in | 18 +- libOTe/libOTe.vcxproj.filters | 369 --- libOTe/libOTe.vcxproj.vcxproj | 230 -- libOTe/version.h | 4 +- libOTe_Tests/AknOt_Tests.cpp | 4 +- libOTe_Tests/BaseOT_Tests.cpp | 137 +- libOTe_Tests/BaseOT_Tests.h | 11 + libOTe_Tests/CMakeLists.txt | 13 +- libOTe_Tests/NcoOT_Tests.cpp | 16 +- libOTe_Tests/OT_Tests.cpp | 154 +- libOTe_Tests/OT_Tests.h | 2 + libOTe_Tests/SilentOT_Tests.cpp | 648 ++++- libOTe_Tests/SilentOT_Tests.h | 9 +- libOTe_Tests/UnitTests.cpp | 90 +- libOTe_Tests/bitpolymul_Tests.cpp | 34 +- libOTe_Tests/cmakeTests/CMakeLists.txt | 8 + libOTe_Tests/cmakeTests/main.cpp | 12 + libOTe_Tests/libOTe_Tests.vcxproj.filters | 111 - libOTe_Tests/libOTe_Tests.vcxproj.vcxproj | 166 -- libOTe_TestsVS/AknOT_TestsVS.cpp | 37 - libOTe_TestsVS/BaseOT_TestsVS.cpp | 23 - libOTe_TestsVS/OT_TestsVS.cpp | 134 - libOTe_TestsVS/libOTe_TestsVS.filters | 63 - libOTe_TestsVS/libOTe_TestsVS.vcxproj | 144 - libOTe_TestsVS/stdafx.cpp | 8 - libOTe_TestsVS/stdafx.h | 14 - libOTe_TestsVS/targetver.h | 9 - .../KyberOT}/CMakeLists.txt | 13 +- {KyberOT => thirdparty/KyberOT}/KyberOT.c | 0 {KyberOT => thirdparty/KyberOT}/KyberOT.h | 0 .../KyberOT}/PQCgenKAT_kem.c | 0 {KyberOT => thirdparty/KyberOT}/api.h | 0 {KyberOT => thirdparty/KyberOT}/cbd.h | 0 {KyberOT => thirdparty/KyberOT}/cbdeta4.s | 0 {KyberOT => thirdparty/KyberOT}/cbdref.c | 0 {KyberOT => thirdparty/KyberOT}/consts.c | 0 {KyberOT => thirdparty/KyberOT}/cpucycles.c | 0 {KyberOT => thirdparty/KyberOT}/cpucycles.h | 0 {KyberOT => thirdparty/KyberOT}/fips202.c | 0 {KyberOT => thirdparty/KyberOT}/fips202.h | 0 {KyberOT => thirdparty/KyberOT}/fips202x4.c | 0 {KyberOT => thirdparty/KyberOT}/fips202x4.h | 0 {KyberOT => thirdparty/KyberOT}/genmatrix.c | 0 {KyberOT => thirdparty/KyberOT}/genmatrix.h | 0 {KyberOT => thirdparty/KyberOT}/indcpa.c | 0 {KyberOT => thirdparty/KyberOT}/indcpa.h | 0 {KyberOT => thirdparty/KyberOT}/invntt.s | 0 .../keccak4x/KeccakP-1600-times4-SIMD256.c | 0 .../keccak4x/KeccakP-1600-times4-SIMD256.o | Bin .../keccak4x/KeccakP-1600-times4-SnP.h | 0 .../keccak4x/KeccakP-1600-unrolling.macros | 0 .../KyberOT}/keccak4x/SIMD256-config.h | 0 .../KyberOT}/keccak4x/align.h | 0 .../KyberOT}/keccak4x/brg_endian.h | 0 {KyberOT => thirdparty/KyberOT}/kem.c | 0 {KyberOT => thirdparty/KyberOT}/kex.c | 0 {KyberOT => thirdparty/KyberOT}/kex.h | 0 {KyberOT => thirdparty/KyberOT}/ntt.h | 0 {KyberOT => thirdparty/KyberOT}/ntt.s | 0 {KyberOT => thirdparty/KyberOT}/params.h | 0 {KyberOT => thirdparty/KyberOT}/poly.c | 0 {KyberOT => thirdparty/KyberOT}/poly.h | 0 {KyberOT => thirdparty/KyberOT}/polyvec.c | 0 {KyberOT => thirdparty/KyberOT}/polyvec.h | 0 .../KyberOT}/polyvec_pointwise_acc.s | 0 {KyberOT => thirdparty/KyberOT}/precomp.c | 0 {KyberOT => thirdparty/KyberOT}/randombytes.c | 0 {KyberOT => thirdparty/KyberOT}/randombytes.h | 0 {KyberOT => thirdparty/KyberOT}/reduce.c | 0 {KyberOT => thirdparty/KyberOT}/reduce.h | 0 {KyberOT => thirdparty/KyberOT}/rng.c | 0 {KyberOT => thirdparty/KyberOT}/rng.h | 0 {KyberOT => thirdparty/KyberOT}/speed.c | 0 {KyberOT => thirdparty/KyberOT}/test_kex.c | 0 {KyberOT => thirdparty/KyberOT}/test_kyber.c | 0 {KyberOT => thirdparty/KyberOT}/testvectors.c | 0 {KyberOT => thirdparty/KyberOT}/verify.c | 0 {KyberOT => thirdparty/KyberOT}/verify.h | 0 thirdparty/SimplestOT/CMakeLists.txt | 34 + .../SimplestOT}/Keccak-simple-settings.h | 0 .../SimplestOT}/Keccak-simple.c | 0 {SimplestOT => thirdparty/SimplestOT}/LICENSE | 0 .../SimplestOT}/consts.s | 0 .../SimplestOT}/consts4x.s | 0 .../SimplestOT}/cpucycles.c | 0 .../SimplestOT}/cpucycles.h | 0 .../SimplestOT}/crypto_hash.h | 0 .../SimplestOT}/fe25519.h | 0 .../SimplestOT}/fe25519_add.c | 0 .../SimplestOT}/fe25519_freeze.s | 0 .../SimplestOT}/fe25519_getparity.c | 0 .../SimplestOT}/fe25519_invert.c | 0 .../SimplestOT}/fe25519_iseq_vartime.c | 0 .../SimplestOT}/fe25519_mul.s | 0 .../SimplestOT}/fe25519_neg.c | 0 .../SimplestOT}/fe25519_nsquare.s | 0 .../SimplestOT}/fe25519_pack.c | 0 .../SimplestOT}/fe25519_pow2523.c | 0 .../SimplestOT}/fe25519_setint.c | 0 .../SimplestOT}/fe25519_square.s | 0 .../SimplestOT}/fe25519_sub.c | 0 .../SimplestOT}/fe25519_unpack.c | 0 .../SimplestOT}/ge25519.data | 0 .../SimplestOT}/ge25519.h | 0 .../SimplestOT}/ge25519_add.c | 0 .../SimplestOT}/ge25519_add_p1p1.s | 0 .../SimplestOT}/ge25519_dbl_p1p1.s | 0 .../SimplestOT}/ge25519_double.c | 0 .../SimplestOT}/ge25519_lookup.s | 0 .../SimplestOT}/ge25519_lookup_niels.s | 0 .../SimplestOT}/ge25519_nielsadd2.s | 0 .../SimplestOT}/ge25519_p1p1_to_p2.s | 0 .../SimplestOT}/ge25519_p1p1_to_p3.s | 0 .../SimplestOT}/ge25519_pack.c | 0 .../SimplestOT}/ge25519_scalarmult.c | 0 .../SimplestOT}/ge25519_scalarmult_base.c | 0 .../SimplestOT}/ge25519_setneutral.c | 0 .../SimplestOT}/ge25519_unpack.c | 0 {SimplestOT => thirdparty/SimplestOT}/ge4x.c | 0 .../SimplestOT}/ge4x.data | 0 {SimplestOT => thirdparty/SimplestOT}/ge4x.h | 0 .../SimplestOT}/ge4x_add_p1p1.s | 0 .../SimplestOT}/ge4x_double_p1p1.s | 0 .../SimplestOT}/ge4x_lookup.s | 0 .../SimplestOT}/ge4x_lookup_niels.s | 0 .../SimplestOT}/ge4x_niels_add_p1p1.s | 0 .../SimplestOT}/ge4x_pack.c | 0 .../SimplestOT}/ge4x_unpack_vartime.c | 0 {SimplestOT => thirdparty/SimplestOT}/gfe4x.c | 0 {SimplestOT => thirdparty/SimplestOT}/gfe4x.h | 0 .../SimplestOT}/gfe4x_add.s | 0 .../SimplestOT}/gfe4x_getparity.c | 0 .../SimplestOT}/gfe4x_iseq_vartime.c | 0 .../SimplestOT}/gfe4x_mul.s | 0 .../SimplestOT}/gfe4x_nsquare.c | 0 .../SimplestOT}/gfe4x_pow2523.c | 0 .../SimplestOT}/gfe4x_square.s | 0 .../SimplestOT}/gfe4x_sub.s | 0 .../SimplestOT}/network.c | 0 .../SimplestOT}/network.h | 0 .../SimplestOT}/ot_config.h | 0 .../SimplestOT}/ot_receiver.c | 0 .../SimplestOT}/ot_receiver.h | 0 .../SimplestOT}/ot_receiver_test.c | 0 .../SimplestOT}/ot_sender.c | 0 .../SimplestOT}/ot_sender.h | 0 .../SimplestOT}/ot_sender_test.c | 0 .../SimplestOT}/randombytes.c | 0 .../SimplestOT}/randombytes.h | 0 .../SimplestOT}/sc25519.h | 0 .../SimplestOT}/sc25519_from32bytes.c | 0 .../SimplestOT}/sc25519_random.c | 0 .../SimplestOT}/sc25519_window4.c | 0 {SimplestOT => thirdparty/SimplestOT}/to_4x.h | 0 thirdparty/getBitpolymul.py | 71 + title.PNG | Bin 66494 -> 0 bytes 271 files changed, 9722 insertions(+), 17088 deletions(-) create mode 100644 .github/workflows/build-test.yml delete mode 100644 .travis.yml delete mode 100644 KyberOT/KyberOT.vcxproj delete mode 100644 KyberOT/KyberOT.vcxproj.filters delete mode 100644 KyberOT/Makefile_old delete mode 100644 SimplestOT/CMakeLists.txt delete mode 100644 SimplestOT/SimplestOT.vcxproj delete mode 100644 SimplestOT/SimplestOT.vcxproj.filters create mode 100644 build.py delete mode 100644 buildAll.ps1 create mode 100644 cmake/Config.cmake.in create mode 100644 cmake/buildOptions.cmake create mode 100644 cmake/install.cmake create mode 100644 cmake/libOTeConfig.cmake create mode 100644 cmake/libOTeConfigVersion.cmake create mode 100644 cmake/libOTeDepHelper.cmake create mode 100644 cmake/libOTeFindBuildDir.cmake delete mode 100644 copySourceToLinux.ps1 create mode 100644 frontend/ExampleBase.h create mode 100644 frontend/ExampleNChooseOne.h create mode 100644 frontend/ExampleSilent.h create mode 100644 frontend/ExampleTwoChooseOne.h create mode 100644 frontend/benchmark.h delete mode 100644 frontend/frontend.vcxproj delete mode 100644 frontend/frontend.vcxproj.filters delete mode 100644 libOTe.sln create mode 100644 libOTe/Base/McRosRoy.h create mode 100644 libOTe/Base/McRosRoyTwist.h create mode 100644 libOTe/Tools/DefaultCurve.h create mode 100644 libOTe/Tools/LDPC/Mtx.cpp create mode 100644 libOTe/Tools/LDPC/Mtx.h create mode 100644 libOTe/Tools/LDPC/Util.cpp create mode 100644 libOTe/Tools/LDPC/Util.h create mode 100644 libOTe/Tools/Popf/EKEPopf.h create mode 100644 libOTe/Tools/Popf/FeistelMulPopf.h create mode 100644 libOTe/Tools/Popf/FeistelMulRistPopf.h create mode 100644 libOTe/Tools/Popf/FeistelPopf.h create mode 100644 libOTe/Tools/Popf/FeistelRistPopf.h create mode 100644 libOTe/Tools/Popf/MRPopf.h delete mode 100644 libOTe/Tools/bitpolymul/bc.cpp delete mode 100644 libOTe/Tools/bitpolymul/bc.h delete mode 100644 libOTe/Tools/bitpolymul/bc_to_gen_code.h delete mode 100644 libOTe/Tools/bitpolymul/bc_to_lch_gen_code.cpp delete mode 100644 libOTe/Tools/bitpolymul/bc_to_mono_gen_code.cpp delete mode 100644 libOTe/Tools/bitpolymul/bitmat_prod.h delete mode 100644 libOTe/Tools/bitpolymul/bpmDefines.h delete mode 100644 libOTe/Tools/bitpolymul/btfy.cpp delete mode 100644 libOTe/Tools/bitpolymul/btfy.h delete mode 100644 libOTe/Tools/bitpolymul/encode.cpp delete mode 100644 libOTe/Tools/bitpolymul/encode.h delete mode 100644 libOTe/Tools/bitpolymul/gf2128_cantor_iso.h delete mode 100644 libOTe/Tools/bitpolymul/gf264_cantor_iso.h delete mode 100644 libOTe/Tools/bitpolymul/gfext_aesni.h delete mode 100644 libOTe/Tools/bitpolymul/ska.h delete mode 100644 libOTe/Tools/bitpolymul/transpose.h delete mode 100644 libOTe/Tools/bitpolymul/transpose_bit.h delete mode 100644 libOTe/Tools/bitpolymul/trunc_btfy_tab.h delete mode 100644 libOTe/Tools/bitpolymul/trunc_btfy_tab_64.h delete mode 100644 libOTe/TwoChooseOne/IknpDotExtReceiver.cpp delete mode 100644 libOTe/TwoChooseOne/IknpDotExtReceiver.h delete mode 100644 libOTe/TwoChooseOne/IknpDotExtSender.cpp delete mode 100644 libOTe/TwoChooseOne/IknpDotExtSender.h create mode 100644 libOTe/Vole/NoisyVoleReceiver.cpp create mode 100644 libOTe/Vole/NoisyVoleReceiver.h create mode 100644 libOTe/Vole/NoisyVoleSender.cpp create mode 100644 libOTe/Vole/NoisyVoleSender.h delete mode 100644 libOTe/config.h delete mode 100644 libOTe/libOTe.vcxproj.filters delete mode 100644 libOTe/libOTe.vcxproj.vcxproj create mode 100644 libOTe_Tests/cmakeTests/CMakeLists.txt create mode 100644 libOTe_Tests/cmakeTests/main.cpp delete mode 100644 libOTe_Tests/libOTe_Tests.vcxproj.filters delete mode 100644 libOTe_Tests/libOTe_Tests.vcxproj.vcxproj delete mode 100644 libOTe_TestsVS/AknOT_TestsVS.cpp delete mode 100644 libOTe_TestsVS/BaseOT_TestsVS.cpp delete mode 100644 libOTe_TestsVS/OT_TestsVS.cpp delete mode 100644 libOTe_TestsVS/libOTe_TestsVS.filters delete mode 100644 libOTe_TestsVS/libOTe_TestsVS.vcxproj delete mode 100644 libOTe_TestsVS/stdafx.cpp delete mode 100644 libOTe_TestsVS/stdafx.h delete mode 100644 libOTe_TestsVS/targetver.h rename {KyberOT => thirdparty/KyberOT}/CMakeLists.txt (51%) rename {KyberOT => thirdparty/KyberOT}/KyberOT.c (100%) rename {KyberOT => thirdparty/KyberOT}/KyberOT.h (100%) rename {KyberOT => thirdparty/KyberOT}/PQCgenKAT_kem.c (100%) rename {KyberOT => thirdparty/KyberOT}/api.h (100%) rename {KyberOT => thirdparty/KyberOT}/cbd.h (100%) rename {KyberOT => thirdparty/KyberOT}/cbdeta4.s (100%) rename {KyberOT => thirdparty/KyberOT}/cbdref.c (100%) rename {KyberOT => thirdparty/KyberOT}/consts.c (100%) rename {KyberOT => thirdparty/KyberOT}/cpucycles.c (100%) rename {KyberOT => thirdparty/KyberOT}/cpucycles.h (100%) rename {KyberOT => thirdparty/KyberOT}/fips202.c (100%) rename {KyberOT => thirdparty/KyberOT}/fips202.h (100%) rename {KyberOT => thirdparty/KyberOT}/fips202x4.c (100%) rename {KyberOT => thirdparty/KyberOT}/fips202x4.h (100%) rename {KyberOT => thirdparty/KyberOT}/genmatrix.c (100%) rename {KyberOT => thirdparty/KyberOT}/genmatrix.h (100%) rename {KyberOT => thirdparty/KyberOT}/indcpa.c (100%) rename {KyberOT => thirdparty/KyberOT}/indcpa.h (100%) rename {KyberOT => thirdparty/KyberOT}/invntt.s (100%) rename {KyberOT => thirdparty/KyberOT}/keccak4x/KeccakP-1600-times4-SIMD256.c (100%) rename {KyberOT => thirdparty/KyberOT}/keccak4x/KeccakP-1600-times4-SIMD256.o (100%) rename {KyberOT => thirdparty/KyberOT}/keccak4x/KeccakP-1600-times4-SnP.h (100%) rename {KyberOT => thirdparty/KyberOT}/keccak4x/KeccakP-1600-unrolling.macros (100%) rename {KyberOT => thirdparty/KyberOT}/keccak4x/SIMD256-config.h (100%) rename {KyberOT => thirdparty/KyberOT}/keccak4x/align.h (100%) rename {KyberOT => thirdparty/KyberOT}/keccak4x/brg_endian.h (100%) rename {KyberOT => thirdparty/KyberOT}/kem.c (100%) rename {KyberOT => thirdparty/KyberOT}/kex.c (100%) rename {KyberOT => thirdparty/KyberOT}/kex.h (100%) rename {KyberOT => thirdparty/KyberOT}/ntt.h (100%) rename {KyberOT => thirdparty/KyberOT}/ntt.s (100%) rename {KyberOT => thirdparty/KyberOT}/params.h (100%) rename {KyberOT => thirdparty/KyberOT}/poly.c (100%) rename {KyberOT => thirdparty/KyberOT}/poly.h (100%) rename {KyberOT => thirdparty/KyberOT}/polyvec.c (100%) rename {KyberOT => thirdparty/KyberOT}/polyvec.h (100%) rename {KyberOT => thirdparty/KyberOT}/polyvec_pointwise_acc.s (100%) rename {KyberOT => thirdparty/KyberOT}/precomp.c (100%) rename {KyberOT => thirdparty/KyberOT}/randombytes.c (100%) rename {KyberOT => thirdparty/KyberOT}/randombytes.h (100%) rename {KyberOT => thirdparty/KyberOT}/reduce.c (100%) rename {KyberOT => thirdparty/KyberOT}/reduce.h (100%) rename {KyberOT => thirdparty/KyberOT}/rng.c (100%) rename {KyberOT => thirdparty/KyberOT}/rng.h (100%) rename {KyberOT => thirdparty/KyberOT}/speed.c (100%) rename {KyberOT => thirdparty/KyberOT}/test_kex.c (100%) rename {KyberOT => thirdparty/KyberOT}/test_kyber.c (100%) rename {KyberOT => thirdparty/KyberOT}/testvectors.c (100%) rename {KyberOT => thirdparty/KyberOT}/verify.c (100%) rename {KyberOT => thirdparty/KyberOT}/verify.h (100%) create mode 100644 thirdparty/SimplestOT/CMakeLists.txt rename {SimplestOT => thirdparty/SimplestOT}/Keccak-simple-settings.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/Keccak-simple.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/LICENSE (100%) rename {SimplestOT => thirdparty/SimplestOT}/consts.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/consts4x.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/cpucycles.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/cpucycles.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/crypto_hash.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_add.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_freeze.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_getparity.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_invert.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_iseq_vartime.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_mul.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_neg.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_nsquare.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_pack.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_pow2523.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_setint.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_square.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_sub.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/fe25519_unpack.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519.data (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_add.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_add_p1p1.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_dbl_p1p1.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_double.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_lookup.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_lookup_niels.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_nielsadd2.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_p1p1_to_p2.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_p1p1_to_p3.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_pack.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_scalarmult.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_scalarmult_base.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_setneutral.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge25519_unpack.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge4x.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge4x.data (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge4x.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge4x_add_p1p1.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge4x_double_p1p1.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge4x_lookup.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge4x_lookup_niels.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge4x_niels_add_p1p1.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge4x_pack.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ge4x_unpack_vartime.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/gfe4x.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/gfe4x.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/gfe4x_add.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/gfe4x_getparity.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/gfe4x_iseq_vartime.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/gfe4x_mul.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/gfe4x_nsquare.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/gfe4x_pow2523.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/gfe4x_square.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/gfe4x_sub.s (100%) rename {SimplestOT => thirdparty/SimplestOT}/network.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/network.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/ot_config.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/ot_receiver.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ot_receiver.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/ot_receiver_test.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ot_sender.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/ot_sender.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/ot_sender_test.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/randombytes.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/randombytes.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/sc25519.h (100%) rename {SimplestOT => thirdparty/SimplestOT}/sc25519_from32bytes.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/sc25519_random.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/sc25519_window4.c (100%) rename {SimplestOT => thirdparty/SimplestOT}/to_4x.h (100%) create mode 100644 thirdparty/getBitpolymul.py delete mode 100644 title.PNG diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml new file mode 100644 index 00000000..954184ce --- /dev/null +++ b/.github/workflows/build-test.yml @@ -0,0 +1,267 @@ +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the master branch + push: + branches: [ master, ci ] + pull_request: {} + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build-ubuntu: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + with: + submodules: recursive + + # Runs a set of commands using the runners shell + - name: build boost + run: python3 build.py --setup --boost --par=4 + + - name: build relic + run: python3 build.py --setup --relic --par=4 + + - name: build bitpolymul + run: python3 build.py --setup --bitpolymul --par=4 + + - name: build libOTe + run: python3 build.py --par=4 -- -D ENABLE_ALL_OT=ON -D ENABLE_RELIC=ON -DENABLE_CIRCUIT=ON + + - name: unit tests + run: ./out/build/linux/frontend/frontend_libOTe -u + + + - name: find source tree + run: | + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -DCMAKE_BUILD_TYPE=Release -D CMAKE_PREFIX_PATH=../../ + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + - name: hint test + run: | + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -D LIBOTE_HINT=../.. + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + - name: install prefix test + run: | + python3 build.py --setup --boost --relic --bitpolymul --install=~/install + python3 build.py --install=~/install + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=~/install + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + + - name: install test + run: | + python3 build.py --setup --boost --relic --bitpolymul --install --sudo + python3 build.py --install --sudo + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -DCMAKE_BUILD_TYPE=Release + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + - name: build sodium + run: python3 build.py --setup --sodium --par=4 + + - name: build libOTe + run: python3 build.py --par=4 -- -D ENABLE_ALL_OT=ON -D ENABLE_SODIUM=ON -DENABLE_RELIC=OFF + + - name: unit tests + run: ./out/build/linux/frontend/frontend_libOTe -u + + + - name: find source tree + run: | + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -DCMAKE_BUILD_TYPE=Release -D CMAKE_PREFIX_PATH=../../ + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + - name: hint test + run: | + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -D LIBOTE_HINT=../.. + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + - name: install prefix test + run: | + python3 build.py --setup --boost --relic --sodium --install=~/install + python3 build.py --install=~/install + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=~/install + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + + - name: install test + run: | + python3 build.py --setup --boost --sodium --install --sudo + python3 build.py --install --sudo + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -DCMAKE_BUILD_TYPE=Release + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + # This workflow contains a single job called "build" + build-osx: + # The type of runner that the job will run on + runs-on: macos-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + with: + submodules: recursive + + # Runs a set of commands using the runners shell + - name: build boost + run: python3 build.py --setup --boost --par=4 + + - name: build relic + run: python3 build.py --setup --relic --par=4 + + - name: build libOTe + run: | + python3 build.py --par=4 -- -D ENABLE_ALL_OT=ON -D ENABLE_RELIC=ON -D ENABLE_SSE=OFF + python3 build.py --par=4 -- -D ENABLE_SILENTOT=OFF + + - name: unit tests + run: ./out/build/linux/frontend/frontend_libOTe -u + + + - name: find source tree + run: | + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -DCMAKE_BUILD_TYPE=Release -D CMAKE_PREFIX_PATH=../../ + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + - name: hint test + run: | + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -D LIBOTE_HINT=../.. + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + - name: install prefix test + run: | + python3 build.py --setup --boost --relic --install=~/install + python3 build.py --install=~/install + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=~/install + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + + - name: install test + run: | + python3 build.py --setup --boost --relic --install --sudo + python3 build.py --install --sudo + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -DCMAKE_BUILD_TYPE=Release + cmake --build out/ + ./out/main + rm -rf out/ + cd ../.. + + + build-windows: + # The type of runner that the job will run on + runs-on: windows-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + with: + submodules: recursive + - uses: seanmiddleditch/gha-setup-ninja@v3 + - uses: ilammy/msvc-dev-cmd@v1 + + # Runs a set of commands using the runners shell + - name: build boost + run: python3 build.py --setup --boost --par=4 + + - name: build relic + run: python3 build.py --setup --relic --par=4 + + - name: build bitpolymul + run: python3 build.py --setup --bitpolymul --par=4 + + - name: build libOTe + run: python3 build.py --par=4 -- -D ENABLE_ALL_OT=ON -D ENABLE_RELIC=ON -G Ninja + + + - name: unit test + run: ./out/build/x64-Release/frontend/frontend_libOTe.exe -u + + - name: find source tree + run: | + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -DCMAKE_BUILD_TYPE=Release -D CMAKE_PREFIX_PATH=../../ + cmake --build out/ --config Release + ./out/Release/main.exe + rm -r -fo out/ + cd ../.. + + - name: hint test + run: | + python3 build.py --setup + python3 build.py + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -D LIBOTE_HINT=../.. + cmake --build out/ --config Release + ./out/Release/main.exe + rm -r -fo out/ + cd ../.. + + - name: install prefix test + run: | + python3 build.py --setup --relic --boost --install=~/install + python3 build.py --install=~/install + cd libOTe_Tests/cmakeTests + cmake -S . -B out/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=~/install + cmake --build out/ --config Release + ./out/Release/main.exe + rm -r -fo out/ + cd ../.. \ No newline at end of file diff --git a/.gitignore b/.gitignore index d751fab0..0ee0796c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ *.user *.sln.docstates *.vs +.vscode/ CMakeFiles/* */CMakeFiles/* @@ -13,9 +14,18 @@ CMakeFiles/* CMakeCache.txt */CMakeCache.txt +CMakeSettings.json *.a *.args.json +libOTe/config.h +frontend/frontend_libOTe + +.DS_Store +*/.DS_Store + +lib/ +CMakeSettings.json # Build results [Dd]ebug/ @@ -26,6 +36,7 @@ build/ bld/ [Bb]in/ [Oo]bj/ +out/ # Roslyn cache directories *.ide/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 34c1b787..00000000 --- a/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -dist: trusty -sudo: false -language: cpp - -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-6 - - g++-6 - - cmake - -script: - #- export CXX=/usr/local/clang-5.0.0/bin/clang - #- export CC=/usr/local/clang-5.0.0/bin/clang - - export CXX=/usr/bin/g++-6 - - export CC=/usr/bin/gcc-6 - - ls - - cd cryptoTools/thirdparty/linux - - bash all.get - - cd ../../.. - - cmake . - - cmake --build . -- -j2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b10b56e..a7f0d9b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,10 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.15) +if (POLICY CMP0048) + cmake_policy(SET CMP0048 NEW) +endif (POLICY CMP0048) -project(libOTe) +project(libOTe VERSION 1.5.1) if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") @@ -9,37 +12,37 @@ if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") ############################################ # If top level cmake # ############################################ - if(${CMAKE_VERSION} VERSION_LESS "3.12.0") - message("Please consider updating CMake to 3.12+") - endif() - - set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin) - set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib) - set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib) - + ############################################ # Flag and #defines # ############################################ add_definitions(-DSOLUTION_DIR='${CMAKE_SOURCE_DIR}') - set(COMMON_FLAGS "-Wall -march=native -Wfatal-errors ") + if(MSVC) + + # optionally add the following to CMAKE_PREFIX_PATH + if(NOT DEFINED CMAKE_PREFIX_PATH AND NOT DEFINED NO_OC_DEFAULT_PREFIX) + set(CMAKE_PREFIX_PATH + "c:/libs" + "${CMAKE_CURRENT_LIST_DIR}/..;" + ) + endif() + + else() + set(COMMON_FLAGS "-Wall -march=native -Wfatal-errors") + SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO " -O2 -g -ggdb") + SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -ggdb") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") + endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS}") - # -Wno-ignored-attributes -Wno-parentheses - # -maes -msse2 -msse3 -msse4.1 -mpclmul - # -std=c++14 - # -fPIC -no-pie - - # Select flags. - SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO " -O2 -g -ggdb -rdynamic") - SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -ggdb -rdynamic") - ############################################ # Build mode checks # ############################################ - + # Set a default build type for single-configuration # CMake generators if no build type is set. if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) @@ -47,141 +50,44 @@ if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") endif() if( NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release" - AND NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" + AND NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" AND NOT "${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo" ) - - message(FATAL_ERROR ": Unknown build type - \${CMAKE_BUILD_TYPE}=${CMAKE_BUILD_TYPE}. Please use one of Debug, Release, or RelWithDebInfo. e.g. call\n\tcmake . -DCMAKE_BUILD_TYPE=Release\n" ) + + message(WARNING ": Unknown build type - \${CMAKE_BUILD_TYPE}=${CMAKE_BUILD_TYPE}. Please use one of Debug, Release, or RelWithDebInfo. e.g. call\n\tcmake . -DCMAKE_BUILD_TYPE=Release\n" ) endif() + + endif() - - + + ############################################# # Build cryptoTools (common utilities) # ############################################# add_subdirectory(cryptoTools) - + ############################################# # CONFIGURE # ############################################# +include(cmake/buildOptions.cmake) +include(cmake/libOTeDepHelper.cmake) -if(DEFINED ENABLE_ALL_OT) - set(ENABLE_SIMPLESTOT ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_SIMPLESTOT_ASM ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_MR ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_MR_KYBER ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_NP ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_KOS ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_IKNP ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_SILENTOT ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_DELTA_KOS ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_DELTA_IKNP ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_OOS ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_KKRT ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_RR ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - set(ENABLE_AKN ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) - unset(ENABLE_ALL_OT CACHE) -endif() - -option(ENABLE_SIMPLESTOT "Build the SimplestOT base OT" OFF) -option(ENABLE_SIMPLESTOT_ASM "Build the assembly based SimplestOT library" OFF) -option(ENABLE_MR "Build the MasnyRindal base OT" OFF) -option(ENABLE_MR_KYBER "Build the Kyber (LWE based) library and MR-Kyber base OT" OFF) -option(ENABLE_NP "Build the NaorPinkas base OT" OFF) - -option(ENABLE_KOS "Build the KOS OT-Ext protocol." OFF) -option(ENABLE_IKNP "Build the IKNP OT-Ext protocol." OFF) -option(ENABLE_SILENTOT "Build the Slient OT protocol." OFF) -option(ENABLE_DELTA_KOS "Build the KOS Delta-OT-Ext protocol." OFF) -option(ENABLE_DELTA_IKNP "Build the IKNP Delta-OT-Ext protocol." OFF) - -option(ENABLE_OOS "Build the OOS 1-oo-N OT-Ext protocol." OFF) -option(ENABLE_KKRT "Build the KKRT 1-oo-N OT-Ext protocol." OFF) -option(ENABLE_RR "Build the RR 1-oo-N OT-Ext protocol." OFF) - -option(ENABLE_AKN "Build the RR ~k-oo-N OT-Ext protocol." OFF) - -option(OTE_KOS_FIAT_SHAMIR "Build the library withing Fiat Shamir for KOS" OFF) - -set(OTE_KOS_HASH "OTE_DAVIE_MEYER_AES" CACHE STRING "Hashing technique for KOS") -set_property(CACHE OTE_KOS_HASH PROPERTY STRINGS OTE_RANDOM_ORACLE OTE_DAVIE_MEYER_AES) - -message(STATUS "General Options\n=======================================================") -message(STATUS "Option: ENABLE_ALL_OT = ON/OFF\n\n") - -message(STATUS "Base OT protocols\n=======================================================") -message(STATUS "Option: ENABLE_SIMPLESTOT = ${ENABLE_SIMPLESTOT}") -message(STATUS "Option: ENABLE_SIMPLESTOT_ASM = ${ENABLE_SIMPLESTOT_ASM}") -message(STATUS "Option: ENABLE_MR = ${ENABLE_MR}") -message(STATUS "Option: ENABLE_MR_KYBER = ${ENABLE_MR_KYBER}") -message(STATUS "Option: ENABLE_NP = ${ENABLE_NP}\n\n") - -message(STATUS "1-out-of-2 OT Extension protocols\n=======================================================") -message(STATUS "Option: ENABLE_KOS = ${ENABLE_KOS}") -message(STATUS "Option: ENABLE_IKNP = ${ENABLE_IKNP}") -message(STATUS "Option: ENABLE_SILENTOT = ${ENABLE_SILENTOT}\n\n") - -message(STATUS "1-out-of-2 Delta-OT Extension protocols\n=======================================================") -message(STATUS "Option: ENABLE_DELTA_KOS = ${ENABLE_DELTA_KOS}") -message(STATUS "Option: ENABLE_DELTA_IKNP = ${ENABLE_DELTA_IKNP}\n\n") - -message(STATUS "1-out-of-N OT Extension protocols\n=======================================================") -message(STATUS "Option: ENABLE_OOS = ${ENABLE_OOS}") -message(STATUS "Option: ENABLE_KKRT = ${ENABLE_KKRT}") -message(STATUS "Option: ENABLE_RR = ${ENABLE_RR}\n\n") - -message(STATUS "Other libOTe options\n=======================================================") -message(STATUS "Option: OTE_KOS_HASH = ${OTE_KOS_HASH}") -message(STATUS " OTE_RANDOM_ORACLE use the random oracle (slower)") -message(STATUS " OTE_DAVIE_MEYER_AES use AES in the Davie Meyer compression function\n") -message(STATUS "Option: OTE_KOS_FIAT_SHAMIR = ${OTE_KOS_FIAT_SHAMIR}\n\n") +file(REMOVE ${CMAKE_CURRENT_LIST_DIR}/libOTe/config.h) +configure_file(libOTe/config.h.in libOTe/config.h) ############################################# -# Config Checks # +# Build libOTe # ############################################# -if( NOT ENABLE_ALL_OT AND - NOT ENABLE_SIMPLESTOT AND - NOT ENABLE_SIMPLESTOT_ASM AND - NOT ENABLE_MR AND - NOT ENABLE_MR_KYBER AND - NOT ENABLE_NP) - message(WARNING "NO Base OT enabled.") +if(ENABLE_SIMPLESTOT_ASM AND (NOT MSVC)) + add_subdirectory(thirdparty/SimplestOT) endif() -if ((ENABLE_ALL_OT OR ENABLE_MR) AND NOT (ENABLE_MIRACL OR ENABLE_RELIC)) - message(FATAL_ERROR "ENABLE_ALL_OT and ENABLE_MR requires ENABLE_MIRACL or ENABLE_RELIC") +if(ENABLE_MR_KYBER AND (NOT MSVC)) + add_subdirectory(thirdparty/KyberOT) endif() -if ((ENABLE_SIMPLESTOT OR ENABLE_MR OR ENABLE_NP) AND - NOT (ENABLE_MIRACL OR ENABLE_RELIC)) - message(FATAL_ERROR "ENABLE_SIMPLESTOT and ENABLE_MR requires ENABLE_MIRACL or ENABLE_RELIC") -endif() - -if(ENABLE_SSE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} $ -maes -msse2 -msse3 -msse4.1 -mpclmul ") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -msse2 -msse3 -msse4.1 -mpclmul ") -endif() - - -configure_file(libOTe/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/libOTe/config.h) -# Support out-of-source builds. -# include_directories(${CMAKE_BINARY_DIR}) - - -############################################# -# Build libOTe # -############################################# - -if(ENABLE_SIMPLESTOT_ASM) - add_subdirectory(SimplestOT) -endif(ENABLE_SIMPLESTOT_ASM) - -if(ENABLE_MR_KYBER) - add_subdirectory(KyberOT) -endif(ENABLE_MR_KYBER) - add_subdirectory(libOTe) add_subdirectory(libOTe_Tests) @@ -191,3 +97,9 @@ add_subdirectory(libOTe_Tests) add_subdirectory(frontend) + +############################################# +# install # +############################################# + +include("${CMAKE_CURRENT_LIST_DIR}/cmake/install.cmake") diff --git a/KyberOT/KyberOT.vcxproj b/KyberOT/KyberOT.vcxproj deleted file mode 100644 index 3d25968e..00000000 --- a/KyberOT/KyberOT.vcxproj +++ /dev/null @@ -1,276 +0,0 @@ - - - - - Debug_DLLRT - Win32 - - - Debug_DLLRT - x64 - - - Debug - Win32 - - - Release_DLLRT - Win32 - - - Release_DLLRT - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {CE639ABE-6913-428A-92B0-7C5A6458B983} - KyberOT - 10.0 - - - - Application - true - v142 - MultiByte - - - Application - true - v142 - MultiByte - - - Application - false - v142 - true - MultiByte - - - Application - false - v142 - true - MultiByte - - - Application - true - v142 - MultiByte - - - Application - true - v142 - MultiByte - - - Application - false - v142 - true - MultiByte - - - Application - false - v142 - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Level3 - MaxSpeed - true - true - true - true - - - true - true - - - - - Level3 - MaxSpeed - true - true - true - true - - - true - true - - - - - Level3 - Disabled - true - true - - - - - Level3 - Disabled - true - true - - - - - Level3 - Disabled - true - true - - - - - Level3 - Disabled - true - true - - - - - Level3 - MaxSpeed - true - true - true - true - - - true - true - - - - - Level3 - MaxSpeed - true - true - true - true - - - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/KyberOT/KyberOT.vcxproj.filters b/KyberOT/KyberOT.vcxproj.filters deleted file mode 100644 index 6195a4a3..00000000 --- a/KyberOT/KyberOT.vcxproj.filters +++ /dev/null @@ -1,163 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - - - - - - - - - \ No newline at end of file diff --git a/KyberOT/Makefile_old b/KyberOT/Makefile_old deleted file mode 100644 index 3744276f..00000000 --- a/KyberOT/Makefile_old +++ /dev/null @@ -1,95 +0,0 @@ -CC = /usr/bin/cc -CFLAGS = -g -Wall -Wextra -O3 -fomit-frame-pointer -march=native -fPIC -NISTFLAGS = -O3 -fomit-frame-pointer -march=native -fPIC -RM = /bin/rm - -all: test_kyber512 \ - test_kyber768 \ - test_kyber1024 \ - test_kex512 \ - test_kex768 \ - test_kex1024 \ - testvectors512 \ - testvectors768 \ - testvectors1024 \ - speed512 \ - speed768 \ - speed1024 \ - PQCgenKAT_kem \ - main - - -SOURCES = kem.c poly.c polyvec.c polyvec_pointwise_acc.s fips202.c reduce.c cbdeta4.s cbdref.c precomp.c verify.c indcpa.c kex.c consts.c genmatrix.c fips202x4.c \ - keccak4x/KeccakP-1600-times4-SIMD256.o \ - ntt.s invntt.s -HEADERS = params.h poly.h polyvec.h reduce.h cbd.h ntt.h verify.h indcpa.h kex.h genmatrix.h fips202x4.h - -main: $(SOURCES) $(HEADERS) main.c randombytes.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=2 $(SOURCES) randombytes.c main.c -o main - -test_kyber512: $(SOURCES) $(HEADERS) test_kyber.c randombytes.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=2 $(SOURCES) randombytes.c test_kyber.c -o test_kyber512 - -test_kyber768: $(SOURCES) $(HEADERS) test_kyber.c randombytes.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=3 $(SOURCES) randombytes.c test_kyber.c -o test_kyber768 - -test_kyber1024: $(SOURCES) $(HEADERS) test_kyber.c randombytes.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=4 $(SOURCES) randombytes.c test_kyber.c -o test_kyber1024 - -test_kex512: $(SOURCES) $(HEADERS) test_kex.c randombytes.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=2 $(SOURCES) randombytes.c test_kex.c -o test_kex512 - -test_kex768: $(SOURCES) $(HEADERS) test_kex.c randombytes.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=3 $(SOURCES) randombytes.c test_kex.c -o test_kex768 - -test_kex1024: $(SOURCES) $(HEADERS) test_kex.c randombytes.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=4 $(SOURCES) randombytes.c test_kex.c -o test_kex1024 - -testvectors512: $(SOURCES) $(HEADERS) cpucycles.h cpucycles.c testvectors.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=2 $(SOURCES) cpucycles.c testvectors.c -o testvectors512 - -testvectors768: $(SOURCES) $(HEADERS) cpucycles.h cpucycles.c testvectors.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=3 $(SOURCES) cpucycles.c testvectors.c -o testvectors768 - -testvectors1024: $(SOURCES) $(HEADERS) cpucycles.h cpucycles.c testvectors.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=4 $(SOURCES) cpucycles.c testvectors.c -o testvectors1024 - -speed512: $(SOURCES) $(HEADERS) cpucycles.h cpucycles.c speed.c randombytes.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=2 $(SOURCES) randombytes.c cpucycles.c speed.c -o speed512 - -speed768: $(SOURCES) $(HEADERS) cpucycles.h cpucycles.c speed.c randombytes.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=3 $(SOURCES) randombytes.c cpucycles.c speed.c -o speed768 - -speed1024: $(SOURCES) $(HEADERS) cpucycles.h cpucycles.c speed.c randombytes.c randombytes.h - $(CC) $(CFLAGS) -DKYBER_K=4 $(SOURCES) randombytes.c cpucycles.c speed.c -o speed1024 - -PQCgenKAT_kem: $(SOURCES) $(HEADERS) PQCgenKAT_kem.c rng.c rng.h - $(CC) $(NISTFLAGS) -o $@ $(SOURCES) -I. rng.c PQCgenKAT_kem.c -lcrypto - -keccak4x/KeccakP-1600-times4-SIMD256.o: keccak4x/KeccakP-1600-times4-SIMD256.c \ - - keccak4x/align.h \ - keccak4x/brg_endian.h \ - keccak4x/KeccakP-1600-times4-SIMD256.c \ - keccak4x/KeccakP-1600-times4-SnP.h \ - keccak4x/KeccakP-1600-unrolling.macros \ - keccak4x/SIMD256-config.h - $(CC) $(CFLAGS) -c keccak4x/KeccakP-1600-times4-SIMD256.c -o $@ - -.PHONY: clean test - -clean: - -$(RM) *.o - -$(RM) -r test_kyber512 - -$(RM) -r test_kyber768 - -$(RM) -r test_kyber1024 - -$(RM) -r test_kex512 - -$(RM) -r test_kex768 - -$(RM) -r test_kex1024 - -$(RM) -r testvectors512 - -$(RM) -r testvectors768 - -$(RM) -r testvectors1024 - -$(RM) -r speed512 - -$(RM) -r speed768 - -$(RM) -r speed1024 - -$(RM) -r PQCgenKAT_kem diff --git a/LICENSE b/LICENSE index b0a72fb2..eea38374 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,8 @@ +Dual-licensed under Unlicense or MIT. + + +----------------------- Unlicense --------------------------- + This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or @@ -21,4 +26,26 @@ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -For more information, please refer to \ No newline at end of file +For more information, please refer to + + +----------------------- MIT --------------------------- +Copyright 2021 Peter Rindal + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies +or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/README.md b/README.md index 095a231b..db53ba52 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ ![](./titleOSU.PNG) ===== - +![Build Status](https://github.com/osu-crypto/libOTe/actions/workflows/build-test.yml/badge.svg) -A fast and portable C++14 library for Oblivious Transfer extension (OTe). The +A fast and portable C++17 library for Oblivious Transfer extension (OTe). The primary design goal of this library to obtain *high performance* while being *easy to use*. This library currently implements: -* The semi-honest 1-out-of-2 OT [IKNP03]. +* The semi-honest 1-out-of-2 OT [[IKNP03]](https://www.iacr.org/archive/crypto2003/27290145/27290145.pdf). * The semi-honest 1-out-of-2 Silent OT [[BCGIKRS19]](https://eprint.iacr.org/2019/1159.pdf). -* The semi-honest 1-out-of-2 Delta-OT [IKNP03],[[BLNNOOSS15]](https://eprint.iacr.org/2015/472.pdf). +* The semi-honest 1-out-of-2 Delta-OT [[IKNP03]](https://www.iacr.org/archive/crypto2003/27290145/27290145.pdf),[[BLNNOOSS15]](https://eprint.iacr.org/2015/472.pdf). * The semi-honest 1-out-of-N OT [[KKRT16]](https://eprint.iacr.org/2016/799). * The malicious secure 1-out-of-2 OT [[KOS15]](https://eprint.iacr.org/2015/546). * The malicious secure 1-out-of-2 Delta-OT [[KOS15]](https://eprint.iacr.org/2015/546),[[BLNNOOSS15]](https://eprint.iacr.org/2015/472.pdf). @@ -18,21 +18,117 @@ primary design goal of this library to obtain *high performance* while being * The malicious secure 1-out-of-2 base OT [NP01]. * The malicious secure 1-out-of-2 base OT [[CO15]](https://eprint.iacr.org/2015/267.pdf) (Faster Linux ASM version disabled by default). * The malicious secure 1-out-of-2 base OT [[MR19]](https://eprint.iacr.org/2019/706.pdf) +* Several malicious secure batched 1-out-of-2 base OTs from [[MRR21]](https://eprint.iacr.org/2021/682) ## Introduction This library provides several different classes of OT protocols. First is the -base OT protocol of Naor Pinkas [NP01]. This protocol bootstraps all the other +base OT protocol of [NP01, CO15, MR19, MRR21]. These protocol bootstraps all the other OT extension protocols. Within the OT extension protocols, we have 1-out-of-2, -1-out-of-N and K-out-of-N, both in the semi-honest and malicious settings. +1-out-of-N and K-out-of-N, both in the semi-honest and malicious settings. See The `frontend` or `libOTe_Tests` folder for examples. All implementations are highly optimized using fast SSE instructions and vectorization to obtain optimal performance both in the single and multi-threaded setting. See the **Performance** section for a comparison between protocols and to other libraries. -Networking can be performed using both the sockets provided by the library and -external socket classes. See the [networking tutorial](https://github.com/ladnir/cryptoTools/blob/57220fc45252d089a7fd90816144e447a2ce02b8/frontend_cryptoTools/Tutorials/Network.cpp#L264) -for an example. +Networking can be performed using both the sockets provided by the library and +external socket classes. See the [networking tutorial](https://github.com/ladnir/cryptoTools/blob/57220fc45252d089a7fd90816144e447a2ce02b8/frontend_cryptoTools/Tutorials/Network.cpp#L264) for an example. + + +## Build + +The library is *cross platform* and has been tested on Windows, Mac and Linux. +There is one mandatory dependency on [Boost 1.75](http://www.boost.org/) (networking), +and three **optional dependencies** on [libsodium](https://doc.libsodium.org/), +[Relic](https://github.com/relic-toolkit/relic), or +[SimplestOT](https://github.com/osu-crypto/libOTe/tree/master/SimplestOT) (Unix only) +for Base OTs. +CMake 3.15+ is required and the build script assumes python 3. + +The library can be built as +``` +git clone --recursive https://github.com/osu-crypto/libOTe.git +cd libOTe +python build.py --setup --boost --relic +python build.py -- -D ENABLE_RELIC=ON -D ENABLE_ALL_OT=ON +``` +The main executable with examples is `frontend` and is located in the build directory, eg `out/build/linux/frontend/frontend.exe, out/build/x64-Release/frontend/Release/frontend.exe` depending on the OS. + +### Build Options +LibOTe can be built with various only the selected protocols enabled. `-D ENABLE_ALL_OT=ON` will enable all available protocols depending on platform/dependancies. The `ON`/`OFF` options include + +**Malicious base OT:** + * `ENABLE_SIMPLESTOT` the SimplestOT [[CO15]](https://eprint.iacr.org/2015/267.pdf) protocol (relic or sodium). + * `ENABLE_SIMPLESTOT_ASM` the SimplestOT base OT protocol [[CO15]](https://eprint.iacr.org/2015/267.pdf) protocol (linux assembly). + * `ENABLE_MRR` the McQuoid Rosulek Roy [[MRR20]](https://eprint.iacr.org/2020/1043) protocol (relic or sodium). + * `ENABLE_MRR_TWIST` the McQuoid Rosulek Roy [[MRR21]](https://eprint.iacr.org/2021/682) protocol (sodium fork). + * `ENABLE_MR` the Masny Rindal [[MR19]](https://eprint.iacr.org/2019/706.pdf) protocol (relic or sodium). + * `ENABLE_MR_KYBER` the Masny Rindal [[MR19]](https://eprint.iacr.org/2019/706.pdf) protocol (Kyber fork). + * `ENABLE_NP` the Naor Pinkas [NP01] base OT (relic or sodium). + +**1-out-of-2 OT Extension:** + * `ENABLE_IKNP` the Ishai et al [[IKNP03]](https://www.iacr.org/archive/crypto2003/27290145/27290145.pdf) semi-honest protocol. + * `ENABLE_KOS` the Keller et al [[KOS15]](https://eprint.iacr.org/2015/546) malicious protocol. + * `ENABLE_DELTA_KOS` the Burra et al [[BLNNOOSS15]](https://eprint.iacr.org/2015/472.pdf),[[KOS15]](https://eprint.iacr.org/2015/546) malicious Delta-OT protocol. + * `ENABLE_SILENTOT` the Couteau et al [CRR21],[[BCGIKRS19]](https://eprint.iacr.org/2019/1159.pdf) semi-honest/malicious protocol. + + **Vole:** + * `ENABLE_SILENT_VOLE` the Couteau et al [CRR21] semi-honest/malicious protocol. + + Addiition options can be set for cryptoTools. See the cmake output. + +### Dependancies + +Dependancies can be managed via the `build.py` script or or installed via an external tool. If an external tool is used install to system location or set `-D CMAKE_PREFIX_PATH=path/to/install`. + +**Boost** +The library requires boost and can be fetched as +``` +python build.py --setup --boost +``` + +**Enabling/Disabling [Relic](https://github.com/relic-toolkit/relic) (for base OTs):** + The library can be built with Relic as +``` +python build.py --setup --relic +python build.py -- -D ENABLE_RELIC=ON +``` +Relic can be disabled by removing `--relic` from the setup and setting `-D ENABLE_RELIC=OFF`. + +**Enabling/Disabling [libsodium](https://github.com/osu-crypto/libsodium) (for base OTs):** + The library can be built with libsodium as +``` +python build.py --setup --sodium +python build.py -- -D ENABLE_SODIUM=ON +``` +libsodium can be disabled by removing `--sodium` from the setup and setting `-D ENABLE_SODIUM=OFF`. The McQuoid Rosulek Roy 2021 Base OTs uses a twisted curve which additionally require the `noclamp` option for Montgomery curves and is currently only in a [fork](https://github.com/osu-crypto/libsodium) of libsodium. If you prefer the stable libsodium, then install it and add `-D SODIUM_MONTGOMERY=OFF` as a cmake argument to libOTe. + +## Install + +libOTe can be installed and linked the same way as other cmake projects. By default the dependancies are not installed. To install all dependancies, run the following +``` +python build.py --setup --boost --relic --sodium --install +``` +You can also selectively install the dependancies. The install location can be specifying as `--install=path/to/installation`. Otherwise the system default is used. + +The main library is similarly installed as +``` +python build.py --install +``` + +By default, sudo is not used. If installation requires sudo access, then add `--sudo` to the `build.py` script arguments. See `python build.py --help` for full details. + + +## Linking +libOTe can be linked via cmake as +``` +find_package(libOTe REQUIRED) +target_link_libraries(myProject oc::libOTe) +``` +Other exposed targets are `oc::cryptoTools, oc::tests_cryptoTools, oc::libOTe_Tests`. In addition, cmake variables `libOTe_LIB, libOTe_INC, ENABLE_XXX` will be defined, where `XXX` is one of the libOTe options. + +To ensure that cmake can find libOTe, you can either install libOTe or build it locally and set `-D CMAKE_PREFIX_PATH=path/to/libOTe` or provide its location as a cmake `HINTS`, i.e. `find_package(libOTe HINTS path/to/libOTe)`. + ## Example Code A minimal working example showing how to perform `n` OTs using the IKNP protocol. @@ -78,126 +174,6 @@ void minimal() } ``` -## Performance - -The running time in seconds for computing n=224 OTs on a single Intel -Xeon server (`2 36-cores Intel Xeon CPU E5-2699 v3 @ 2.30GHz and 256GB of RAM`) -as of 11/16/2016. All timings shown reflect a "single" thread per party, with the -expection that network IO in libOTe is performed in the background by a separate thread. - - -| *Type* | *Security* | *Protocol* | libOTe (SHA1/AES) | [Encrypto Group](https://github.com/encryptogroup/OTExtension) (SHA256) | [Apricot](https://github.com/bristolcrypto/apricot) (AES-hash) | OOS16 (blake2) | [emp-toolkit](https://github.com/emp-toolkit) (AES-hash) | -|--------------------- |----------- |-------------- |---------------- |---------------- |--------- |--------- |------------ | -| 1-out-of-N (N=276) | malicious | OOS16 | **10.6 / 9.2** | ~ | ~ | 24** | ~ | -| 1-out-of-N (N=2128)| passive| KKRT16 | **9.2 / 6.7** | ~ | ~ | ~ | ~ | -| 1-out-of-2 Delta-OT | malicious | KOS15 | **1.9*** | ~ | ~ | ~ | ~ | -| 1-out-of-2 Delta-OT | passive | KOS15 | **1.7*** | ~ | ~ | ~ | ~ | -| 1-out-of-2 | malicious | ALSZ15 | ~ | 17.3 | ~ | ~ | 10 | -| 1-out-of-2 | malicious | KOS15 | **3.9 / 0.7** | ~ | 1.1 | ~ | 2.9 | -| 1-out-of-2 | passive | IKNP03 | **3.7 / 0.6** | 11.3 | **0.6** | ~ | 2.7 | -| 1-out-of-2 Base | malicious | CO15 | **1,592/~** | ~ |~ | ~ | ~ | -| 1-out-of-2 Base | malicious | NP00 | **12,876/~** | ~ | ~ | ~ | ~ | - - - -## Install - -The library is *cross platform* and has been tested on Windows, Mac and Linux. -There is one mandatory dependency on [Boost 1.69](http://www.boost.org/) (networking), -and three **optional dependencies** on, [Miracl](https://www.miracl.com/), -[Relic](https://github.com/relic-toolkit/relic) or -[SimplestOT](https://github.com/osu-crypto/libOTe/tree/master/SimplestOT) (Unix only) -for Base OTs. Any or all of these dependenies can be enabled. See below. - - -### Windows - -In `Powershell`, this will set up the project - -``` -git clone --recursive https://github.com/osu-crypto/libOTe.git -cd libOTe/cryptoTools/thirdparty/win -getBoost.ps1 -cd ../../.. -libOTe.sln -``` -Not all protocols will be built by default. Which protocol are built is controlled by the `libOTe/config.h` file. Manually edit this file to enable the desired protocol. - -To see all the command line options, execute the program `frontend.exe`. - -**Boost and visual studio 2017:** If boost does not build with visual studio 2017 -follow [these instructions](https://stackoverflow.com/questions/41464356/build-boost-with-msvc-14-1-vs2017-rc). - -**Enabling [Relic](https://github.com/relic-toolkit/relic) (for base OTs):** - * Build the library in the folder next libOTe (i.e. share the same parent directory): -``` -git clone https://github.com/ladnir/relic.git -cd relic -cmake . -DMULTI=OPENMP -DCMAKE_INSTALL_PREFIX:PATH=C:\libs -DCMAKE_GENERATOR_PLATFORM=x64 -DRUNTIME=MT -cmake --build . -cmake --install . -``` - * Edit the config file [libOTe/cryptoTools/cryptoTools/Common/config.h](https://github.com/ladnir/cryptoTools/blob/master/cryptoTools/Common/config.h) to include `#define ENABLE_RELIC ON`. - -### Linux / Mac - - In short, this will build the project - -``` -git clone --recursive https://github.com/osu-crypto/libOTe.git -cd libOTe/cryptoTools/thirdparty/linux -bash boost.get -cd ../../.. -cmake . -DENABLE_XXX=ON -make -``` -where `ENABLE_XXX` should be replaced by `ENABLE_IKNP, ENABLE_KOS, ...` depending on which protocol(s) should be enabled. See the output of `cmake .` for a complete list. You will also need to enable one one of the base OT protocols (see below). The libraries will be placed in `libOTe/lib` and the binary `frontend_libOTe` will be placed in -`libOTe/bin` To see all the command line options, execute the program - -`./bin/frontend_libOTe` - - -**Enable Base OTs using:** - * `cmake . -DENABLE_RELIC=ON`: Build the library with integration to the - [Relic](https://github.com/relic-toolkit/relic) library. Requires that - relic is built with `cmake . -DMULTI=PTHREAD` and installed. - * **Linux Only**: `cmake . -DENABLE_SIMPLESTOT_ASM=ON`: Build the library with integration to the - [SimplestOT](https://github.com/osu-crypto/libOTe/tree/master/SimplestOT) - library implementing a base OT. - -**Other Options:** Several other compile time options exists. See the output of `cmake .` for a complete list. - - -**Note:** In the case boost is already installed, the steps -`cd libOTe/cryptoTools/thirdparty/linux; bash boost.get` can be skipped and CMake will attempt -to find them instead. Boost is found with the CMake findBoost package and miracl -is found with the `find_library(miracl)` command. If there is a version mismatch then you will still need to run the provided boost build script. - - - -### Linking - - You can either `make install` on linux or link libOTe's source tree. In the latter - case, you will need to include the following: - -1) .../libOTe -2) .../libOTe/cryptoTools -3) .../libOTe/cryptoTools/thirdparty/linux/boost -4) .../libOTe/cryptoTools/thirdparty/linux/miracl/miracl (if enabled) -5) [Relic includes] (if enabled) - -and link: -1) .../libOTe/bin/liblibOTe.a -2) .../libOTe/bin/libcryptoTools.a -3) .../libOTe/bin/libSimplestOT.a (if enabled) -3) .../libOTe/bin/libKyberOT.a (if enabled) -4) .../libOTe/cryptoTools/thirdparty/linux/boost/stage/lib/libboost_system.a -5) .../libOTe/cryptoTools/thirdparty/linux/boost/stage/lib/libboost_thread.a -6) .../libOTe/cryptoTools/thirdparty/linux/miracl/miracl/source/libmiracl.a (if enabled) -7) [Relic binary] (if enabled) - -**Note:** On windows the linking paths follow a similar pattern. - ## Help Contact Peter Rindal peterrindal@gmail.com for any assistance on building @@ -217,14 +193,36 @@ or running the library. ## License -This project has been placed in the public domain. As such, you are unrestricted in how +This project has been placed in the public domain and/or MIT license. As such, you are unrestricted in how you use it, commercial or otherwise. However, no warranty of fitness is provided. If you found this project helpful, feel free to spread the word and cite us. + + ## Performance +The running time in seconds for computing n=224 OTs on a single Intel +Xeon server (`2 36-cores Intel Xeon CPU E5-2699 v3 @ 2.30GHz and 256GB of RAM`) +as of 11/16/2016. All timings shown reflect a "single" thread per party, with the +expection that network IO in libOTe is performed in the background by a separate thread. + + +| *Type* | *Security* | *Protocol* | libOTe (SHA1/AES) | [Encrypto Group](https://github.com/encryptogroup/OTExtension) (SHA256) | [Apricot](https://github.com/bristolcrypto/apricot) (AES-hash) | OOS16 (blake2) | [emp-toolkit](https://github.com/emp-toolkit) (AES-hash) | +|--------------------- |----------- |-------------- |---------------- |---------------- |--------- |--------- |------------ | +| 1-out-of-N (N=276) | malicious | OOS16 | **10.6 / 9.2** | ~ | ~ | 24** | ~ | +| 1-out-of-N (N=2128)| passive| KKRT16 | **9.2 / 6.7** | ~ | ~ | ~ | ~ | +| 1-out-of-2 Delta-OT | malicious | KOS15 | **1.9*** | ~ | ~ | ~ | ~ | +| 1-out-of-2 Delta-OT | passive | KOS15 | **1.7*** | ~ | ~ | ~ | ~ | +| 1-out-of-2 | malicious | ALSZ15 | ~ | 17.3 | ~ | ~ | 10 | +| 1-out-of-2 | malicious | KOS15 | **3.9 / 0.7** | ~ | 1.1 | ~ | 2.9 | +| 1-out-of-2 | passive | IKNP03 | **3.7 / 0.6** | 11.3 | **0.6** | ~ | 2.7 | +| 1-out-of-2 Base | malicious | CO15 | **1,592/~** | ~ |~ | ~ | ~ | +| 1-out-of-2 Base | malicious | NP00 | **12,876/~** | ~ | ~ | ~ | ~ | + ## Citation +[NP01] - Moni Naor, Benny Pinkas, _Efficient Oblivious Transfer Protocols_. + [IKNP03] - Yuval Ishai and Joe Kilian and Kobbi Nissim and Erez Petrank, _Extending Oblivious Transfers Efficiently_. [KOS15] - Marcel Keller and Emmanuela Orsini and Peter Scholl, _Actively Secure OT Extension with Optimal Overhead_. [eprint/2015/546](https://eprint.iacr.org/2015/546) @@ -238,6 +236,6 @@ found this project helpful, feel free to spread the word and cite us. [BLNNOOSS15] - Sai Sheshank Burra and Enrique Larraia and Jesper Buus Nielsen and Peter Sebastian Nordholt and Claudio Orlandi and Emmanuela Orsini and Peter Scholl and Nigel P. Smart, _High Performance Multi-Party Computation for Binary Circuits Based on Oblivious Transfer_. [eprint/2015/472](https://eprint.iacr.org/2015/472.pdf) [ALSZ15] - Gilad Asharov and Yehuda Lindell and Thomas Schneider and Michael Zohner, _More Efficient Oblivious Transfer Extensions with Security for Malicious Adversaries_. [eprint/2015/061](https://eprint.iacr.org/2015/061) - -[NP01] - Moni Naor, Benny Pinkas, _Efficient Oblivious Transfer Protocols_. + + diff --git a/SimplestOT/CMakeLists.txt b/SimplestOT/CMakeLists.txt deleted file mode 100644 index 9ce136a0..00000000 --- a/SimplestOT/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -#project(SimplestOT C C++ ASM) - -enable_language(ASM) - -file(GLOB_RECURSE SRC_SIMPLE_LIB - ${CMAKE_SOURCE_DIR}/SimplestOT/*.c - ${CMAKE_SOURCE_DIR}/SimplestOT/*.s) - -add_library(SimplestOT STATIC ${SRC_SIMPLE_LIB}) -target_link_libraries(SimplestOT PUBLIC cryptoTools) -#target_compile_options(SimplestOT PUBLIC -fPIC -no-pie) -target_link_options(SimplestOT PUBLIC -fPIC -no-pie) - -############################################# -# Install # -############################################# - -# install library -install(TARGETS SimplestOT DESTINATION lib) - -# install headers -install(DIRECTORY . DESTINATION include/SimplestOT FILES_MATCHING PATTERN "*.h") diff --git a/SimplestOT/SimplestOT.vcxproj b/SimplestOT/SimplestOT.vcxproj deleted file mode 100644 index 2ff4ffb0..00000000 --- a/SimplestOT/SimplestOT.vcxproj +++ /dev/null @@ -1,323 +0,0 @@ - - - - - Debug_DLLRT - Win32 - - - Debug_DLLRT - x64 - - - Debug - Win32 - - - Release_DLLRT - Win32 - - - Release_DLLRT - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {904419B6-0A3E-41A8-B27A-CF1BAE7343B6} - SimplestOT - 10.0 - - - - Application - true - v142 - MultiByte - - - Application - true - v142 - MultiByte - - - Application - false - v142 - true - MultiByte - - - Application - false - v142 - true - MultiByte - - - Application - true - v142 - MultiByte - - - Application - true - v142 - MultiByte - - - Application - false - v142 - true - MultiByte - - - Application - false - v142 - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Level3 - MaxSpeed - true - true - true - true - $(ProjectDir)../cryptoTools/ - - - true - true - - - %(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - true - true - $(ProjectDir)../cryptoTools/ - - - true - true - - - %(AdditionalDependencies) - - - - - Level3 - Disabled - true - true - - - - - Level3 - Disabled - true - true - - - - - Level3 - Disabled - true - true - $(ProjectDir)../cryptoTools/ - - - - - %(AdditionalDependencies) - - - - - Level3 - Disabled - true - true - $(ProjectDir)../cryptoTools/ - - - - - %(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - true - true - - - true - true - - - - - Level3 - MaxSpeed - true - true - true - true - - - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SimplestOT/SimplestOT.vcxproj.filters b/SimplestOT/SimplestOT.vcxproj.filters deleted file mode 100644 index 3a9965fd..00000000 --- a/SimplestOT/SimplestOT.vcxproj.filters +++ /dev/null @@ -1,202 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build.py b/build.py new file mode 100644 index 00000000..70500753 --- /dev/null +++ b/build.py @@ -0,0 +1,43 @@ +import os +import sys +import cryptoTools.build + +import thirdparty.getBitpolymul as getBitpolymul + + +def getParallel(args): + par = multiprocessing.cpu_count() + for x in args: + if x.startswith("--par="): + val = x.split("=",1)[1] + par = int(val) + if par < 1: + par = 1 + return par + + +def Setup(install, prefix, par): + dir_path = os.path.dirname(os.path.realpath(__file__)) + os.chdir(dir_path + "/thirdparty") + + + getBitpolymul.get(install,prefix, par) + + os.chdir(dir_path) + + + + +if __name__ == "__main__": + + + (mainArgs, cmake) = cryptoTools.build.parseArgs() + install, prefix = cryptoTools.build.getInstallArgs(mainArgs) + par = cryptoTools.build.getParallel(mainArgs) + + bitpolymul = "--bitpolymul" in mainArgs + setup = "--setup" in mainArgs + if setup and bitpolymul: + Setup(install, prefix, par) + + cryptoTools.build.main("libOTe") diff --git a/buildAll.ps1 b/buildAll.ps1 deleted file mode 100644 index 747e5bc8..00000000 --- a/buildAll.ps1 +++ /dev/null @@ -1,30 +0,0 @@ -$ErrorActionPreference = "Stop" - -# Update this if needed -$MSBuild = 'C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe' -#$MSBuild = 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe' - -if(!(Test-Path $MSBuild)) -{ - - - Write-Host "Could not find MSBuild as" - Write-Host " $MSBuild" - Write-Host "" - Write-Host "Please update its location in the script" - - exit - -} - -cd ./cryptoTools/thirdparty/win - -& ./getBoost.ps1 -& ./getMiracl.ps1 - -cd ../../.. - -& $MSBuild libOTe.sln /p:Configuration=Release /p:Platform=x64 -& $MSBuild libOTe.sln /p:Configuration=Debug /p:Platform=x64 - - diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in new file mode 100644 index 00000000..1fe36d9f --- /dev/null +++ b/cmake/Config.cmake.in @@ -0,0 +1,33 @@ +@PACKAGE_INIT@ + +set(ENABLE_BITPOLYMUL @ENABLE_BITPOLYMUL@) +set(ENABLE_SIMPLESTOT @ENABLE_SIMPLESTOT@) +set(ENABLE_SIMPLESTOT_ASM @ENABLE_SIMPLESTOT_ASM@) +set(ENABLE_MR @ENABLE_MR@) +set(ENABLE_MR_KYBER @ENABLE_MR_KYBER@) +set(ENABLE_NP @ENABLE_NP@) +set(ENABLE_KOS @ENABLE_KOS@) +set(ENABLE_IKNP @ENABLE_IKNP@) +set(ENABLE_SILENTOT @ENABLE_SILENTOT@) +set(ENABLE_DELTA_KOS @ENABLE_DELTA_KOS@) +set(ENABLE_DELTA_IKNP @ENABLE_DELTA_IKNP@) +set(ENABLE_OOS @ENABLE_OOS@) +set(ENABLE_KKRT @ENABLE_KKRT@) +set(ENABLE_RR @ENABLE_RR@) +set(ENABLE_AKN @ENABLE_AKN@) +set(ENABLE_SILENT_VOLE @ENABLE_SILENT_VOLE@) + +find_package(cryptoTools REQUIRED HINTS "${CMAKE_CURRENT_LIST_DIR}/.." ${CMAKE_CURRENT_LIST_DIR}) + +include("${CMAKE_CURRENT_LIST_DIR}/libOTeDepHelper.cmake") + + +include("${CMAKE_CURRENT_LIST_DIR}/libOTeTargets.cmake") + +OC_getAllLinkedLibraries(oc::libOTe libOTe_LIBRARIES libOTe_INCLUDE_DIRS) +OC_getAllLinkedLibraries(oc::libOTe_Tests libOTe_Tests_LIBRARIES libOTe_Tests_INCLUDE_DIRS) + +set(libOTe_LIB ${libOTe_LIBRARIES}) +set(libOTe_INC ${libOTe_INCLUDE_DIRS}) +set(libOTe_Tests_LIB ${libOTe_Tests_LIBRARIES}) +set(libOTe_Tests_INC ${libOTe_Tests_INCLUDE_DIRS}) \ No newline at end of file diff --git a/cmake/buildOptions.cmake b/cmake/buildOptions.cmake new file mode 100644 index 00000000..88fd0247 --- /dev/null +++ b/cmake/buildOptions.cmake @@ -0,0 +1,138 @@ + +if(DEFINED ENABLE_ALL_OT) + + # requires sodium or relic + if(${ENABLE_SODIUM} OR ${ENABLE_RELIC}) + set(oc_BB ${ENABLE_ALL_OT}) + else() + set(oc_BB OFF) + endif() + set(ENABLE_SIMPLESTOT ${oc_BB} CACHE BOOL "" FORCE) + set(ENABLE_MR ${oc_BB} CACHE BOOL "" FORCE) + set(ENABLE_NP ${oc_BB} CACHE BOOL "" FORCE) + + # requires sodium + if(${ENABLE_SODIUM} OR ${ENABLE_RELIC}) + set(oc_BB ${ENABLE_ALL_OT}) + else() + set(oc_BB OFF) + endif() + set(ENABLE_MRR ${oc_BB} CACHE BOOL "" FORCE) + + # requires sodium + if(${ENABLE_SODIUM} AND SODIUM_MONTGOMERY) + set(oc_BB ${ENABLE_ALL_OT}) + else() + set(oc_BB OFF) + endif() + set(ENABLE_MRR_TWIST ${oc_BB} CACHE BOOL "" FORCE) + + + # requires linux + if(UNIX AND NOT(APPLE OR MSVC)) + set(oc_BB ${ENABLE_ALL_OT}) + else() + set(oc_BB OFF) + endif() + set(ENABLE_SIMPLESTOT_ASM ${oc_BB} CACHE BOOL "" FORCE) + set(ENABLE_MR_KYBER ${oc_BB} CACHE BOOL "" FORCE) + + + # general + set(ENABLE_KOS ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) + set(ENABLE_IKNP ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) + set(ENABLE_SILENTOT ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) + set(ENABLE_DELTA_KOS ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) + set(ENABLE_DELTA_IKNP ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) + set(ENABLE_OOS ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) + set(ENABLE_KKRT ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) + set(ENABLE_RR ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) + set(ENABLE_AKN ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) + set(ENABLE_SILENT_VOLE ${ENABLE_ALL_OT} CACHE BOOL "" FORCE) + unset(ENABLE_ALL_OT CACHE) +endif() + +option(ENABLE_SIMPLESTOT "Build the SimplestOT base OT" OFF) +option(ENABLE_SIMPLESTOT_ASM "Build the assembly based SimplestOT library" OFF) +option(ENABLE_MRR "Build the McQuoidRosulekRoy 20 PopfOT base OT using Ristretto KA" OFF) +option(ENABLE_MRR_TWIST "Build the McQuoidRosulekRoy 21 PopfOT base OT using Moeller KA" OFF) +option(ENABLE_MR "Build the MasnyRindal base OT" OFF) +option(ENABLE_MR_KYBER "Build the Kyber (LWE based) library and MR-Kyber base OT" OFF) +option(ENABLE_NP "Build the NaorPinkas base OT" OFF) + +option(ENABLE_KOS "Build the KOS OT-Ext protocol." OFF) +option(ENABLE_IKNP "Build the IKNP OT-Ext protocol." OFF) +option(ENABLE_SILENTOT "Build the Slient OT protocol." OFF) +option(ENABLE_DELTA_KOS "Build the KOS Delta-OT-Ext protocol." OFF) +option(ENABLE_DELTA_IKNP "Build the IKNP Delta-OT-Ext protocol." OFF) + +option(ENABLE_OOS "Build the OOS 1-oo-N OT-Ext protocol." OFF) +option(ENABLE_KKRT "Build the KKRT 1-oo-N OT-Ext protocol." OFF) +option(ENABLE_RR "Build the RR 1-oo-N OT-Ext protocol." OFF) + +option(ENABLE_AKN "Build the RR ~k-oo-N OT-Ext protocol." OFF) + +set(ENABLE_BITPOLYMUL ${ENABLE_SILENTOT}) + + +message(STATUS "General Options\n=======================================================") +message(STATUS "Option: ENABLE_ALL_OT = ON/OFF") + +message(STATUS "Base OT protocols\n=======================================================") +message(STATUS "Option: ENABLE_SIMPLESTOT = ${ENABLE_SIMPLESTOT}") +message(STATUS "Option: ENABLE_SIMPLESTOT_ASM = ${ENABLE_SIMPLESTOT_ASM}") +message(STATUS "Option: ENABLE_MRR = ${ENABLE_MRR}") +message(STATUS "Option: ENABLE_MRR_TWIST = ${ENABLE_MRR_TWIST}") +message(STATUS "Option: ENABLE_MR = ${ENABLE_MR}") +message(STATUS "Option: ENABLE_MR_KYBER = ${ENABLE_MR_KYBER}") +message(STATUS "Option: ENABLE_NP = ${ENABLE_NP}\n\n") + +message(STATUS "1-out-of-2 OT Extension protocols\n=======================================================") +message(STATUS "Option: ENABLE_KOS = ${ENABLE_KOS}") +message(STATUS "Option: ENABLE_IKNP = ${ENABLE_IKNP}") +message(STATUS "Option: ENABLE_SILENTOT = ${ENABLE_SILENTOT}\n\n") + +message(STATUS "1-out-of-2 Delta-OT Extension protocols\n=======================================================") +message(STATUS "Option: ENABLE_DELTA_KOS = ${ENABLE_DELTA_KOS}\n\n") + +message(STATUS "1-out-of-N OT Extension protocols\n=======================================================") +message(STATUS "Option: ENABLE_OOS = ${ENABLE_OOS}") +message(STATUS "Option: ENABLE_KKRT = ${ENABLE_KKRT}") +message(STATUS "Option: ENABLE_RR = ${ENABLE_RR}\n\n") + + +############################################# +# Config Checks # +############################################# + +if(NOT UNIX OR APPLE OR MSVC) + if(ENABLE_SIMPLESTOT_ASM) + message(FATAL_ERROR "ENABLE_SIMPLESTOT_ASM only supported on Linux") + endif() + if(ENABLE_MR_KYBER) + message(FATAL_ERROR "ENABLE_MR_KYBER only supported on Linux") + endif() + +endif() + +if( NOT ENABLE_SIMPLESTOT AND + NOT ENABLE_SIMPLESTOT_ASM AND + NOT ENABLE_MRR AND + NOT ENABLE_MRR_TWIST AND + NOT ENABLE_MR AND + NOT ENABLE_MR_KYBER AND + NOT ENABLE_NP) + message(WARNING "NO Base OT enabled.") +endif() + +if (ENABLE_MRR_TWIST AND NOT ENABLE_SODIUM) + message(FATAL_ERROR "ENABLE_MRR_TWIST requires ENABLE_SODIUM") +endif() + +if (ENABLE_MRR_TWIST AND NOT SODIUM_MONTGOMERY) + message(FATAL_ERROR "ENABLE_MRR_TWIST requires libsodium to support Montgomery curve noclamp operations. get sodium from https://github.com/osu-crypto/libsodium to enable.") +endif() + +if ((ENABLE_SIMPLESTOT OR ENABLE_MR OR ENABLE_NP OR ENABLE_MRR) AND NOT (ENABLE_SODIUM OR ENABLE_RELIC)) + message(FATAL_ERROR "ENABLE_SIMPLESTOT, ENABLE_MR, ENABLE_NP, and ENABLE_MRR require ENABLE_SODIUM or ENABLE_RELIC") +endif() \ No newline at end of file diff --git a/cmake/install.cmake b/cmake/install.cmake new file mode 100644 index 00000000..4463d90f --- /dev/null +++ b/cmake/install.cmake @@ -0,0 +1,106 @@ + + + + + + +############################################# +# Install # +############################################# + + +#configure_file("${CMAKE_CURRENT_LIST_DIR}/libOTeDepHelper.cmake" "libOTeDepHelper.cmake" ) + +# make cache variables for install destinations +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) + + +# generate the config file that is includes the exports +configure_package_config_file( + "${CMAKE_CURRENT_LIST_DIR}/Config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/libOTeConfig.cmake" + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libOTe + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO +) + +if(NOT DEFINED libOTe_VERSION_MAJOR) + message("\n\n\n\n warning, libOTe_VERSION_MAJOR not defined ${libOTe_VERSION_MAJOR}") +endif() + +set_property(TARGET libOTe PROPERTY VERSION ${libOTe_VERSION}) + +# generate the version file for the config file +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/libOTeConfigVersion.cmake" + VERSION "${libOTe_VERSION_MAJOR}.${libOTe_VERSION_MINOR}.${libOTe_VERSION_PATCH}" + COMPATIBILITY AnyNewerVersion +) + +configure_file("${CMAKE_CURRENT_LIST_DIR}/libOTeDepHelper.cmake" "libOTeDepHelper.cmake" COPYONLY) + +# install the configuration file +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/libOTeConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/libOTeConfigVersion.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/libOTeDepHelper.cmake" + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libOTe +) + +set(exportLibs + "libOTe;libOTe_Tests;") + +if(ENABLE_MR_KYBER) + set(exportLibs "${exportLibs}KyberOT;") + + # install headers + install( + DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../KyberOT/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/KyberOT + FILES_MATCHING PATTERN "*.h") +endif() + +if(ENABLE_SIMPLESTOT_ASM) + set(exportLibs "${exportLibs}SimplestOT;") + # install headers + install( + DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../SimplestOT/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SimplestOT + FILES_MATCHING PATTERN "*.h") +endif() + +# install library +install( + TARGETS ${exportLibs} + DESTINATION ${CMAKE_INSTALL_LIBDIR} + EXPORT libOTeTargets) + +# install headers +install( + DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../libOTe/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libOTe + FILES_MATCHING PATTERN "*.h") + +#install config header +install( + DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/libOTe" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/" + FILES_MATCHING PATTERN "*.h") + +# install test headers +install( + DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../libOTe_Tests/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libOTe_Tests + FILES_MATCHING PATTERN "*.h") + +# install config +install(EXPORT libOTeTargets + FILE libOTeTargets.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libOTe + NAMESPACE oc:: +) + export(EXPORT libOTeTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/libOTeTargets.cmake" + NAMESPACE oc:: +) \ No newline at end of file diff --git a/cmake/libOTeConfig.cmake b/cmake/libOTeConfig.cmake new file mode 100644 index 00000000..f3b0d8be --- /dev/null +++ b/cmake/libOTeConfig.cmake @@ -0,0 +1,15 @@ +# these are just pass through config file for the ones that are placed in the build directory. + +if(MSVC) + set(LIBOTE_THIRDPARTY_HINT "${CMAKE_CURRENT_LIST_DIR}/../thirdparty/win") +else() + set(LIBOTE_THIRDPARTY_HINT "${CMAKE_CURRENT_LIST_DIR}/../thirdparty/unix") +endif() +if(MSVC) + set(OC_THIRDPARTY_HINT "${CMAKE_CURRENT_LIST_DIR}/../cryptoTools/thirdparty/win") +else() + set(OC_THIRDPARTY_HINT "${CMAKE_CURRENT_LIST_DIR}/../cryptoTools/thirdparty/unix") +endif() +include("${CMAKE_CURRENT_LIST_DIR}/libOTeFindBuildDir.cmake") +include("${LIBOTE_BUILD_DIR}/libOTeConfig.cmake") + \ No newline at end of file diff --git a/cmake/libOTeConfigVersion.cmake b/cmake/libOTeConfigVersion.cmake new file mode 100644 index 00000000..4c648601 --- /dev/null +++ b/cmake/libOTeConfigVersion.cmake @@ -0,0 +1,3 @@ +# these are just pass through config file for the ones that are placed in the build directory. +include("${CMAKE_CURRENT_LIST_DIR}/libOTeFindBuildDir.cmake") +include("${LIBOTE_BUILD_DIR}/libOTeConfigVersion.cmake") diff --git a/cmake/libOTeDepHelper.cmake b/cmake/libOTeDepHelper.cmake new file mode 100644 index 00000000..e39972fb --- /dev/null +++ b/cmake/libOTeDepHelper.cmake @@ -0,0 +1,40 @@ +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) +cmake_policy(SET CMP0045 NEW) +cmake_policy(SET CMP0074 NEW) + + +set(LIBOTE_INSOURCE_FIND_DEPS (EXISTS ${CMAKE_CURRENT_LIST_DIR}/libOTeFindBuildDir.cmake)) + +if(NOT DEFINED LIBOTE_THIRDPARTY_HINT) + if(LIBOTE_INSOURCE_FIND_DEPS) + # we currenty are in the libOTe source tree, libOTe/cmake + if(MSVC) + set(LIBOTE_THIRDPARTY_HINT "${CMAKE_CURRENT_LIST_DIR}/../thirdparty/win") + else() + set(LIBOTE_THIRDPARTY_HINT "${CMAKE_CURRENT_LIST_DIR}/../thirdparty/unix") + endif() + else() + # we currenty are in install tree, /lib/cmake/libOTe + set(LIBOTE_THIRDPARTY_HINT "${CMAKE_CURRENT_LIST_DIR}/../../..") + endif() +endif() + +set(PUSHED_CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}) +set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${LIBOTE_THIRDPARTY_HINT}") + + +## bitpolymul +########################################################################### + +if (ENABLE_BITPOLYMUL) + find_package(bitpolymul) + + if(NOT TARGET bitpolymul) + message(FATAL_ERROR "failed to find bitpolymul. Looked at LIBOTE_THIRDPARTY_HINT=${LIBOTE_THIRDPARTY_HINT}") + endif() +endif () + +# resort the previous prefix path +set(CMAKE_PREFIX_PATH ${PUSHED_CMAKE_PREFIX_PATH}) +cmake_policy(POP) \ No newline at end of file diff --git a/cmake/libOTeFindBuildDir.cmake b/cmake/libOTeFindBuildDir.cmake new file mode 100644 index 00000000..96a29b06 --- /dev/null +++ b/cmake/libOTeFindBuildDir.cmake @@ -0,0 +1,35 @@ + + +if(NOT DEFINED LIBOTE_BUILD_TYPE) + if(DEFINED CMAKE_BUILD_TYPE) + set(LIBOTE_BUILD_TYPE ${CMAKE_BUILD_TYPE}) + else() + set(LIBOTE_BUILD_TYPE "Release") + endif() +endif() + +if(NOT LIBOTE_BUILD_DIR) + if(MSVC) + + set(LIBOTE_CONFIG_NAME "${LIBOTE_BUILD_TYPE}") + if("${LIBOTE_CONFIG_NAME}" STREQUAL "RelWithDebInfo" ) + set(LIBOTE_CONFIG_NAME "Release") + endif() + + + set(LIBOTE_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}/../out/build/x64-${LIBOTE_CONFIG_NAME}") + else() + set(LIBOTE_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}/../out/build/linux") + endif() +else() + message(STATUS "LIBOTE_BUILD_DIR preset to ${LIBOTE_BUILD_DIR}") +endif() + + +if(NOT CRYPTOTOOLS_BUILD_DIR) + set(CRYPTOTOOLS_BUILD_DIR "${LIBOTE_BUILD_DIR}/cryptoTools/") +endif() + +if(NOT EXISTS "${LIBOTE_BUILD_DIR}") + message(FATAL_ERROR "failed to find the libOTe build directory. Looked at LIBOTE_BUILD_DIR: ${LIBOTE_BUILD_DIR}") +endif() \ No newline at end of file diff --git a/copySourceToLinux.ps1 b/copySourceToLinux.ps1 deleted file mode 100644 index 1cee046b..00000000 --- a/copySourceToLinux.ps1 +++ /dev/null @@ -1,20 +0,0 @@ -$RemoteUserName='rindalp' -$RemoteHostName='eve.eecs.oregonstate.edu' -$PrivateKey='C:/keys/key.ppk' -$SolutionDir=$PWD -$RemoteWorkingDir='/scratch/repo/libOTe' - -# only files with these extensions will be copied -$FileMasks='**.cpp;**.c;**.h;*.bin,*.S,*.sh,*CMake*;*.in;*/KyberOT/keccak4x/KeccakP-1600-times4-SIMD256.o;*/Tools/*.txt;*/gsl/*;**/Makefile;**.data;thirdparty/linux/**.get;*/libOTe_Tests/testData/*.txt' - -# everything in these folders will be skipped -$ExcludeDirs='.git/;thirdparty/;Debug/;Release/;x64/;ipch/;.vs/;CMakeFiles/;boost/' - -C:\tools\WinSCP.com /command ` - "open $RemoteUserName@$RemoteHostName -privatekey=""$PrivateKey"""` - "call mkdir -p $RemoteWorkingDir"` - "synchronize Remote $SolutionDir $RemoteWorkingDir -filemask=""$FileMasks|$ExcludeDirs;"" -transfer=binary"` - "call mkdir -p $RemoteWorkingDir/cryptoTools/thirdparty/"` - "call mkdir -p $RemoteWorkingDir/cryptoTools/thirdparty/linux/"` - "synchronize remote $SolutionDir/cryptoTools/thirdparty/linux/ $RemoteWorkingDir/cryptoTools/thirdparty/linux/ -filemask=""**.get|$ExcludeDirs"" -transfer=binary"` - "exit" \ No newline at end of file diff --git a/cryptoTools b/cryptoTools index 924e3280..139a4b0b 160000 --- a/cryptoTools +++ b/cryptoTools @@ -1 +1 @@ -Subproject commit 924e328071b8c0616df01a233705702a7f6df2c3 +Subproject commit 139a4b0b53d2f2ed0bee53f8e9e6775d141ddb50 diff --git a/frontend/ExampleBase.h b/frontend/ExampleBase.h new file mode 100644 index 00000000..83e4c93c --- /dev/null +++ b/frontend/ExampleBase.h @@ -0,0 +1,77 @@ +#pragma once + +#include "libOTe/Base/SimplestOT.h" +#include "libOTe/Base/McRosRoyTwist.h" +#include "libOTe/Base/McRosRoy.h" +#include "libOTe/Tools/Popf/EKEPopf.h" +#include "libOTe/Tools/Popf/MRPopf.h" +#include "libOTe/Tools/Popf/FeistelPopf.h" +#include "libOTe/Tools/Popf/FeistelMulPopf.h" +#include "libOTe/Tools/Popf/FeistelRistPopf.h" +#include "libOTe/Tools/Popf/FeistelMulRistPopf.h" +#include "libOTe/Base/MasnyRindal.h" +#include "libOTe/Base/MasnyRindalKyber.h" +#include "libOTe/Base/naor-pinkas.h" + +#include "cryptoTools/Common/BitVector.h" + +namespace osuCrypto +{ + + template + void baseOT_example_from_ot(Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP&, BaseOT ot) + { + IOService ios; + PRNG prng(sysRandomSeed()); + + if (totalOTs == 0) + totalOTs = 128; + + if (numThreads > 1) + std::cout << "multi threading for the base OT example is not implemented.\n" << std::flush; + + Timer t; + Timer::timeUnit s; + if (role == Role::Receiver) + { + auto chl0 = Session(ios, ip, SessionMode::Server).addChannel(); + chl0.waitForConnection(); + BaseOT recv = ot; + + std::vector msg(totalOTs); + BitVector choice(totalOTs); + choice.randomize(prng); + + + s = t.setTimePoint("base OT start"); + + recv.receive(choice, msg, prng, chl0); + } + else + { + + auto chl1 = Session(ios, ip, SessionMode::Client).addChannel(); + chl1.waitForConnection(); + + BaseOT send = ot; + + std::vector> msg(totalOTs); + + s = t.setTimePoint("base OT start"); + + send.send(msg, prng, chl1); + } + + auto e = t.setTimePoint("base OT end"); + auto milli = std::chrono::duration_cast(e - s).count(); + + std::cout << tag << (role == Role::Receiver ? " (receiver)" : " (sender)") + << " n=" << totalOTs << " " << milli << " ms" << std::endl; + } + + template + void baseOT_example(Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP& clp) + { + return baseOT_example_from_ot(role, totalOTs, numThreads, ip, tag, clp, BaseOT()); + } +} diff --git a/frontend/ExampleNChooseOne.h b/frontend/ExampleNChooseOne.h new file mode 100644 index 00000000..d08fdb4a --- /dev/null +++ b/frontend/ExampleNChooseOne.h @@ -0,0 +1,235 @@ +#pragma once + + +#include "cryptoTools/Common/Matrix.h" +#include "libOTe/NChooseOne/Oos/OosNcoOtReceiver.h" +#include "libOTe/NChooseOne/Oos/OosNcoOtSender.h" +#include "libOTe/NChooseOne/Kkrt/KkrtNcoOtReceiver.h" +#include "libOTe/NChooseOne/Kkrt/KkrtNcoOtSender.h" +#include "cryptoTools/Common/Matrix.h" + +namespace osuCrypto +{ + + + + + + template + void NChooseOne_example(Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP&) + { + const u64 step = 1024; + + if (totalOTs == 0) + totalOTs = 1 << 20; + + bool randomOT = true; + auto numOTs = totalOTs / numThreads; + auto numChosenMsgs = 256; + + // get up the networking + auto rr = role == Role::Sender ? SessionMode::Server : SessionMode::Client; + IOService ios; + Session ep0(ios, ip, rr); + PRNG prng(sysRandomSeed()); + + // for each thread we need to construct a channel (socket) for it to communicate on. + std::vector chls(numThreads); + for (int i = 0; i < numThreads; ++i) + chls[i] = ep0.addChannel(); + + std::vector recvers(numThreads); + std::vector senders(numThreads); + + // all Nco Ot extenders must have configure called first. This determines + // a variety of parameters such as how many base OTs are required. + bool maliciousSecure = false; + u64 statSecParam = 40; + u64 inputBitCount = 76; // the kkrt protocol default to 128 but oos can only do 76. + recvers[0].configure(maliciousSecure, statSecParam, inputBitCount); + senders[0].configure(maliciousSecure, statSecParam, inputBitCount); + + // Generate new base OTs for the first extender. This will use + // the default BaseOT protocol. You can also manually set the + // base OTs with setBaseOts(...); + if (role == Role::Sender) + senders[0].genBaseOts(prng, chls[0]); + else + recvers[0].genBaseOts(prng, chls[0]); + + // now that we have one valid pair of extenders, we can call split on + // them to get more copies which can be used concurrently. + for (int i = 1; i < numThreads; ++i) + { + recvers[i] = recvers[0].splitBase(); + senders[i] = senders[0].splitBase(); + } + + // create a lambda function that performs the computation of a single receiver thread. + auto recvRoutine = [&](int k) + { + auto& chl = chls[k]; + PRNG prng(sysRandomSeed()); + + if (randomOT) + { + // once configure(...) and setBaseOts(...) are called, + // we can compute many batches of OTs. First we need to tell + // the instance how mant OTs we want in this batch. This is done here. + recvers[k].init(numOTs, prng, chl); + + // now we can iterate over the OTs and actaully retreive the desired + // messages. However, for efficieny we will do this in steps where + // we do some computation followed by sending off data. This is more + // efficient since data will be sent in the background :). + for (int i = 0; i < numOTs; ) + { + // figure out how many OTs we want to do in this step. + auto min = std::min(numOTs - i, step); + i += min; + + //// iterate over this step. + //for (u64 j = 0; j < min; ++j, ++i) + //{ + // // For the OT index by i, we need to pick which + // // one of the N OT messages that we want. For this + // // example we simply pick a random one. Note only the + // // first log2(N) bits of choice is considered. + // block choice = prng.get(); + + // // this will hold the (random) OT message of our choice + // block otMessage; + + // // retreive the desired message. + // recvers[k].encode(i, &choice, &otMessage); + + // // do something cool with otMessage + // //otMessage; + //} + + // Note that all OTs in this region must be encode. If there are some + // that you don't actually care about, then you can skip them by calling + // + // recvers[k].zeroEncode(i); + // + + // Now that we have gotten out the OT messages for this step, + // we are ready to send over network some information that + // allows the sender to also compute the OT messages. Since we just + // encoded "min" OT messages, we will tell the class to send the + // next min "correction" values. + recvers[k].sendCorrection(chl, min); + } + + // once all numOTs have been encoded and had their correction values sent + // we must call check. This allows to sender to make sure we did not cheat. + // For semi-honest protocols, this can and will be skipped. + recvers[k].check(chl, ZeroBlock); + + } + else + { + std::vectorrecvMsgs(numOTs); + std::vector choices(numOTs); + + // define which messages the receiver should learn. + for (int i = 0; i < numOTs; ++i) + choices[i] = prng.get(); + + // the messages that were learned are written to recvMsgs. + recvers[k].receiveChosen(numChosenMsgs, recvMsgs, choices, prng, chl); + } + }; + + // create a lambda function that performs the computation of a single sender thread. + auto sendRoutine = [&](int k) + { + auto& chl = chls[k]; + PRNG prng(sysRandomSeed()); + + if (randomOT) + { + // Same explanation as above. + senders[k].init(numOTs, prng, chl); + + // Same explanation as above. + for (int i = 0; i < numOTs; ) + { + // Same explanation as above. + auto min = std::min(numOTs - i, step); + + // unlike for the receiver, before we call encode to get + // some desired OT message, we must call recvCorrection(...). + // This receivers some information that the receiver had sent + // and allows the sender to compute any OT message that they desired. + // Note that the step size must match what the receiver used. + // If this is unknown you can use recvCorrection(chl) -> u64 + // which will tell you how many were sent. + senders[k].recvCorrection(chl, min); + i += min; + //// we now encode any OT message with index less that i + min. + //for (u64 j = 0; j < min; ++j, ++i) + //{ + // // in particular, the sender can retreive many OT messages + // // at a single index, in this case we chose to retreive 3 + // // but that is arbitrary. + // auto choice0 = prng.get(); + // auto choice1 = prng.get(); + // auto choice2 = prng.get(); + + // // these we hold the actual OT messages. + // block + // otMessage0, + // otMessage1, + // otMessage2; + + // // now retreive the messages + // senders[k].encode(i, &choice0, &otMessage0); + // senders[k].encode(i, &choice1, &otMessage1); + // senders[k].encode(i, &choice2, &otMessage2); + //} + } + + // This call is required to make sure the receiver did not cheat. + // All corrections must be recieved before this is called. + senders[k].check(chl, ZeroBlock); + } + else + { + // populate this with the messages that you want to send. + Matrix sendMessages(numOTs, numChosenMsgs); + prng.get(sendMessages.data(), sendMessages.size()); + + // perform the OTs with the given messages. + senders[k].sendChosen(sendMessages, prng, chl); + } + }; + + + std::vector thds(numThreads); + std::function routine; + + if (role == Role::Sender) + routine = sendRoutine; + else + routine = recvRoutine; + + + Timer time; + auto s = time.setTimePoint("start"); + + for (int k = 0; k < numThreads; ++k) + thds[k] = std::thread(routine, k); + + + for (int k = 0; k < numThreads; ++k) + thds[k].join(); + + auto e = time.setTimePoint("finish"); + auto milli = std::chrono::duration_cast(e - s).count(); + + if (role == Role::Sender) + std::cout << tag << " n=" << totalOTs << " " << milli << " ms " << (chls[0].getTotalDataRecv() + chls[0].getTotalDataSent()) * chls.size() << std::endl; + } + +} diff --git a/frontend/ExampleSilent.h b/frontend/ExampleSilent.h new file mode 100644 index 00000000..0ce34954 --- /dev/null +++ b/frontend/ExampleSilent.h @@ -0,0 +1,265 @@ +#pragma once + +#include "libOTe/TwoChooseOne/SilentOtExtReceiver.h" +#include "libOTe/TwoChooseOne/SilentOtExtSender.h" +#include "util.h" +#include + +#include "cryptoTools/Network/IOService.h" + +namespace osuCrypto +{ + + void Silent_example(Role role, u64 numOTs, u64 numThreads, std::string ip, std::string tag, CLP& cmd) + { +#ifdef ENABLE_SILENTOT + + if (numOTs == 0) + numOTs = 1 << 20; + + numOTs = numOTs / numThreads; + + + // get up the networking + auto rr = role == Role::Sender ? SessionMode::Server : SessionMode::Client; + IOService ios; + Session ep0(ios, ip, rr); + PRNG prng(sysRandomSeed()); + + // for each thread we need to construct a channel (socket) for it to communicate on. + std::vector chls(numThreads); + for (u64 i = 0; i < numThreads; ++i) + chls[i] = ep0.addChannel(); + + //bool mal = cmd.isSet("mal"); + SilentOtExtSender sender; + SilentOtExtReceiver receiver; + + //auto otType = cmd.isSet("noHash") ? + // OTType::Correlated : + // OTType::Random; + + bool fakeBase = cmd.isSet("fakeBase"); + + gTimer.setTimePoint("begin"); + + auto routine = [&](int i, int s, SilentBaseType type) + { + Timer timer; + u64 milli=0; + try { + + if (i != 0) + throw RTE_LOC; + + // get a random number generator seeded from the system + PRNG prng(sysRandomSeed()); + PRNG pp(ZeroBlock); + + + if (role == Role::Receiver) + { + gTimer.setTimePoint("recver.thrd.begin"); + + // construct the choices that we want. + BitVector choice(numOTs); + gTimer.setTimePoint("recver.msg.alloc0"); + + // construct a vector to stored the received messages. + //std::vector msgs(numOTs); + //std::unique_ptr backing(new block[numOTs]); + //span msgs(backing.get(), numOTs); + gTimer.setTimePoint("recver.msg.alloc1"); + + + receiver.configure(numOTs, s, 1); + gTimer.setTimePoint("recver.config"); + + //sync(chls[0], role); + if (fakeBase) + { + auto nn = receiver.baseOtCount(); + std::vector> baseSendMsgs(nn); + pp.get(baseSendMsgs.data(), baseSendMsgs.size()); + receiver.setBaseOts(baseSendMsgs, prng, chls[0]); + } + + gTimer.setTimePoint("recver.genBase"); + sync(chls[i], role); + + auto b = timer.setTimePoint("start"); + receiver.setTimePoint("start"); + // perform numOTs random OTs, the results will be written to msgs. + receiver.silentReceiveInplace(numOTs, prng, chls[i]); + + receiver.setTimePoint("finish"); + auto e = timer.setTimePoint("finish"); + milli = std::chrono::duration_cast(e - b).count(); + } + else + { + gTimer.setTimePoint("sender.thrd.begin"); + + //std::vector> msgs(numOTs); + //std::unique_ptr backing(new block[deltaOT ? numOTs : numOTs * 2]); + //MatrixView msgs(backing.get(), numOTs, deltaOT ? 1 : 2); + gTimer.setTimePoint("sender.msg.alloc"); + + block delta = prng.get(); + + sender.configure(numOTs, s, 1); + gTimer.setTimePoint("sender.config"); + + + //sync(chls[0], role); + if (fakeBase) + { + auto nn = sender.baseOtCount(); + BitVector bits(nn); + bits.randomize(prng); + std::vector> baseSendMsgs(bits.size()); + std::vector baseRecvMsgs(bits.size()); + pp.get(baseSendMsgs.data(), baseSendMsgs.size()); + for (u64 i = 0; i < bits.size(); ++i) + baseRecvMsgs[i] = baseSendMsgs[i][bits[i]]; + sender.setBaseOts(baseRecvMsgs, bits, chls[0]); + } + + gTimer.setTimePoint("sender.genBase"); + + // construct a vector to stored the random send messages. + + // if delta OT is used, then the user can call the following + // to set the desired XOR difference between the zero messages + // and the one messages. + // + // senders[i].setDelta(some 128 bit delta); + // + sync(chls[i], role); + + sender.setTimePoint("start"); + auto b = timer.setTimePoint("start"); + // perform the OTs and write the random OTs to msgs. + sender.silentSendInplace(delta, numOTs, prng, chls[i]); + + sender.setTimePoint("finish"); + auto e = timer.setTimePoint("finish"); + milli = std::chrono::duration_cast(e - b).count(); + + } + } + catch (std::exception& e) + { + std::cout << e.what() << std::endl; + } + catch (...) + { + std::cout << "unknown exception" << std::endl; + + } + return milli; + }; + + cmd.setDefault("s", "2"); + cmd.setDefault("sec", "128"); + auto mulType = (MultType)cmd.getOr("multType", (int)MultType::QuasiCyclic); + std::vector ss = cmd.getMany("s"); + //std::vector secs = cmd.getMany("sec"); + int sec = 128; + u64 trials = cmd.getOr("trials", 1); + std::vector< SilentBaseType> types; + + receiver.mMultType = mulType; + sender.mMultType = mulType; + + + if (cmd.isSet("base")) + types.push_back(SilentBaseType::Base); + else if (cmd.isSet("baseExtend")) + types.push_back(SilentBaseType::BaseExtend); + else + types.push_back(SilentBaseType::BaseExtend); + //if (cmd.isSet("extend")) + // types.push_back(SilentBaseType::Extend); + //if (types.size() == 0 || cmd.isSet("none")) + // types.push_back(SilentBaseType::None); + + + for (auto s : ss) + for (auto type : types) + { + for (u64 tt = 0; tt < trials; ++tt) + { + + chls[0].resetStats(); + + Timer sendTimer, recvTimer; + + sendTimer.setTimePoint("start"); + recvTimer.setTimePoint("start"); + + sender.setTimer(sendTimer); + receiver.setTimer(recvTimer); + + + std::vector thrds; + for (u64 i = 1; i < numThreads; ++i) + thrds.emplace_back(routine, (int)i, (int)s, type); + + auto milli = routine(0, s, type); + + for (auto& tt : thrds) + tt.join(); + + u64 com = 0; + for (auto& c : chls) + com += (c.getTotalDataRecv() + c.getTotalDataSent()); + + std::string typeStr = "n "; + switch (type) + { + case SilentBaseType::Base: + typeStr = "b "; + break; + //case SilentBaseType::Extend: + // typeStr = "e "; + // break; + case SilentBaseType::BaseExtend: + typeStr = "be"; + break; + default: + break; + } + if (role == Role::Sender) + { + + lout << tag << + " n:" << Color::Green << std::setw(6) << std::setfill(' ') << numOTs << Color::Default << + " type: " << Color::Green << typeStr << Color::Default << + " sec: " << Color::Green << std::setw(3) << std::setfill(' ') << sec << Color::Default << + " s: " << Color::Green << s << Color::Default << + " || " << Color::Green << + std::setw(6) << std::setfill(' ') << milli << " ms " << + std::setw(6) << std::setfill(' ') << com << " bytes" << std::endl << Color::Default; + + if (cmd.getOr("v", 0) > 1) + lout << gTimer << std::endl; + + } + if (cmd.isSet("v")) + { + if (role == Role::Sender) + lout << " **** sender ****\n" << sendTimer << std::endl; + + if (role == Role::Receiver) + lout << " **** receiver ****\n" << recvTimer << std::endl; + } + } + + } + +#endif + } + + +} \ No newline at end of file diff --git a/frontend/ExampleTwoChooseOne.h b/frontend/ExampleTwoChooseOne.h new file mode 100644 index 00000000..83009dab --- /dev/null +++ b/frontend/ExampleTwoChooseOne.h @@ -0,0 +1,217 @@ +#pragma once + +#include "libOTe/Base/BaseOT.h" +#include "libOTe/TwoChooseOne/KosOtExtReceiver.h" +#include "libOTe/TwoChooseOne/KosOtExtSender.h" +#include "libOTe/TwoChooseOne/KosDotExtReceiver.h" +#include "libOTe/TwoChooseOne/KosDotExtSender.h" +#include "libOTe/TwoChooseOne/IknpOtExtReceiver.h" +#include "libOTe/TwoChooseOne/IknpOtExtSender.h" + + +#include "libOTe/TwoChooseOne/SilentOtExtReceiver.h" +#include "libOTe/TwoChooseOne/SilentOtExtSender.h" + +namespace osuCrypto +{ + +#ifdef ENABLE_IKNP + void noHash(IknpOtExtSender& s, IknpOtExtReceiver& r) + { + s.mHash = false; + r.mHash = false; + } +#endif + + template + void noHash(Sender&, Receiver&) + { + throw std::runtime_error("This protocol does not support noHash"); + } + + template + void TwoChooseOne_example(Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP& cmd) + { + if (totalOTs == 0) + totalOTs = 1 << 20; + + bool randomOT = true; + + auto numOTs = totalOTs / numThreads; + u64 trials = cmd.getOr("trials", 1); + + // get up the networking + auto rr = role == Role::Sender ? SessionMode::Server : SessionMode::Client; + IOService ios; + Session ep0(ios, ip, rr); + PRNG prng(sysRandomSeed()); + + // for each thread we need to construct a channel (socket) for it to communicate on. + std::vector chls(numThreads); + for (int i = 0; i < numThreads; ++i) + chls[i] = ep0.addChannel(); + + + + std::vector senders(numThreads); + std::vector receivers(numThreads); + +#ifdef LIBOTE_HAS_BASE_OT + // Now compute the base OTs, we need to set them on the first pair of extenders. + // In real code you would only have a sender or reciever, not both. But we do + // here just showing the example. + if (role == Role::Receiver) + { + DefaultBaseOT base; + std::array, 128> baseMsg; + base.send(baseMsg, prng, chls[0], numThreads); + receivers[0].setBaseOts(baseMsg, prng, chls[0]); + + //receivers[0].genBaseOts(prng, chls[0]); + } + else + { + + DefaultBaseOT base; + BitVector bv(128); + std::array baseMsg; + bv.randomize(prng); + base.receive(bv, baseMsg, prng, chls[0], numThreads); + senders[0].setBaseOts(baseMsg, bv, chls[0]); + } +#else + if (!cmd.isSet("fakeBase")) + std::cout << "warning, base ots are not enabled. Fake base OTs will be used. " << std::endl; + PRNG commonPRNG(oc::ZeroBlock); + std::array, 128> sendMsgs; + commonPRNG.get(sendMsgs.data(), sendMsgs.size()); + if (role == Role::Receiver) + { + receivers[0].setBaseOts(sendMsgs, prng, chls[0]); + } + else + { + BitVector bv(128); + bv.randomize(commonPRNG); + std::array recvMsgs; + for (u64 i = 0; i < 128; ++i) + recvMsgs[i] = sendMsgs[i][bv[i]]; + senders[0].setBaseOts(recvMsgs, bv, chls[0]); + } +#endif + + // for the rest of the extenders, call split. This securely + // creates two sets of extenders that can be used in parallel. + for (auto i = 1; i < numThreads; ++i) + { + if (role == Role::Receiver) + receivers[i] = receivers[0].splitBase(); + else + senders[i] = senders[0].splitBase(); + } + + if (cmd.isSet("noHash")) + for (auto i = 0; i < numThreads; ++i) + noHash(senders[i], receivers[i]); + + Timer timer, sendTimer, recvTimer; + sendTimer.setTimePoint("start"); + recvTimer.setTimePoint("start"); + auto routine = [&](int i) + { + // get a random number generator seeded from the system + PRNG prng(sysRandomSeed()); + + // construct a vector to stored the random send messages. + std::vector> sMsgs(numOTs * (role == Role::Sender)); + + // construct the choices that we want. + BitVector choice(numOTs); + // in this case pick random messages. + choice.randomize(prng); + + // construct a vector to stored the received messages. + std::vector rMsgs(numOTs * (role != Role::Sender)); + + for (u64 tt = 0; tt < trials; ++tt) + { + + timer.reset(); + auto s = timer.setTimePoint("start"); + + if (role == Role::Receiver) + { + + if (randomOT) + { + // perform numOTs random OTs, the results will be written to msgs. + receivers[i].receive(choice, rMsgs, prng, chls[i]); + } + else + { + // perform numOTs chosen message OTs, the results will be written to msgs. + receivers[i].receiveChosen(choice, rMsgs, prng, chls[i]); + } + } + else + { + + // if delta OT is used, then the user can call the following + // to set the desired XOR difference between the zero messages + // and the one messages. + // + // senders[i].setDelta(some 128 bit delta); + // + + if (randomOT) + { + // perform the OTs and write the random OTs to msgs. + senders[i].send(sMsgs, prng, chls[i]); + } + else + { + // Populate msgs with something useful... + prng.get(sMsgs.data(), sMsgs.size()); + + // perform the OTs. The receiver will learn one + // of the messages stored in msgs. + senders[i].sendChosen(sMsgs, prng, chls[i]); + } + } + + auto e = timer.setTimePoint("finish"); + auto milli = std::chrono::duration_cast(e - s).count(); + + auto com = (chls[0].getTotalDataRecv() + chls[0].getTotalDataSent()) * numThreads; + + if (role == Role::Sender && i == 0) + lout << tag << " n=" << Color::Green << totalOTs << " " << milli << " ms " << com << " bytes" << std::endl << Color::Default; + + } + + if (cmd.isSet("v") && role == Role::Sender && i == 0) + { + if (role == Role::Sender) + lout << " **** sender ****\n" << sendTimer << std::endl; + + if (role == Role::Receiver) + lout << " **** receiver ****\n" << recvTimer << std::endl; + } + + }; + + senders[0].setTimer(sendTimer); + receivers[0].setTimer(recvTimer); + + std::vector thrds(numThreads); + for (int i = 0; i < numThreads; ++i) + thrds[i] = std::thread(routine, i); + + for (int i = 0; i < numThreads; ++i) + thrds[i].join(); + + + } + + +} diff --git a/frontend/benchmark.h b/frontend/benchmark.h new file mode 100644 index 00000000..90fe90f1 --- /dev/null +++ b/frontend/benchmark.h @@ -0,0 +1,84 @@ +#include "cryptoTools/Common/CLP.h" + +namespace osuCrypto +{ + + //inline void encodeBench(CLP& cmd) + //{ + // u64 mm = cmd.getOr("r", 100000); + // u64 w = cmd.getOr("w", 5); + // auto gap = cmd.getOr("g", 16); + // LdpcDiagRegRepeaterEncoder::Code code; + // if (w == 11) + // code = LdpcDiagRegRepeaterEncoder::Weight11; + // else if (w == 5) + // code = LdpcDiagRegRepeaterEncoder::Weight5; + // else + // throw RTE_LOC; + + // u64 colWeight = w; + // u64 diags = w; + // u64 gapWeight = w; + // u64 period = mm; + // std::vector db{ 5,31 }; + // PRNG pp(oc::ZeroBlock); + // u64 trials = cmd.getOr("t", 10); + + + // PRNG prng(ZeroBlock); + + + // LdpcEncoder TZ; + // TZ.init(sampleTriangularBand(mm, mm * 2, w, 1, 2, 0, 0, 0, {}, true, true, false, prng, prng), 0); + + + // //auto H = sampleRegTriangularBand(mm, mm, colWeight, gap, gapWeight, diags, 0,0, {}, true, false, false, prng); + // ////std::cout << H << std::endl; + // //return; + // S1DiagRepEncoder mZpsDiagEncoder; + // mZpsDiagEncoder.mL.init(mm, colWeight); + // mZpsDiagEncoder.mR.init(mm, gap, gapWeight, period, db, true, pp); + + + // std::vector x(mZpsDiagEncoder.cols()); + // Timer timer; + + + + + // S1DiagRegRepEncoder enc2; + // enc2.mL.init(mm, colWeight); + // enc2.mR.init(mm, code, true); + + // //mZpsDiagEncoder.setTimer(timer); + // //enc2.setTimer(timer); + // timer.setTimePoint("_____________________"); + + // for (u64 i = 0; i < trials; ++i) + // { + // TZ.cirTransEncode(x); + // timer.setTimePoint("tz"); + // } + // timer.setTimePoint("_____________________"); + + // for (u64 i = 0; i < trials; ++i) + // { + + // mZpsDiagEncoder.cirTransEncode(x); + // timer.setTimePoint("a"); + // } + + + // timer.setTimePoint("_____________________"); + // for (u64 i = 0; i < trials; ++i) + // { + + // enc2.cirTransEncode(x); + // timer.setTimePoint("b"); + + // } + + // std::cout << timer << std::endl; + //} + +} \ No newline at end of file diff --git a/frontend/frontend.vcxproj b/frontend/frontend.vcxproj deleted file mode 100644 index d0f2c7f7..00000000 --- a/frontend/frontend.vcxproj +++ /dev/null @@ -1,162 +0,0 @@ - - - - - Debug_DLLRT - x64 - - - Debug - x64 - - - Release_DLLRT - x64 - - - Release - x64 - - - - {C81DC04B-A0F0-4B77-8DCE-C8190E629467} - frontend - 10.0 - - - - Application - true - v142 - MultiByte - - - Application - true - v142 - MultiByte - - - Application - false - v142 - true - MultiByte - - - Application - false - v142 - true - MultiByte - - - - - - - - - - - - - - - - - - - - - false - - - false - - - - Level3 - Disabled - true - $(SolutionDir);$(SolutionDir)/cryptoTools/;$(SolutionDir)/cryptoTools/thirdparty\win\boost\;$(SolutionDir)/cryptoTools/thirdparty\win\;$(SolutionDir)/cryptoTools/thirdparty/win/NTL/include;$(SolutionDir)/cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/NTL/include;C:/libs/miracl - MultiThreadedDebug - SOLUTION_DIR=R"**($(SolutionDir))**";_WIN32_WINNT=0x0501 ;_MBCS;%(PreprocessorDefinitions) - true - true - - - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(ProjectDir)..\cryptoTools\thirdparty\win\boost\stage\lib;C:/libs/boost\stage\lib;$(OutDir);$(ProjectDir)..\cryptoTools/thirdparty\win\;$(ProjectDir)..\cryptoTools/thirdparty\win/Miracl/x64/$(Configuration);C:/libs/;C:\libs\lib;C:/libs/Miracl/x64/$(Configuration);$(SolutionDir)../bitpolymul2/lib/$(Configuration) - tests_cryptoTools.lib;cryptoTools.lib;libOTe.lib;libOTe_Tests.lib;%(AdditionalDependencies) - - - - - Level3 - Disabled - true - $(SolutionDir);$(SolutionDir)/cryptoTools/;$(SolutionDir)/cryptoTools/thirdparty\win\boost\;$(SolutionDir)/cryptoTools/thirdparty\win\;$(SolutionDir)/cryptoTools/thirdparty/win/NTL/include;$(SolutionDir)/cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/NTL/include;C:/libs/miracl - MultiThreadedDebugDLL - SOLUTION_DIR=R"**($(SolutionDir))**";_WIN32_WINNT=0x0501 ;_MBCS;%(PreprocessorDefinitions) - true - true - - - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(ProjectDir)..\cryptoTools\thirdparty\win\boost\stage\lib;C:/libs/boost\stage\lib;$(OutDir);$(ProjectDir)..\cryptoTools/thirdparty\win\;$(ProjectDir)..\cryptoTools/thirdparty\win/Miracl/x64/$(Configuration);C:/libs/;C:\libs\lib;C:/libs/Miracl/x64/$(Configuration);$(SolutionDir)../bitpolymul2/lib/$(Configuration) - tests_cryptoTools.lib;cryptoTools.lib;libOTe.lib;libOTe_Tests.lib;%(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir);$(SolutionDir)/cryptoTools/;$(SolutionDir)/cryptoTools/thirdparty\win\boost\;$(SolutionDir)/cryptoTools/thirdparty\win\;$(SolutionDir)/cryptoTools/thirdparty/win/NTL/include;$(SolutionDir)/cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/NTL/include;C:/libs/miracl - MultiThreaded - SOLUTION_DIR=R"**($(SolutionDir))**";_WIN32_WINNT=0x0501 ;_MBCS;%(PreprocessorDefinitions) - true - true - - - true - true - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(ProjectDir)..\cryptoTools\thirdparty\win\boost\stage\lib;C:/libs/boost\stage\lib;$(OutDir);$(ProjectDir)..\cryptoTools/thirdparty\win\;$(ProjectDir)..\cryptoTools/thirdparty\win/Miracl/x64/$(Configuration);C:/libs/;C:\libs\lib;C:/libs/Miracl/x64/$(Configuration);$(SolutionDir)../bitpolymul2/lib/$(Configuration) - tests_cryptoTools.lib;cryptoTools.lib;libOTe.lib;libOTe_Tests.lib;%(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir);$(SolutionDir)/cryptoTools/;$(SolutionDir)/cryptoTools/thirdparty\win\boost\;$(SolutionDir)/cryptoTools/thirdparty\win\;$(SolutionDir)/cryptoTools/thirdparty/win/NTL/include;$(SolutionDir)/cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/NTL/include;C:/libs/miracl - MultiThreadedDLL - SOLUTION_DIR=R"**($(SolutionDir))**";_WIN32_WINNT=0x0501 ;_MBCS;%(PreprocessorDefinitions) - true - true - - - true - true - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(ProjectDir)..\cryptoTools\thirdparty\win\boost\stage\lib;C:/libs/boost\stage\lib;$(OutDir);$(ProjectDir)..\cryptoTools/thirdparty\win\;$(ProjectDir)..\cryptoTools/thirdparty\win/Miracl/x64/$(Configuration);C:/libs/;C:\libs\lib;C:/libs/Miracl/x64/$(Configuration);$(SolutionDir)../bitpolymul2/lib/$(Configuration) - tests_cryptoTools.lib;cryptoTools.lib;libOTe.lib;libOTe_Tests.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/frontend/frontend.vcxproj.filters b/frontend/frontend.vcxproj.filters deleted file mode 100644 index 30d7070f..00000000 --- a/frontend/frontend.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - Source Files - - - - - Header Files - - - - - - \ No newline at end of file diff --git a/frontend/main.cpp b/frontend/main.cpp index 71100981..e0bf5841 100644 --- a/frontend/main.cpp +++ b/frontend/main.cpp @@ -1,903 +1,261 @@ -#include - -//using namespace std; -#include "tests_cryptoTools/UnitTests.h" -#include "libOTe_Tests/UnitTests.h" - -#include -using namespace osuCrypto; - - -#include -#include -#include -#include -#include -#include -#include -#include -int miraclTestMain(); -#include - -#include "libOTe/TwoChooseOne/KosOtExtReceiver.h" -#include "libOTe/TwoChooseOne/KosOtExtSender.h" -#include "libOTe/TwoChooseOne/KosDotExtReceiver.h" -#include "libOTe/TwoChooseOne/KosDotExtSender.h" -#include "libOTe/TwoChooseOne/IknpOtExtReceiver.h" -#include "libOTe/TwoChooseOne/IknpOtExtSender.h" -#include "libOTe/TwoChooseOne/IknpDotExtReceiver.h" -#include "libOTe/TwoChooseOne/IknpDotExtSender.h" - -#include "libOTe/NChooseOne/Oos/OosNcoOtReceiver.h" -#include "libOTe/NChooseOne/Oos/OosNcoOtSender.h" -#include "libOTe/NChooseOne/Kkrt/KkrtNcoOtReceiver.h" -#include "libOTe/NChooseOne/Kkrt/KkrtNcoOtSender.h" - -#include "libOTe/TwoChooseOne/SilentOtExtReceiver.h" -#include "libOTe/TwoChooseOne/SilentOtExtSender.h" - -#include "libOTe/NChooseK/AknOtReceiver.h" -#include "libOTe/NChooseK/AknOtSender.h" - -#include -#include "util.h" -#include -#include - -#include "libOTe/Base/SimplestOT.h" -#include "libOTe/Base/MasnyRindal.h" -#include "libOTe/Base/MasnyRindalKyber.h" -#include "libOTe/Base/naor-pinkas.h" - - - -template -void NChooseOne_example(Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP&) -{ - const u64 step = 1024; - - if (totalOTs == 0) - totalOTs = 1 << 20; - - bool randomOT = true; - auto numOTs = totalOTs / numThreads; - auto numChosenMsgs = 256; - - // get up the networking - auto rr = role == Role::Sender ? SessionMode::Server : SessionMode::Client; - IOService ios; - Session ep0(ios, ip, rr); - PRNG prng(sysRandomSeed()); - - // for each thread we need to construct a channel (socket) for it to communicate on. - std::vector chls(numThreads); - for (int i = 0; i < numThreads; ++i) - chls[i] = ep0.addChannel(); - - std::vector recvers(numThreads); - std::vector senders(numThreads); - - // all Nco Ot extenders must have configure called first. This determines - // a variety of parameters such as how many base OTs are required. - bool maliciousSecure = false; - u64 statSecParam = 40; - u64 inputBitCount = 76; // the kkrt protocol default to 128 but oos can only do 76. - recvers[0].configure(maliciousSecure, statSecParam, inputBitCount); - senders[0].configure(maliciousSecure, statSecParam, inputBitCount); - - // Generate new base OTs for the first extender. This will use - // the default BaseOT protocol. You can also manually set the - // base OTs with setBaseOts(...); - if (role == Role::Sender) - senders[0].genBaseOts(prng, chls[0]); - else - recvers[0].genBaseOts(prng, chls[0]); - - // now that we have one valid pair of extenders, we can call split on - // them to get more copies which can be used concurrently. - for (int i = 1; i < numThreads; ++i) - { - recvers[i] = recvers[0].splitBase(); - senders[i] = senders[0].splitBase(); - } - - // create a lambda function that performs the computation of a single receiver thread. - auto recvRoutine = [&](int k) - { - auto& chl = chls[k]; - PRNG prng(sysRandomSeed()); - - if (randomOT) - { - // once configure(...) and setBaseOts(...) are called, - // we can compute many batches of OTs. First we need to tell - // the instance how mant OTs we want in this batch. This is done here. - recvers[k].init(numOTs, prng, chl); - - // now we can iterate over the OTs and actaully retreive the desired - // messages. However, for efficieny we will do this in steps where - // we do some computation followed by sending off data. This is more - // efficient since data will be sent in the background :). - for (int i = 0; i < numOTs; ) - { - // figure out how many OTs we want to do in this step. - auto min = std::min(numOTs - i, step); - - // iterate over this step. - for (u64 j = 0; j < min; ++j, ++i) - { - // For the OT index by i, we need to pick which - // one of the N OT messages that we want. For this - // example we simply pick a random one. Note only the - // first log2(N) bits of choice is considered. - block choice = prng.get(); - - // this will hold the (random) OT message of our choice - block otMessage; - - // retreive the desired message. - recvers[k].encode(i, &choice, &otMessage); - - // do something cool with otMessage - //otMessage; - } - - // Note that all OTs in this region must be encode. If there are some - // that you don't actually care about, then you can skip them by calling - // - // recvers[k].zeroEncode(i); - // - - // Now that we have gotten out the OT messages for this step, - // we are ready to send over network some information that - // allows the sender to also compute the OT messages. Since we just - // encoded "min" OT messages, we will tell the class to send the - // next min "correction" values. - recvers[k].sendCorrection(chl, min); - } - - // once all numOTs have been encoded and had their correction values sent - // we must call check. This allows to sender to make sure we did not cheat. - // For semi-honest protocols, this can and will be skipped. - recvers[k].check(chl, ZeroBlock); - - } - else - { - std::vectorrecvMsgs(numOTs); - std::vector choices(numOTs); - - // define which messages the receiver should learn. - for (int i = 0; i < numOTs; ++i) - choices[i] = prng.get(); - - // the messages that were learned are written to recvMsgs. - recvers[k].receiveChosen(numChosenMsgs, recvMsgs, choices, prng, chl); - } - }; - - // create a lambda function that performs the computation of a single sender thread. - auto sendRoutine = [&](int k) - { - auto& chl = chls[k]; - PRNG prng(sysRandomSeed()); - - if (randomOT) - { - - // Same explanation as above. - senders[k].init(numOTs, prng, chl); - - // Same explanation as above. - for (int i = 0; i < numOTs; ) - { - // Same explanation as above. - auto min = std::min(numOTs - i, step); - - // unlike for the receiver, before we call encode to get - // some desired OT message, we must call recvCorrection(...). - // This receivers some information that the receiver had sent - // and allows the sender to compute any OT message that they desired. - // Note that the step size must match what the receiver used. - // If this is unknown you can use recvCorrection(chl) -> u64 - // which will tell you how many were sent. - senders[k].recvCorrection(chl, min); - - // we now encode any OT message with index less that i + min. - for (u64 j = 0; j < min; ++j, ++i) - { - // in particular, the sender can retreive many OT messages - // at a single index, in this case we chose to retreive 3 - // but that is arbitrary. - auto choice0 = prng.get(); - auto choice1 = prng.get(); - auto choice2 = prng.get(); - - // these we hold the actual OT messages. - block - otMessage0, - otMessage1, - otMessage2; - - // now retreive the messages - senders[k].encode(i, &choice0, &otMessage0); - senders[k].encode(i, &choice1, &otMessage1); - senders[k].encode(i, &choice2, &otMessage2); - } - } - - // This call is required to make sure the receiver did not cheat. - // All corrections must be recieved before this is called. - senders[k].check(chl, ZeroBlock); - } - else - { - // populate this with the messages that you want to send. - Matrix sendMessages(numOTs, numChosenMsgs); - prng.get(sendMessages.data(), sendMessages.size()); - - // perform the OTs with the given messages. - senders[k].sendChosen(sendMessages, prng, chl); - } - }; - - - std::vector thds(numThreads); - std::function routine; - - if (role == Role::Sender) - routine = sendRoutine; - else - routine = recvRoutine; - - - Timer time; - auto s = time.setTimePoint("start"); - - for (int k = 0; k < numThreads; ++k) - thds[k] = std::thread(routine, k); - - - for (int k = 0; k < numThreads; ++k) - thds[k].join(); - - auto e = time.setTimePoint("finish"); - auto milli = std::chrono::duration_cast(e - s).count(); - - if (role == Role::Sender) - std::cout << tag << " n=" << totalOTs << " " << milli << " ms" << std::endl; -} - - -template -void TwoChooseOne_example(Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP & cmd) -{ - if (totalOTs == 0) - totalOTs = 1 << 20; - - bool randomOT = true; - - auto numOTs = totalOTs / numThreads; - - // get up the networking - auto rr = role == Role::Sender ? SessionMode::Server : SessionMode::Client; - IOService ios; - Session ep0(ios, ip, rr); - PRNG prng(sysRandomSeed()); - - // for each thread we need to construct a channel (socket) for it to communicate on. - std::vector chls(numThreads); - for (int i = 0; i < numThreads; ++i) - chls[i] = ep0.addChannel(); - - Timer timer, sendTimer, recvTimer; - timer.reset(); - auto s = timer.setTimePoint("start"); - sendTimer.setTimePoint("start"); - recvTimer.setTimePoint("start"); - - - std::vector senders(numThreads); - std::vector receivers(numThreads); - -#ifdef LIBOTE_HAS_BASE_OT - // Now compute the base OTs, we need to set them on the first pair of extenders. - // In real code you would only have a sender or reciever, not both. But we do - // here just showing the example. - if (role == Role::Receiver) - { - DefaultBaseOT base; - std::array, 128> baseMsg; - base.send(baseMsg, prng, chls[0], numThreads); - receivers[0].setBaseOts(baseMsg, prng, chls[0]); - - //receivers[0].genBaseOts(prng, chls[0]); - } - else - { - - DefaultBaseOT base; - BitVector bv(128); - std::array baseMsg; - bv.randomize(prng); - base.receive(bv, baseMsg, prng, chls[0], numThreads); - senders[0].setBaseOts(baseMsg, bv,chls[0]); - } -#else - std::cout << "warning, base ots are not enabled. Fake base OTs will be used. " << std::endl; - PRNG commonPRNG(oc::ZeroBlock); - std::array, 128> sendMsgs; - commonPRNG.get(sendMsgs.data(), sendMsgs.size()); - if (role == Role::Receiver) - { - receivers[0].setBaseOts(sendMsgs, prng, chls[0]); - } - else - { - BitVector bv(128); - bv.randomize(commonPRNG); - std::array recvMsgs; - for (u64 i = 0; i < 128; ++i) - recvMsgs[i] = sendMsgs[i][bv[i]]; - senders[0].setBaseOts(recvMsgs, bv, chls[0]); - } -#endif - - // for the rest of the extenders, call split. This securely - // creates two sets of extenders that can be used in parallel. - for (auto i = 1; i < numThreads; ++i) - { - if (role == Role::Receiver) - receivers[i] = receivers[0].splitBase(); - else - senders[i] = senders[0].splitBase(); - } - - - auto routine = [&](int i) - { - // get a random number generator seeded from the system - PRNG prng(sysRandomSeed()); - - if (role == Role::Receiver) - { - // construct the choices that we want. - BitVector choice(numOTs); - // in this case pick random messages. - choice.randomize(prng); - - // construct a vector to stored the received messages. - std::vector msgs(numOTs); - - if (randomOT) - { - // perform numOTs random OTs, the results will be written to msgs. - receivers[i].receive(choice, msgs, prng, chls[i]); - } - else - { - // perform numOTs chosen message OTs, the results will be written to msgs. - receivers[i].receiveChosen(choice, msgs, prng, chls[i]); - } - } - else - { - // construct a vector to stored the random send messages. - std::vector> msgs(numOTs); - - // if delta OT is used, then the user can call the following - // to set the desired XOR difference between the zero messages - // and the one messages. - // - // senders[i].setDelta(some 128 bit delta); - // - - if (randomOT) - { - // perform the OTs and write the random OTs to msgs. - senders[i].send(msgs, prng, chls[i]); - } - else - { - // Populate msgs with something useful... - prng.get(msgs.data(), msgs.size()); - - // perform the OTs. The receiver will learn one - // of the messages stored in msgs. - senders[i].sendChosen(msgs, prng, chls[i]); - } - } - }; - - senders[0].setTimer(sendTimer); - receivers[0].setTimer(recvTimer); - - std::vector thrds(numThreads); - for (int i = 0; i < numThreads; ++i) - thrds[i] = std::thread(routine, i); - - for (int i = 0; i < numThreads; ++i) - thrds[i].join(); - - auto e = timer.setTimePoint("finish"); - auto milli = std::chrono::duration_cast(e - s).count(); - - auto com = (chls[0].getTotalDataRecv() + chls[0].getTotalDataSent()) * numThreads; - - if (role == Role::Sender) - lout << tag << " n=" << Color::Green << totalOTs << " " << milli << " ms " << com << " bytes" << std::endl << Color::Default; - - - if (cmd.isSet("v")) - { - if (role == Role::Sender) - lout << " **** sender ****\n" << sendTimer << std::endl; - - if (role == Role::Receiver) - lout << " **** receiver ****\n" << recvTimer << std::endl; - } -} - - -//template -void TwoChooseOneG_example(Role role, int numOTs, int numThreads, std::string ip, std::string tag, CLP & cmd) -{ -#ifdef ENABLE_SILENTOT - - if (numOTs == 0) - numOTs = 1 << 20; - using OtExtSender = SilentOtExtSender; - using OtExtRecver = SilentOtExtReceiver; - - // get up the networking - auto rr = role == Role::Sender ? SessionMode::Server : SessionMode::Client; - IOService ios; - Session ep0(ios, ip, rr); - PRNG prng(sysRandomSeed()); - - // for each thread we need to construct a channel (socket) for it to communicate on. - std::vector chls(numThreads); - for (int i = 0; i < numThreads; ++i) - chls[i] = ep0.addChannel(); - - //bool mal = cmd.isSet("mal"); - OtExtSender sender; - OtExtRecver receiver; - - - auto routine = [&](int s, int sec, SilentBaseType type) - { - // get a random number generator seeded from the system - PRNG prng(sysRandomSeed()); - - sync(chls[0], role); - - if (role == Role::Receiver) - { - // construct the choices that we want. - BitVector choice(numOTs); - // in this case pick random messages. - choice.randomize(prng); - - // construct a vector to stored the received messages. - std::vector msgs(numOTs); - - receiver.genBase(numOTs, chls[0], prng, s, sec, type, chls.size()); - // perform numOTs random OTs, the results will be written to msgs. - receiver.silentReceive(choice, msgs, prng, chls); - } - else - { - std::vector> msgs(numOTs); - - sender.genBase(numOTs, chls[0], prng, s, sec, type, chls.size()); - // construct a vector to stored the random send messages. - - // if delta OT is used, then the user can call the following - // to set the desired XOR difference between the zero messages - // and the one messages. - // - // senders[i].setDelta(some 128 bit delta); - // - - // perform the OTs and write the random OTs to msgs. - sender.silentSend(msgs, prng, chls); - } - }; - - cmd.setDefault("s", "4"); - cmd.setDefault("sec", "80"); - std::vector ss = cmd.getMany("s"); - std::vector secs = cmd.getMany("sec"); - std::vector< SilentBaseType> types; - - if (cmd.isSet("base")) - types.push_back(SilentBaseType::Base); - if (cmd.isSet("baseExtend")) - types.push_back(SilentBaseType::BaseExtend); - //if (cmd.isSet("extend")) - // types.push_back(SilentBaseType::Extend); - //if (types.size() == 0 || cmd.isSet("none")) - // types.push_back(SilentBaseType::None); - - - for (auto s : ss) - for (auto sec : secs) - for (auto type : types) - { - - chls[0].resetStats(); - - Timer timer, sendTimer, recvTimer; - timer.reset(); - auto b = timer.setTimePoint("start"); - sendTimer.setTimePoint("start"); - recvTimer.setTimePoint("start"); - - sender.setTimer(sendTimer); - receiver.setTimer(recvTimer); - - routine(s, sec, type); - - - auto e = timer.setTimePoint("finish"); - auto milli = std::chrono::duration_cast(e - b).count(); - - u64 com = 0; - for(auto &c : chls) - com += (c.getTotalDataRecv() + c.getTotalDataSent()); - - std::string typeStr = "n "; - switch (type) - { - case SilentBaseType::Base: - typeStr = "b "; - break; - //case SilentBaseType::Extend: - // typeStr = "e "; - // break; - case SilentBaseType::BaseExtend: - typeStr = "be"; - break; - default: - break; - } - - - if (role == Role::Sender) - lout << tag << - " n:" << Color::Green << std::setw(6) << std::setfill(' ')< -void baseOT_example(Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP&) -{ - IOService ios; - PRNG prng(sysRandomSeed()); - - if (totalOTs == 0) - totalOTs = 128; - - if (numThreads > 1) - std::cout << "multi threading for the base OT example is not implemented.\n" << std::flush; - - if (role == Role::Receiver) - { - auto chl0 = Session(ios, ip, SessionMode::Server).addChannel(); - BaseOT recv; - - std::vector msg(totalOTs); - BitVector choice(totalOTs); - choice.randomize(prng); - - - Timer t; - auto s = t.setTimePoint("base OT start"); - - recv.receive(choice, msg, prng, chl0); - - auto e = t.setTimePoint("base OT end"); - auto milli = std::chrono::duration_cast(e - s).count(); - - std::cout << tag << " n=" << totalOTs << " " << milli << " ms" << std::endl; - } - else - { - - auto chl1 = Session(ios, ip, SessionMode::Client).addChannel(); - - BaseOT send; - - std::vector> msg(totalOTs); - - send.send(msg, prng, chl1); - } -} - - - -static const std::vector -unitTestTag{ "u", "unitTest" }, -kos{ "k", "kos" }, -dkos{ "d", "dkos" }, -kkrt{ "kk", "kkrt" }, -iknp{ "i", "iknp" }, -diknp{ "diknp" }, -oos{ "o", "oos" }, -Silent{ "s", "Silent" }, -akn{ "a", "akn" }, -np{ "np" }, -simple{ "simplest" }, -simpleasm{ "simplest-asm" }; - -using ProtocolFunc = std::function; - -bool runIf(ProtocolFunc protocol, CLP & cmd, std::vector tag) -{ - auto n = cmd.isSet("nn") - ? (1 << cmd.get("nn")) - : cmd.getOr("n", 0); - - auto t = cmd.getOr("t", 1); - auto ip = cmd.getOr("ip", "localhost:1212"); - - if (cmd.isSet(tag)) - { - if (cmd.hasValue("r")) - { - auto role = cmd.get("r") ? Role::Sender : Role::Receiver; - protocol(role, n, t, ip, tag.back(), cmd); - } - else - { - auto thrd = std::thread([&] { - try { protocol(Role::Sender, n, t, ip, tag.back(), cmd); } - catch (std::exception & e) - { - lout << e.what() << std::endl; - } - }); - - try { protocol(Role::Receiver, n, t, ip, tag.back(), cmd); } - catch (std::exception & e) - { - lout << e.what() << std::endl; - } - thrd.join(); - } - - return true; - } - - return false; -} -#ifdef ENABLE_IKNP -void minimal() -{ - // Setup networking. See cryptoTools\frontend_cryptoTools\Tutorials\Network.cpp - IOService ios; - Channel senderChl = Session(ios, "localhost:1212", SessionMode::Server).addChannel(); - Channel recverChl = Session(ios, "localhost:1212", SessionMode::Client).addChannel(); - - // The number of OTs. - int n = 100; - - // The code to be run by the OT receiver. - auto recverThread = std::thread([&]() { - PRNG prng(sysRandomSeed()); - IknpOtExtReceiver recver; - - // Choose which messages should be received. - BitVector choices(n); - choices[0] = 1; - //... - - // Receive the messages - std::vector messages(n); - recver.receiveChosen(choices, messages, prng, recverChl); - - // messages[i] = sendMessages[i][choices[i]]; - }); - - PRNG prng(sysRandomSeed()); - IknpOtExtSender sender; - - // Choose which messages should be sent. - std::vector> sendMessages(n); - sendMessages[0] = { toBlock(54), toBlock(33) }; - //... - - // Send the messages. - sender.sendChosen(sendMessages, prng, senderChl); - recverThread.join(); -} -#endif - - -// -// Created by Erik Buchholz on 27.02.20. -// +#include + +//using namespace std; +#include "tests_cryptoTools/UnitTests.h" +#include "libOTe_Tests/UnitTests.h" +#include + +using namespace osuCrypto; + #include #include -#include -#include + #include #include -#include -#include -#include -#include - -#define LINE "------------------------------------------------------" -#define TOTALOTS 10 -#define SETSIZE 2<<10 - -#ifdef ENABLE_SIMPLESTOT -const bool spEnabled = true; -#else -const bool spEnabled = false; -#endif -#ifdef ENABLE_SIMPLESTOT_ASM -const bool spaEnabled = true; -#else -const bool spaEnabled = false; -#endif -#ifdef ENABLE_IKNP -const bool iknpEnabled = true; -#else -const bool iknpEnabled = false; -#endif -#ifdef ENABLE_DELTA_IKNP -const bool diknpEnabled = true; -#else -const bool diknpEnabled = false; -#endif -#ifdef ENABLE_KOS -const bool kosEnabled = true; -#else -const bool kosEnabled = false; -#endif -#ifdef ENABLE_DELTA_KOS -const bool dkosEnabled = true; -#else -const bool dkosEnabled = false; -#endif -#ifdef ENABLE_NP -const bool npEnabled = true; -#else -const bool npEnabled = false; -#endif - -#ifdef ENABLE_OOS -const bool oosEnabled = true; -#else -const bool oosEnabled = false; -#endif -#ifdef ENABLE_KKRT -const bool kkrtEnabled = true; -#else -const bool kkrtEnabled = false; -#endif - -#ifdef ENABLE_SILENTOT -const bool silentEnabled = true; -#else -const bool silentEnabled = false; -#endif - -#include "cryptoTools/Crypto/RandomOracle.h" -int main(int argc, char** argv) -{ - - CLP cmd; - cmd.parse(argc, argv); - bool flagSet = false; - - if (cmd.isSet(unitTestTag)) - { - flagSet = true; - auto tests = tests_cryptoTools::Tests; - tests += tests_libOTe::Tests; - - tests.runIf(cmd); - return 0; - } - - if (cmd.isSet("latency")) - { - getLatency(cmd); - flagSet = true; - } - -#ifdef ENABLE_SIMPLESTOT - flagSet |= runIf(baseOT_example, cmd, simple); -#endif -#ifdef ENABLE_SIMPLESTOT_ASM - flagSet |= runIf(baseOT_example, cmd, simpleasm); -#endif -#ifdef ENABLE_NP - flagSet |= runIf(baseOT_example, cmd, np); -#endif -#ifdef ENABLE_IKNP - flagSet |= runIf(TwoChooseOne_example, cmd, iknp); -#endif -#ifdef ENABLE_DELTA_IKNP - flagSet |= runIf(TwoChooseOne_example, cmd, diknp); -#endif -#ifdef ENABLE_KOS - flagSet |= runIf(TwoChooseOne_example, cmd, kos); -#endif -#ifdef ENABLE_DELTA_KOS - flagSet |= runIf(TwoChooseOne_example, cmd, dkos); -#endif -#ifdef ENABLE_KKRT - flagSet |= runIf(NChooseOne_example, cmd, kkrt); -#endif -#ifdef ENABLE_OOS - flagSet |= runIf(NChooseOne_example, cmd, oos); -#endif - - flagSet |= runIf(TwoChooseOneG_example, cmd, Silent); - - - - if (flagSet == false) - { - - std::cout - << "#######################################################\n" - << "# - libOTe - #\n" - << "# A library for performing #\n" - << "# oblivious transfer. #\n" - << "# Peter Rindal #\n" - << "#######################################################\n" << std::endl; - - - std::cout - << "Protocols:\n" - << Color::Green << " -simplest-asm" << Color::Default << " : to run the ASM-SimplestOT active secure 1-out-of-2 base OT " < OT sender and network server. r 0 -> OT receiver and network client.\n" - << Color::Green << " -ip " << Color::Default << ": the IP and port of the netowrk server, default = localhost:1212\n" - << Color::Green << " -t " << Color::Default << ": the number of threads that should be used\n" - << Color::Green << " -u " << Color::Default << ": to run the unit tests\n" - << Color::Green << " -u -list " << Color::Default << ": to list the unit tests\n" - << Color::Green << " -u 1 2 15 " << Color::Default << ": to run the unit tests indexed by {1, 2, 15}.\n" - << std::endl; - } - - return 0; -} +#include +#include +#include + +#include +#include "util.h" + +#include "ExampleBase.h" +#include "ExampleTwoChooseOne.h" +#include "ExampleNChooseOne.h" +#include "ExampleSilent.h" + +static const std::vector +unitTestTag{ "u", "unitTest" }, +kos{ "k", "kos" }, +dkos{ "d", "dkos" }, +kkrt{ "kk", "kkrt" }, +iknp{ "i", "iknp" }, +diknp{ "diknp" }, +oos{ "o", "oos" }, +moellerpopf{ "p", "moellerpopf" }, +ristrettopopf{ "r", "ristrettopopf" }, +mr{ "mr" }, +mrb{ "mrb" }, +Silent{ "s", "Silent" }, +vole{ "vole" }, +akn{ "a", "akn" }, +np{ "np" }, +simple{ "simplest" }, +simpleasm{ "simplest-asm" }; + +#ifdef ENABLE_IKNP +void minimal() +{ + // Setup networking. See cryptoTools\frontend_cryptoTools\Tutorials\Network.cpp + IOService ios; + Channel senderChl = Session(ios, "localhost:1212", SessionMode::Server).addChannel(); + Channel recverChl = Session(ios, "localhost:1212", SessionMode::Client).addChannel(); + + // The number of OTs. + int n = 100; + + // The code to be run by the OT receiver. + auto recverThread = std::thread([&]() { + PRNG prng(sysRandomSeed()); + IknpOtExtReceiver recver; + + // Choose which messages should be received. + BitVector choices(n); + choices[0] = 1; + //... + + // Receive the messages + std::vector messages(n); + recver.receiveChosen(choices, messages, prng, recverChl); + + // messages[i] = sendMessages[i][choices[i]]; + }); + + PRNG prng(sysRandomSeed()); + IknpOtExtSender sender; + + // Choose which messages should be sent. + std::vector> sendMessages(n); + sendMessages[0] = { toBlock(54), toBlock(33) }; + //... + + // Send the messages. + sender.sendChosen(sendMessages, prng, senderChl); + recverThread.join(); +} +#endif + + + +#include "cryptoTools/Crypto/RandomOracle.h" +int main(int argc, char** argv) +{ + + CLP cmd; + cmd.parse(argc, argv); + bool flagSet = false; + + //if (cmd.isSet("triang")) + //{ + // ldpc(cmd); + // return 0; + //} + + + //if (cmd.isSet("encode")) + //{ + // encodeBench(cmd); + // return 0; + //} + + if (cmd.isSet(unitTestTag)) + { + flagSet = true; + auto tests = tests_cryptoTools::Tests; + tests += tests_libOTe::Tests; + + auto r = tests.runIf(cmd); + return r == TestCollection::Result::passed ? 0 : -1; + } + + if (cmd.isSet("latency")) + { + getLatency(cmd); + flagSet = true; + } + +#ifdef ENABLE_SIMPLESTOT + flagSet |= runIf(baseOT_example, cmd, simple); +#endif + +#ifdef ENABLE_SIMPLESTOT_ASM + flagSet |= runIf(baseOT_example, cmd, simpleasm); +#endif + +#ifdef ENABLE_MRR_TWIST +#ifdef ENABLE_SSE + flagSet |= runIf([&](Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP& clp) { + DomainSepEKEPopf factory; + const char* domain = "EKE POPF OT example"; + factory.Update(domain, std::strlen(domain)); + baseOT_example_from_ot(role, totalOTs, numThreads, ip, tag, clp, McRosRoyTwist(factory)); + }, cmd, moellerpopf, {"eke"}); +#endif + + flagSet |= runIf([&](Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP& clp) { + DomainSepMRPopf factory; + const char* domain = "MR POPF OT example"; + factory.Update(domain, std::strlen(domain)); + baseOT_example_from_ot(role, totalOTs, numThreads, ip, tag, clp, McRosRoyTwistMR(factory)); + }, cmd, moellerpopf, {"mrPopf"}); + + flagSet |= runIf([&](Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP& clp) { + DomainSepFeistelPopf factory; + const char* domain = "Feistel POPF OT example"; + factory.Update(domain, std::strlen(domain)); + baseOT_example_from_ot(role, totalOTs, numThreads, ip, tag, clp, McRosRoyTwistFeistel(factory)); + }, cmd, moellerpopf, {"feistel"}); + + flagSet |= runIf([&](Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP& clp) { + DomainSepFeistelMulPopf factory; + const char* domain = "Feistel With Multiplication POPF OT example"; + factory.Update(domain, std::strlen(domain)); + baseOT_example_from_ot(role, totalOTs, numThreads, ip, tag, clp, McRosRoyTwistMul(factory)); + }, cmd, moellerpopf, {"feistelMul"}); +#endif + +#ifdef ENABLE_MRR + flagSet |= runIf([&](Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP& clp) { + DomainSepFeistelRistPopf factory; + const char* domain = "Feistel POPF OT example (Risretto)"; + factory.Update(domain, std::strlen(domain)); + baseOT_example_from_ot(role, totalOTs, numThreads, ip, tag, clp, McRosRoy(factory)); + }, cmd, ristrettopopf, {"feistel"}); + + flagSet |= runIf([&](Role role, int totalOTs, int numThreads, std::string ip, std::string tag, CLP& clp) { + DomainSepFeistelMulRistPopf factory; + const char* domain = "Feistel With Multiplication POPF OT example (Risretto)"; + factory.Update(domain, std::strlen(domain)); + baseOT_example_from_ot(role, totalOTs, numThreads, ip, tag, clp, McRosRoyMul(factory)); + }, cmd, ristrettopopf, {"feistelMul"}); +#endif + +#ifdef ENABLE_MR + flagSet |= runIf(baseOT_example, cmd, mr); +#endif + +#ifdef ENABLE_NP + flagSet |= runIf(baseOT_example, cmd, np); +#endif + +#ifdef ENABLE_IKNP + flagSet |= runIf(TwoChooseOne_example, cmd, iknp); +#endif + +#ifdef ENABLE_KOS + flagSet |= runIf(TwoChooseOne_example, cmd, kos); +#endif + +#ifdef ENABLE_DELTA_KOS + flagSet |= runIf(TwoChooseOne_example, cmd, dkos); +#endif + +#ifdef ENABLE_KKRT + flagSet |= runIf(NChooseOne_example, cmd, kkrt); +#endif + +#ifdef ENABLE_OOS + flagSet |= runIf(NChooseOne_example, cmd, oos); +#endif + + flagSet |= runIf(Silent_example, cmd, Silent); + + + + if (flagSet == false) + { + + std::cout + << "#######################################################\n" + << "# - libOTe - #\n" + << "# A library for performing #\n" + << "# oblivious transfer. #\n" + << "# Peter Rindal #\n" + << "#######################################################\n" << std::endl; + + + std::cout + << "Protocols:\n" + << Color::Green << " -simplest-asm " << Color::Default << " : to run the ASM-SimplestOT active secure 1-out-of-2 base OT " << Color::Red << (spaEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -simplest " << Color::Default << " : to run the SimplestOT active secure 1-out-of-2 base OT " << Color::Red << (spEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -moellerpopf " << Color::Default << " : to run the McRosRoyTwist active secure 1-out-of-2 base OT " << Color::Red << (popfotMoellerEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -ristrettopopf" << Color::Default << " : to run the McRosRoy active secure 1-out-of-2 base OT " << Color::Red << (popfotRistrettoEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -mr " << Color::Default << " : to run the MasnyRindal active secure 1-out-of-2 base OT " << Color::Red << (mrEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -np " << Color::Default << " : to run the NaorPinkas active secure 1-out-of-2 base OT " << Color::Red << (npEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -iknp " << Color::Default << " : to run the IKNP passive secure 1-out-of-2 OT " << Color::Red << (iknpEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -diknp " << Color::Default << " : to run the IKNP passive secure 1-out-of-2 Delta-OT " << Color::Red << (diknpEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -Silent " << Color::Default << " : to run the Silent passive secure 1-out-of-2 OT " << Color::Red << (silentEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -kos " << Color::Default << " : to run the KOS active secure 1-out-of-2 OT " << Color::Red << (kosEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -dkos " << Color::Default << " : to run the KOS active secure 1-out-of-2 Delta-OT " << Color::Red << (dkosEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -oos " << Color::Default << " : to run the OOS active secure 1-out-of-N OT for N=2^76 " << Color::Red << (oosEnabled ? "" : "(disabled)") << "\n" << Color::Default + << Color::Green << " -kkrt " << Color::Default << " : to run the KKRT passive secure 1-out-of-N OT for N=2^128" << Color::Red << (kkrtEnabled ? "" : "(disabled)") << "\n\n" << Color::Default + + << "POPF Options:\n" + << Color::Green << " -eke " << Color::Default << " : to run the EKE POPF (Moeller only) " << "\n"<< Color::Default + << Color::Green << " -mrPopf " << Color::Default << " : to run the MasnyRindal POPF (Moeller only) " << "\n"<< Color::Default + << Color::Green << " -feistel " << Color::Default << " : to run the Feistel POPF " << "\n"<< Color::Default + << Color::Green << " -feistelMul " << Color::Default << " : to run the Feistel With Multiplication POPF " << "\n\n"<< Color::Default + + << "Other Options:\n" + << Color::Green << " -n " << Color::Default << ": the number of OTs to perform\n" + << Color::Green << " -r 0/1 " << Color::Default << ": Do not play both OT roles. r 1 -> OT sender and network server. r 0 -> OT receiver and network client.\n" + << Color::Green << " -ip " << Color::Default << ": the IP and port of the netowrk server, default = localhost:1212\n" + << Color::Green << " -t " << Color::Default << ": the number of threads that should be used\n" + << Color::Green << " -u " << Color::Default << ": to run the unit tests\n" + << Color::Green << " -u -list " << Color::Default << ": to list the unit tests\n" + << Color::Green << " -u 1 2 15 " << Color::Default << ": to run the unit tests indexed by {1, 2, 15}.\n" + << std::endl; + } + + return 0; +} diff --git a/frontend/util.cpp b/frontend/util.cpp index 6943aae7..f7762fa9 100644 --- a/frontend/util.cpp +++ b/frontend/util.cpp @@ -1,6 +1,5 @@ #include "util.h" -using namespace osuCrypto; #include #include #include @@ -9,137 +8,141 @@ using namespace osuCrypto; #include #include -void getLatency(CLP& cmd) + +namespace osuCrypto { - auto ip = cmd.getOr("ip", "localhost:1212"); - if (cmd.hasValue("r")) + void getLatency(CLP& cmd) { - auto mode = cmd.get("r") != 0 ? SessionMode::Server : SessionMode::Client; - IOService ios; - Session session(ios, ip, mode); - auto chl = session.addChannel(); - if (mode == SessionMode::Server) - senderGetLatency(chl); + auto ip = cmd.getOr("ip", "localhost:1212"); + + if (cmd.hasValue("r")) + { + auto mode = cmd.get("r") != 0 ? SessionMode::Server : SessionMode::Client; + IOService ios; + Session session(ios, ip, mode); + auto chl = session.addChannel(); + if (mode == SessionMode::Server) + senderGetLatency(chl); + else + recverGetLatency(chl); + } else - recverGetLatency(chl); - } - else - { - IOService ios; - Session s(ios, ip, SessionMode::Server); - Session r(ios, ip, SessionMode::Client); - auto cs = s.addChannel(); - auto cr = r.addChannel(); - - auto thrd = std::thread([&]() {senderGetLatency(cs); }); - recverGetLatency(cr); - - thrd.join(); + { + IOService ios; + Session s(ios, ip, SessionMode::Server); + Session r(ios, ip, SessionMode::Client); + auto cs = s.addChannel(); + auto cr = r.addChannel(); + + auto thrd = std::thread([&]() {senderGetLatency(cs); }); + recverGetLatency(cr); + + thrd.join(); + } } -} -void sync(Channel& chl, Role role) -{ - if (role == Role::Receiver) + void sync(Channel& chl, Role role) { + if (role == Role::Receiver) + { - u8 dummy[1]; - chl.recv(dummy, 1); - Timer timer; + u8 dummy[1]; + chl.recv(dummy, 1); + Timer timer; - auto start = timer.setTimePoint(""); - chl.asyncSend(dummy, 1); - chl.recv(dummy, 1); - auto mid = timer.setTimePoint(""); - - chl.asyncSend(dummy, 1); + auto start = timer.setTimePoint(""); + chl.asyncSend(dummy, 1); + chl.recv(dummy, 1); + auto mid = timer.setTimePoint(""); + chl.asyncSend(dummy, 1); - auto rrt = mid - start; - auto ms = std::chrono::duration_cast(rrt).count(); - if (ms > 4) - std::this_thread::sleep_for(rrt / 2); + auto rrt = mid - start; + auto ms = std::chrono::duration_cast(rrt).count(); + if (ms > 4) + std::this_thread::sleep_for(rrt / 2); + } + else + { + u8 dummy[1]; + chl.asyncSend(dummy, 1); + chl.recv(dummy, 1); + chl.asyncSend(dummy, 1); + chl.recv(dummy, 1); + } } - else + + void senderGetLatency(Channel& chl) { - u8 dummy[1]; - chl.asyncSend(dummy, 1); - chl.recv(dummy, 1); - chl.asyncSend(dummy, 1); - chl.recv(dummy, 1); - } -} -void senderGetLatency(Channel& chl) -{ + u8 dummy[1]; - u8 dummy[1]; + chl.asyncSend(dummy, 1); - chl.asyncSend(dummy, 1); + chl.recv(dummy, 1); + chl.asyncSend(dummy, 1); - chl.recv(dummy, 1); - chl.asyncSend(dummy, 1); + std::vector oneMbit((1 << 20) / 8); + for (u64 i = 0; i < tryCount; ++i) + { + chl.recv(dummy, 1); - std::vector oneMbit((1 << 20) / 8); - for (u64 i = 0; i < tryCount; ++i) - { - chl.recv(dummy, 1); + for (u64 j = 0; j < (1 << 10); ++j) + chl.asyncSend(oneMbit.data(), oneMbit.size()); + } + chl.recv(dummy, 1); - for(u64 j =0; j < (1<<10); ++j) - chl.asyncSend(oneMbit.data(), oneMbit.size()); - } - chl.recv(dummy, 1); + } -} + void recverGetLatency(Channel& chl) + { -void recverGetLatency(Channel& chl) -{ + u8 dummy[1]; + chl.recv(dummy, 1); + Timer timer; + auto start = timer.setTimePoint(""); + chl.asyncSend(dummy, 1); - u8 dummy[1]; - chl.recv(dummy, 1); - Timer timer; - auto start = timer.setTimePoint(""); - chl.asyncSend(dummy, 1); + chl.recv(dummy, 1); - chl.recv(dummy, 1); + auto mid = timer.setTimePoint(""); + auto recvStart = mid; + auto recvEnd = mid; - auto mid = timer.setTimePoint(""); - auto recvStart = mid; - auto recvEnd = mid; + auto rrt = mid - start; + std::cout << "latency: " << std::chrono::duration_cast(rrt).count() << " ms" << std::endl; - auto rrt = mid - start; - std::cout << "latency: " << std::chrono::duration_cast(rrt).count() << " ms" << std::endl; - - std::vector oneMbit((1 << 20) / 8); - for (u64 i = 0; i < tryCount; ++i) - { - recvStart = timer.setTimePoint(""); - chl.asyncSend(dummy, 1); + std::vector oneMbit((1 << 20) / 8); + for (u64 i = 0; i < tryCount; ++i) + { + recvStart = timer.setTimePoint(""); + chl.asyncSend(dummy, 1); - for (u64 j = 0; j < (1 << 10); ++j) - chl.recv(oneMbit); + for (u64 j = 0; j < (1 << 10); ++j) + chl.recv(oneMbit); - recvEnd = timer.setTimePoint(""); + recvEnd = timer.setTimePoint(""); - // nanoseconds per GegaBit - auto uspGb = std::chrono::duration_cast(recvEnd - recvStart - rrt / 2).count(); + // nanoseconds per GegaBit + auto uspGb = std::chrono::duration_cast(recvEnd - recvStart - rrt / 2).count(); - // nanoseconds per second - auto usps = std::chrono::duration_cast(std::chrono::seconds(1)).count(); + // nanoseconds per second + auto usps = std::chrono::duration_cast(std::chrono::seconds(1)).count(); - // MegaBits per second - auto Mbps = usps * 1.0 / uspGb * (1 << 10); + // MegaBits per second + auto Mbps = usps * 1.0 / uspGb * (1 << 10); - std::cout << "bandwidth: " << Mbps << " Mbps" << std::endl; - } + std::cout << "bandwidth: " << Mbps << " Mbps" << std::endl; + } - chl.asyncSend(dummy, 1); + chl.asyncSend(dummy, 1); -} + } +} \ No newline at end of file diff --git a/frontend/util.h b/frontend/util.h index 543a6eb0..a25c068a 100644 --- a/frontend/util.h +++ b/frontend/util.h @@ -1,18 +1,152 @@ #pragma once -// This file and the associated implementation has been placed in the public domain, waiving all copyright. No restrictions are placed on its use. +// This file and the associated implementation has been placed in the public domain, waiving all copyright. No restrictions are placed on its use. #include +#include #include -void senderGetLatency(osuCrypto::Channel& chl); +#include "libOTe/config.h" +#include +#include -void recverGetLatency(osuCrypto::Channel& chl); -void getLatency(osuCrypto::CLP& cmd); -enum class Role +namespace osuCrypto { - Sender, - Receiver -}; -void sync(osuCrypto::Channel& chl, Role role); \ No newline at end of file + + void senderGetLatency(Channel& chl); + + void recverGetLatency(Channel& chl); + void getLatency(CLP& cmd); + + enum class Role + { + Sender, + Receiver + }; + + void sync(Channel& chl, Role role); + + + + using ProtocolFunc = std::function; + + inline bool runIf(ProtocolFunc protocol, CLP & cmd, std::vector tag, + std::vector tag2 = std::vector()) + { + auto n = cmd.isSet("nn") + ? (1 << cmd.get("nn")) + : cmd.getOr("n", 0); + + auto t = cmd.getOr("t", 1); + auto ip = cmd.getOr("ip", "localhost:1212"); + + if (!cmd.isSet(tag)) + return false; + + if (!tag2.empty() && !cmd.isSet(tag2)) + return false; + + if (cmd.hasValue("r")) + { + auto role = cmd.get("r") ? Role::Sender : Role::Receiver; + protocol(role, n, t, ip, tag.back(), cmd); + } + else + { + auto thrd = std::thread([&] { + try { protocol(Role::Sender, n, t, ip, tag.back(), cmd); } + catch (std::exception& e) + { + lout << e.what() << std::endl; + } + }); + + try { protocol(Role::Receiver, n, t, ip, tag.back(), cmd); } + catch (std::exception& e) + { + lout << e.what() << std::endl; + } + thrd.join(); + } + + return true; + } + + + + +#define LINE "------------------------------------------------------" +#define TOTALOTS 10 +#define SETSIZE 2<<10 + +#ifdef ENABLE_SIMPLESTOT + const bool spEnabled = true; +#else + const bool spEnabled = false; +#endif +#ifdef ENABLE_SIMPLESTOT_ASM + const bool spaEnabled = true; +#else + const bool spaEnabled = false; +#endif +#ifdef ENABLE_MRR + const bool popfotRistrettoEnabled = true; +#else + const bool popfotRistrettoEnabled = false; +#endif +#ifdef ENABLE_MRR_TWIST + const bool popfotMoellerEnabled = true; +#else + const bool popfotMoellerEnabled = false; +#endif +#ifdef ENABLE_MR + const bool mrEnabled = true; +#else + const bool mrEnabled = false; +#endif +#ifdef ENABLE_IKNP + const bool iknpEnabled = true; +#else + const bool iknpEnabled = false; +#endif +#ifdef ENABLE_DELTA_IKNP + const bool diknpEnabled = true; +#else + const bool diknpEnabled = false; +#endif +#ifdef ENABLE_KOS + const bool kosEnabled = true; +#else + const bool kosEnabled = false; +#endif +#ifdef ENABLE_DELTA_KOS + const bool dkosEnabled = true; +#else + const bool dkosEnabled = false; +#endif +#ifdef ENABLE_NP + const bool npEnabled = true; +#else + const bool npEnabled = false; +#endif + +#ifdef ENABLE_OOS + const bool oosEnabled = true; +#else + const bool oosEnabled = false; +#endif +#ifdef ENABLE_KKRT + const bool kkrtEnabled = true; +#else + const bool kkrtEnabled = false; +#endif + +#ifdef ENABLE_SILENTOT + const bool silentEnabled = true; +#else + const bool silentEnabled = false; +#endif + + +} diff --git a/libOTe.sln b/libOTe.sln deleted file mode 100644 index 04ee3eae..00000000 --- a/libOTe.sln +++ /dev/null @@ -1,163 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29102.190 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOTe", "libOTe\libOTe.vcxproj.vcxproj", "{D159E2F9-226C-4B19-905E-CC1EA0EB013F}" - ProjectSection(ProjectDependencies) = postProject - {B707F703-490A-447F-9737-C6A70B8D7A61} = {B707F703-490A-447F-9737-C6A70B8D7A61} - {CE639ABE-6913-428A-92B0-7C5A6458B983} = {CE639ABE-6913-428A-92B0-7C5A6458B983} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOTe_Tests", "libOTe_Tests\libOTe_Tests.vcxproj.vcxproj", "{294C00B6-949E-4A45-AFA8-45D53590FC11}" - ProjectSection(ProjectDependencies) = postProject - {B707F703-490A-447F-9737-C6A70B8D7A61} = {B707F703-490A-447F-9737-C6A70B8D7A61} - {D159E2F9-226C-4B19-905E-CC1EA0EB013F} = {D159E2F9-226C-4B19-905E-CC1EA0EB013F} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "frontend", "frontend\frontend.vcxproj", "{C81DC04B-A0F0-4B77-8DCE-C8190E629467}" - ProjectSection(ProjectDependencies) = postProject - {10DCA769-B168-4E7F-914E-E8A525333327} = {10DCA769-B168-4E7F-914E-E8A525333327} - {294C00B6-949E-4A45-AFA8-45D53590FC11} = {294C00B6-949E-4A45-AFA8-45D53590FC11} - {D159E2F9-226C-4B19-905E-CC1EA0EB013F} = {D159E2F9-226C-4B19-905E-CC1EA0EB013F} - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B9CAB0DB-C7A5-4180-A85A-F532BC550E59}" - ProjectSection(SolutionItems) = preProject - .gitignore = .gitignore - build.sh = build.sh - CMakeLists.txt = CMakeLists.txt - copySourceToLinux.ps1 = copySourceToLinux.ps1 - README.md = README.md - testout.txt = testout.txt - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cryptoTools", "cryptoTools\cryptoTools\cryptoTools.vcxproj", "{B707F703-490A-447F-9737-C6A70B8D7A61}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "frontend_cryptoTools", "cryptoTools\frontend_cryptoTools\frontend_cryptoTools.vcxproj", "{9816C48C-6316-40C7-929C-4B29505C7E0A}" - ProjectSection(ProjectDependencies) = postProject - {10DCA769-B168-4E7F-914E-E8A525333327} = {10DCA769-B168-4E7F-914E-E8A525333327} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests_cryptoTools", "cryptoTools\tests_cryptoTools\tests_cryptoTools.vcxproj", "{10DCA769-B168-4E7F-914E-E8A525333327}" - ProjectSection(ProjectDependencies) = postProject - {B707F703-490A-447F-9737-C6A70B8D7A61} = {B707F703-490A-447F-9737-C6A70B8D7A61} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimplestOT", "SimplestOT\SimplestOT.vcxproj", "{904419B6-0A3E-41A8-B27A-CF1BAE7343B6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KyberOT", "KyberOT\KyberOT.vcxproj", "{CE639ABE-6913-428A-92B0-7C5A6458B983}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug_DLLRT|x64 = Debug_DLLRT|x64 - Debug_DLLRT|x86 = Debug_DLLRT|x86 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release_DLLRT|x64 = Release_DLLRT|x64 - Release_DLLRT|x86 = Release_DLLRT|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Debug_DLLRT|x64.ActiveCfg = Debug_DLLRT|x64 - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Debug_DLLRT|x64.Build.0 = Debug_DLLRT|x64 - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Debug_DLLRT|x86.ActiveCfg = Debug_DLLRT|x64 - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Debug|x64.ActiveCfg = Debug|x64 - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Debug|x64.Build.0 = Debug|x64 - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Debug|x86.ActiveCfg = Debug|x64 - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Release_DLLRT|x64.ActiveCfg = Release_DLLRT|x64 - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Release_DLLRT|x64.Build.0 = Release_DLLRT|x64 - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Release_DLLRT|x86.ActiveCfg = Release_DLLRT|x64 - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Release|x64.ActiveCfg = Release|x64 - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Release|x64.Build.0 = Release|x64 - {D159E2F9-226C-4B19-905E-CC1EA0EB013F}.Release|x86.ActiveCfg = Release|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Debug_DLLRT|x64.ActiveCfg = Debug_DLLRT|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Debug_DLLRT|x64.Build.0 = Debug_DLLRT|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Debug_DLLRT|x86.ActiveCfg = Debug_DLLRT|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Debug|x64.ActiveCfg = Debug|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Debug|x64.Build.0 = Debug|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Debug|x86.ActiveCfg = Debug|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Release_DLLRT|x64.ActiveCfg = Release_DLLRT|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Release_DLLRT|x64.Build.0 = Release_DLLRT|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Release_DLLRT|x86.ActiveCfg = Release_DLLRT|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Release|x64.ActiveCfg = Release|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Release|x64.Build.0 = Release|x64 - {294C00B6-949E-4A45-AFA8-45D53590FC11}.Release|x86.ActiveCfg = Release|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Debug_DLLRT|x64.ActiveCfg = Debug_DLLRT|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Debug_DLLRT|x64.Build.0 = Debug_DLLRT|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Debug_DLLRT|x86.ActiveCfg = Debug_DLLRT|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Debug|x64.ActiveCfg = Debug|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Debug|x64.Build.0 = Debug|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Debug|x86.ActiveCfg = Debug|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Release_DLLRT|x64.ActiveCfg = Release_DLLRT|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Release_DLLRT|x64.Build.0 = Release_DLLRT|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Release_DLLRT|x86.ActiveCfg = Release_DLLRT|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Release|x64.ActiveCfg = Release|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Release|x64.Build.0 = Release|x64 - {C81DC04B-A0F0-4B77-8DCE-C8190E629467}.Release|x86.ActiveCfg = Release|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Debug_DLLRT|x64.ActiveCfg = Debug_DLLRT|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Debug_DLLRT|x64.Build.0 = Debug_DLLRT|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Debug_DLLRT|x86.ActiveCfg = Debug_DLLRT|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Debug|x64.ActiveCfg = Debug|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Debug|x64.Build.0 = Debug|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Debug|x86.ActiveCfg = Debug|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Release_DLLRT|x64.ActiveCfg = Release_DLLRT|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Release_DLLRT|x64.Build.0 = Release_DLLRT|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Release_DLLRT|x86.ActiveCfg = Release_DLLRT|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Release|x64.ActiveCfg = Release|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Release|x64.Build.0 = Release|x64 - {B707F703-490A-447F-9737-C6A70B8D7A61}.Release|x86.ActiveCfg = Release|x64 - {9816C48C-6316-40C7-929C-4B29505C7E0A}.Debug_DLLRT|x64.ActiveCfg = Debug_DLLRT|x64 - {9816C48C-6316-40C7-929C-4B29505C7E0A}.Debug_DLLRT|x64.Build.0 = Debug_DLLRT|x64 - {9816C48C-6316-40C7-929C-4B29505C7E0A}.Debug_DLLRT|x86.ActiveCfg = Debug_DLLRT|x64 - {9816C48C-6316-40C7-929C-4B29505C7E0A}.Debug|x64.ActiveCfg = Debug|x64 - {9816C48C-6316-40C7-929C-4B29505C7E0A}.Debug|x86.ActiveCfg = Debug|x64 - {9816C48C-6316-40C7-929C-4B29505C7E0A}.Release_DLLRT|x64.ActiveCfg = Release_DLLRT|x64 - {9816C48C-6316-40C7-929C-4B29505C7E0A}.Release_DLLRT|x86.ActiveCfg = Release_DLLRT|x64 - {9816C48C-6316-40C7-929C-4B29505C7E0A}.Release|x64.ActiveCfg = Release|x64 - {9816C48C-6316-40C7-929C-4B29505C7E0A}.Release|x64.Build.0 = Release|x64 - {9816C48C-6316-40C7-929C-4B29505C7E0A}.Release|x86.ActiveCfg = Release|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Debug_DLLRT|x64.ActiveCfg = Debug_DLLRT|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Debug_DLLRT|x64.Build.0 = Debug_DLLRT|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Debug_DLLRT|x86.ActiveCfg = Debug_DLLRT|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Debug|x64.ActiveCfg = Debug|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Debug|x64.Build.0 = Debug|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Debug|x86.ActiveCfg = Debug|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Release_DLLRT|x64.ActiveCfg = Release_DLLRT|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Release_DLLRT|x64.Build.0 = Release_DLLRT|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Release_DLLRT|x86.ActiveCfg = Release_DLLRT|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Release|x64.ActiveCfg = Release|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Release|x64.Build.0 = Release|x64 - {10DCA769-B168-4E7F-914E-E8A525333327}.Release|x86.ActiveCfg = Release|x64 - {904419B6-0A3E-41A8-B27A-CF1BAE7343B6}.Debug_DLLRT|x64.ActiveCfg = Debug_DLLRT|x64 - {904419B6-0A3E-41A8-B27A-CF1BAE7343B6}.Debug_DLLRT|x86.ActiveCfg = Debug_DLLRT|Win32 - {904419B6-0A3E-41A8-B27A-CF1BAE7343B6}.Debug|x64.ActiveCfg = Debug|x64 - {904419B6-0A3E-41A8-B27A-CF1BAE7343B6}.Debug|x86.ActiveCfg = Debug|Win32 - {904419B6-0A3E-41A8-B27A-CF1BAE7343B6}.Debug|x86.Build.0 = Debug|Win32 - {904419B6-0A3E-41A8-B27A-CF1BAE7343B6}.Release_DLLRT|x64.ActiveCfg = Release_DLLRT|x64 - {904419B6-0A3E-41A8-B27A-CF1BAE7343B6}.Release_DLLRT|x86.ActiveCfg = Release_DLLRT|Win32 - {904419B6-0A3E-41A8-B27A-CF1BAE7343B6}.Release|x64.ActiveCfg = Release|x64 - {904419B6-0A3E-41A8-B27A-CF1BAE7343B6}.Release|x86.ActiveCfg = Release|Win32 - {904419B6-0A3E-41A8-B27A-CF1BAE7343B6}.Release|x86.Build.0 = Release|Win32 - {CE639ABE-6913-428A-92B0-7C5A6458B983}.Debug_DLLRT|x64.ActiveCfg = Debug_DLLRT|x64 - {CE639ABE-6913-428A-92B0-7C5A6458B983}.Debug_DLLRT|x86.ActiveCfg = Debug_DLLRT|Win32 - {CE639ABE-6913-428A-92B0-7C5A6458B983}.Debug|x64.ActiveCfg = Debug|x64 - {CE639ABE-6913-428A-92B0-7C5A6458B983}.Debug|x86.ActiveCfg = Debug|Win32 - {CE639ABE-6913-428A-92B0-7C5A6458B983}.Debug|x86.Build.0 = Debug|Win32 - {CE639ABE-6913-428A-92B0-7C5A6458B983}.Release_DLLRT|x64.ActiveCfg = Release_DLLRT|x64 - {CE639ABE-6913-428A-92B0-7C5A6458B983}.Release_DLLRT|x86.ActiveCfg = Release_DLLRT|Win32 - {CE639ABE-6913-428A-92B0-7C5A6458B983}.Release|x64.ActiveCfg = Release|x64 - {CE639ABE-6913-428A-92B0-7C5A6458B983}.Release|x86.ActiveCfg = Release|Win32 - {CE639ABE-6913-428A-92B0-7C5A6458B983}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {A6D49E45-0C15-4294-9CA8-85737234D96B} - EndGlobalSection - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection -EndGlobal diff --git a/libOTe/Base/BaseOT.h b/libOTe/Base/BaseOT.h index 6092ad4c..0a1dcae6 100644 --- a/libOTe/Base/BaseOT.h +++ b/libOTe/Base/BaseOT.h @@ -4,22 +4,29 @@ #include "SimplestOT.h" #include "naor-pinkas.h" #include "MasnyRindal.h" +#include "McRosRoyTwist.h" +#include "McRosRoy.h" +#include "libOTe/Tools/Popf/EKEPopf.h" +#include "libOTe/Tools/Popf/FeistelMulRistPopf.h" + namespace osuCrypto { -#ifdef ENABLE_SIMPLESTOT_ASM #define LIBOTE_HAS_BASE_OT +#ifdef ENABLE_SIMPLESTOT_ASM using DefaultBaseOT = AsmSimplestOT; +#elif defined ENABLE_MRR_TWIST && defined ENABLE_SSE + using DefaultBaseOT = McRosRoyTwist; #elif defined ENABLE_MR -#define LIBOTE_HAS_BASE_OT using DefaultBaseOT = MasnyRindal; +#elif defined ENABLE_MRR + using DefaultBaseOT = McRosRoy; #elif defined ENABLE_NP_KYBER -#define LIBOTE_HAS_BASE_OT using DefaultBaseOT = MasnyRindalKyber; #elif defined ENABLE_SIMPLESTOT -#define LIBOTE_HAS_BASE_OT using DefaultBaseOT = SimplestOT; #elif defined ENABLE_NP -#define LIBOTE_HAS_BASE_OT using DefaultBaseOT = NaorPinkas; +#else +#undef LIBOTE_HAS_BASE_OT #endif -} \ No newline at end of file +} diff --git a/libOTe/Base/MasnyRindal.cpp b/libOTe/Base/MasnyRindal.cpp index d409233f..5ae8732d 100644 --- a/libOTe/Base/MasnyRindal.cpp +++ b/libOTe/Base/MasnyRindal.cpp @@ -6,17 +6,12 @@ #include #include #include +#include "libOTe/Tools/DefaultCurve.h" -#include -#ifndef ENABLE_RELIC -static_assert(0, "ENABLE_RELIC must be defined to build MasnyRindal"); +#if !(defined(ENABLE_SODIUM) || defined(ENABLE_RELIC)) +static_assert(0, "ENABLE_SODIUM or ENABLE_RELIC must be defined to build MasnyRindal"); #endif -using Curve = oc::REllipticCurve; -using Point = oc::REccPoint; -using Brick = oc::REccPoint; -using Number = oc::REccNumber; - #include namespace osuCrypto @@ -29,142 +24,104 @@ namespace osuCrypto PRNG & prng, Channel & chl) { + using namespace DefaultCurve; + Curve curve; auto n = choices.size(); - Curve curve; - std::array r{ curve, curve }; - auto g = curve.getGenerator(); - auto pointSize = g.sizeBytes(); - RandomOracle ro(sizeof(block)); - Point hPoint(curve); + Point rrNot, rr, hPoint; - std::vector hashBuff(roundUpTo(pointSize, 16)); - std::vector aesBuff((pointSize + 15) / 16); std::vector sk; sk.reserve(n); - - std::vector recvBuff(pointSize); - auto fu = chl.asyncRecv(recvBuff.data(), pointSize); + u8 recvBuff[Point::size]; + auto fu = chl.asyncRecv(recvBuff, Point::size); for (u64 i = 0; i < n;) { auto curStep = std::min(n - i, step); - std::vector sendBuff(pointSize * 2 * curStep); - auto sendBuffIter = sendBuff.data(); - + std::vector sendBuff(Point::size * 2 * curStep); for (u64 k = 0; k < curStep; ++k, ++i) { + rrNot.randomize(prng); - auto& rrNot = r[choices[i] ^ 1]; - auto& rr = r[choices[i]]; - - rrNot.randomize(); - rrNot.toBytes(hashBuff.data()); + u8* rrNotPtr = &sendBuff[Point::size * (2 * k + (choices[i] ^ 1))]; + rrNot.toBytes(rrNotPtr); - ep_map(hPoint, hashBuff.data(), int(pointSize)); + // TODO: Ought to do domain separation. + hPoint.fromHash(rrNotPtr, Point::size); - sk.emplace_back(curve, prng); - - rr = g * sk[i]; + sk.emplace_back(prng); + rr = Point::mulGenerator(sk[i]); rr -= hPoint; - - r[0].toBytes(sendBuffIter); sendBuffIter += pointSize; - r[1].toBytes(sendBuffIter); sendBuffIter += pointSize; + rr.toBytes(&sendBuff[Point::size * (2 * k + choices[i])]); } - if (sendBuffIter != sendBuff.data() + sendBuff.size()) - throw RTE_LOC; - chl.asyncSend(std::move(sendBuff)); } - Point Mb(curve), k(curve); + Point Mb, k; fu.get(); - Mb.fromBytes(recvBuff.data()); + Mb.fromBytes(recvBuff); for (u64 i = 0; i < n; ++i) { k = Mb; k *= sk[i]; - //lout << "g^ab " << k << std::endl; - - k.toBytes(hashBuff.data()); - - ro.Reset(); - ro.Update(hashBuff.data(), pointSize); - ro.Update(i); + RandomOracle ro(sizeof(block)); + ro.Update(k); + ro.Update(i * 2 + choices[i]); ro.Final(messages[i]); } } void MasnyRindal::send(span> messages, PRNG & prng, Channel & chl) { - auto n = static_cast(messages.size()); - + using namespace DefaultCurve; Curve curve; - auto g = curve.getGenerator(); - RandomOracle ro(sizeof(block)); - auto pointSize = g.sizeBytes(); - - Number sk(curve, prng); + auto n = static_cast(messages.size()); - Point Mb = g; - Mb *= sk; + RandomOracle ro; - std::vector buff(pointSize), hashBuff(roundUpTo(pointSize, 16)); - std::vector aesBuff((pointSize + 15) / 16); + u8 sendBuff[Point::size]; - Mb.toBytes(buff.data()); - chl.asyncSend(std::move(buff)); + Number sk(prng); + Point Mb = Point::mulGenerator(sk); + Mb.toBytes(sendBuff); + chl.asyncSend(sendBuff, Point::size); - buff.resize(pointSize * 2 * step); - Point pHash(curve), r(curve); + u8 buff[Point::size * 2 * step]; + Point pHash, r; for (u64 i = 0; i < n; ) { auto curStep = std::min(n - i, step); - - auto buffSize = curStep * pointSize * 2; - chl.recv(buff.data(), buffSize); - auto buffIter = buff.data(); - + auto buffSize = curStep * Point::size * 2; + chl.recv(buff, buffSize); for (u64 k = 0; k < curStep; ++k, ++i) { - std::array buffIters{ - buffIter, - buffIter + pointSize - }; - buffIter += pointSize * 2; - for (u64 j = 0; j < 2; ++j) { - r.fromBytes(buffIters[j]); - ep_map(pHash, buffIters[j ^ 1], int(pointSize)); + r.fromBytes(&buff[Point::size * (2 * k + j)]); + + // TODO: Ought to do domain separation. + pHash.fromHash(&buff[Point::size * (2 * k + (j ^ 1))], Point::size); r += pHash; r *= sk; - r.toBytes(hashBuff.data()); - auto p = (block*)hashBuff.data(); - - ro.Reset(); - ro.Update(hashBuff.data(), pointSize); - ro.Update(i); + ro.Reset(sizeof(block)); + ro.Update(r); + ro.Update(i * 2 + j); ro.Final(messages[i][j]); } } - - if (buffIter != buff.data() + buffSize) - throw RTE_LOC; } - } } -#endif \ No newline at end of file +#endif diff --git a/libOTe/Base/McRosRoy.h b/libOTe/Base/McRosRoy.h new file mode 100644 index 00000000..71b62cf7 --- /dev/null +++ b/libOTe/Base/McRosRoy.h @@ -0,0 +1,195 @@ +#pragma once +#include "libOTe/config.h" +#ifdef ENABLE_MRR + +#include +#include "libOTe/TwoChooseOne/OTExtInterface.h" +#include +#include +#include +#include +#include + +#include "libOTe/Tools/Popf/FeistelRistPopf.h" +#include "libOTe/Tools/Popf/FeistelMulRistPopf.h" + +#if !(defined(ENABLE_SODIUM) || defined(ENABLE_RELIC)) +static_assert(0, "ENABLE_SODIUM or ENABLE_RELIC must be defined to build McRosRoy"); +#endif +#include "libOTe/Tools/DefaultCurve.h" + +namespace osuCrypto +{ + namespace details + { + // The Popf's PopfFunc must be plain old data, PopfIn must be convertible from an integer, and + // PopfOut must be a DefaultCurve::Point. + template + class McRosRoy : public OtReceiver, public OtSender + { + using Curve = DefaultCurve::Curve; + using Point = DefaultCurve::Point; + using Number = DefaultCurve::Number; + + public: + typedef DSPopf PopfFactory; + + McRosRoy() = default; + McRosRoy(const PopfFactory& p) : popfFactory(p) {} + McRosRoy(PopfFactory&& p) : popfFactory(p) {} + + void receive( + const BitVector& choices, + span messages, + PRNG& prng, + Channel& chl, + u64 numThreads) + { + receive(choices, messages, prng, chl); + } + + void send( + span> messages, + PRNG& prng, + Channel& chl, + u64 numThreads) + { + send(messages, prng, chl); + } + + void receive( + const BitVector& choices, + span messages, + PRNG& prng, + Channel& chl) override; + + void send( + span> messages, + PRNG& prng, + Channel& chl) override; + + static_assert(std::is_pod::value, + "Popf function must be Plain Old Data"); + static_assert(std::is_same::value, + "Popf must be programmable on elliptic curve points"); + + private: + PopfFactory popfFactory; + }; + + + } + + // The McQuoid Rosulek Roy OT protocol over the main and twisted curve + // with the Feistel Popf impl. See https://eprint.iacr.org/2021/682 + using McRosRoy = details::McRosRoy; + + // The McQuoid Rosulek Roy OT protocol over the main and twisted curve + // with the streamlined Feistel Popf impl. See https://eprint.iacr.org/2021/682 + using McRosRoyMul = details::McRosRoy; + + + /////////////////////////////////////////////////////////////////////////////// + /// impl + /////////////////////////////////////////////////////////////////////////////// + + namespace details + { + + + template + void McRosRoy::receive( + const BitVector& choices, + span messages, + PRNG& prng, + Channel& chl) + { + Curve curve; + + u64 n = choices.size(); + std::vector sk; sk.reserve(n); + + unsigned char recvBuff[Point::size]; + auto recvDone = chl.asyncRecv(recvBuff, Point::size); + + std::vector sendBuff(n); + + for (u64 i = 0; i < n; ++i) + { + auto factory = popfFactory; + factory.Update(i); + auto popf = factory.construct(); + + sk.emplace_back(prng); + Point B = Point::mulGenerator(sk[i]); + + sendBuff[i] = popf.program(choices[i], std::move(B), prng); + } + + chl.asyncSend(std::move(sendBuff)); + + recvDone.wait(); + Point A; + A.fromBytes(recvBuff); + + for (u64 i = 0; i < n; ++i) + { + Point B = A * sk[i]; + + RandomOracle ro(sizeof(block)); + ro.Update(B); + ro.Update(i); + ro.Update((bool)choices[i]); + ro.Final(messages[i]); + } + } + + template + void McRosRoy::send( + span> msg, + PRNG& prng, + Channel& chl) + { + Curve curve; + + u64 n = static_cast(msg.size()); + + Number sk(prng); + Point A = Point::mulGenerator(sk); + + unsigned char sendBuff[Point::size]; + A.toBytes(sendBuff); + chl.asyncSend(sendBuff, Point::size); + + std::vector recvBuff(n); + chl.recv(recvBuff.data(), recvBuff.size()); + + for (u64 i = 0; i < n; ++i) + { + auto factory = popfFactory; + factory.Update(i); + auto popf = factory.construct(); + + Point Bz = popf.eval(recvBuff[i], 0); + Point Bo = popf.eval(recvBuff[i], 1); + + Bz *= sk; + Bo *= sk; + + RandomOracle ro(sizeof(block)); + ro.Update(Bz); + ro.Update(i); + ro.Update((bool)0); + ro.Final(msg[i][0]); + + ro.Reset(); + ro.Update(Bo); + ro.Update(i); + ro.Update((bool)1); + ro.Final(msg[i][1]); + } + } + } +} + +#endif diff --git a/libOTe/Base/McRosRoyTwist.h b/libOTe/Base/McRosRoyTwist.h new file mode 100644 index 00000000..0b541986 --- /dev/null +++ b/libOTe/Base/McRosRoyTwist.h @@ -0,0 +1,262 @@ +#pragma once +#include "libOTe/config.h" +#ifdef ENABLE_MRR_TWIST + +#include +#include "libOTe/TwoChooseOne/OTExtInterface.h" +#include +#include +#include +#include +#include +#include + +#include "libOTe/Tools/Popf/EKEPopf.h" +#include "libOTe/Tools/Popf/FeistelMulPopf.h" +#include "libOTe/Tools/Popf/FeistelPopf.h" +#include "libOTe/Tools/Popf/MRPopf.h" + +#include +#ifndef ENABLE_SODIUM +static_assert(0, "ENABLE_SODIUM must be defined to build McRosRoyTwist"); +#endif +#ifndef SODIUM_MONTGOMERY +static_assert(0, "SODIUM_MONTGOMERY must be defined to build McRosRoyTwist"); +#endif + +namespace osuCrypto +{ + namespace details + { + // Popf classes should looks something like this: + /* + class Popf + { + public: + typedef ... PopfFunc; + typedef ... PopfIn; + typedef ... PopfOut; + + PopfOut eval(PopfFunc f, PopfIn x) const; + PopfFunc program(PopfIn x, PopfOut y, PRNG& prng) const; + PopfFunc program(PopfIn x, PopfOut y) const; // If program is possible without prng. + }; + */ + + // A factory to create a Popf from a RO should look something like this: + /* + class RODomainSeparatedPopf: public RandomOracle + { + using RandomOracle::Final; + using RandomOracle::outputLength; + + public: + typedef ... ConstructedPopf; + + ConstructedPopf construct(); + }; + */ + + // The Popf's PopfFunc must be plain old data, PopfIn must be convertible from an integer, and + // PopfOut must be a Block256. + template + class McRosRoyTwist : public OtReceiver, public OtSender + { + public: + typedef DSPopf PopfFactory; + + McRosRoyTwist() = default; + McRosRoyTwist(const PopfFactory& p) : popfFactory(p) {} + McRosRoyTwist(PopfFactory&& p) : popfFactory(p) {} + + void receive( + const BitVector& choices, + span messages, + PRNG& prng, + Channel& chl, + u64 numThreads); + + void send( + span> messages, + PRNG& prng, + Channel& chl, + u64 numThreads); + + void receive( + const BitVector& choices, + span messages, + PRNG& prng, + Channel& chl) override; + + void send( + span> messages, + PRNG& prng, + Channel& chl) override; + + static_assert(std::is_pod::value, + "Popf function must be Plain Old Data"); + static_assert(std::is_same::value, + "Popf must be programmable on 256-bit blocks"); + + private: + PopfFactory popfFactory; + + using Monty25519 = Sodium::Monty25519; + using Scalar25519 = Sodium::Scalar25519; + + Monty25519 blockToCurve(Block256 b); + Block256 curveToBlock(Monty25519 p, PRNG& prng); + }; + } + //DomainSepEKEPopf requires SSE +#ifdef ENABLE_SSE + // The McQuoid Rosulek Roy OT protocol over the main and twisted curve + // with the EKE Popf impl. See https://eprint.iacr.org/2021/682 + using McRosRoyTwist = details::McRosRoyTwist; +#endif + + // The McQuoid Rosulek Roy OT protocol over the main and twisted curve + // with the Feistel Popf impl. See https://eprint.iacr.org/2021/682 + using McRosRoyTwistFeistel = details::McRosRoyTwist; + + // The McQuoid Rosulek Roy OT protocol over the main and twisted curve + // with the streamlined Feistel Popf impl. See https://eprint.iacr.org/2021/682 + using McRosRoyTwistMul = details::McRosRoyTwist; + + // The McQuoid Rosulek Roy OT protocol over the main and twisted curve + // with the Masney Rindal Popf impl. See https://eprint.iacr.org/2021/682 + using McRosRoyTwistMR = details::McRosRoyTwist; + + + + + + + /////////////////////////////////////////////////////////////////////////////// + /// impl + /////////////////////////////////////////////////////////////////////////////// + + + namespace details + { + template + inline void McRosRoyTwist::receive(const BitVector& choices, span messages, PRNG& prng, Channel& chl, u64 numThreads) + { + receive(choices, messages, prng, chl); + } + + template + inline void McRosRoyTwist::send(span> messages, PRNG& prng, Channel& chl, u64 numThreads) + { + send(messages, prng, chl); + } + + template + inline void McRosRoyTwist::receive(const BitVector& choices, span messages, PRNG& prng, Channel& chl) + { + u64 n = choices.size(); + + std::vector sk; sk.reserve(n); + std::vector curveChoice; curveChoice.reserve(n); + + Monty25519 A[2]; + auto recvDone = chl.asyncRecv(A, 2); + + std::vector sendBuff(n); + + for (u64 i = 0; i < n; ++i) + { + auto factory = popfFactory; + factory.Update(i); + auto popf = factory.construct(); + + curveChoice.emplace_back(prng.getBit()); + sk.emplace_back(prng, false); + Monty25519 g = (curveChoice[i] == 0) ? + Monty25519::wholeGroupGenerator : Monty25519::wholeTwistGroupGenerator; + Monty25519 B = g * sk[i]; + + sendBuff[i] = popf.program(choices[i], curveToBlock(B, prng), prng); + } + + chl.asyncSend(std::move(sendBuff)); + + recvDone.wait(); + + for (u64 i = 0; i < n; ++i) + { + Monty25519 B = A[curveChoice[i]] * sk[i]; + + RandomOracle ro(sizeof(block)); + ro.Update(B); + ro.Update(i); + ro.Update((bool)choices[i]); + ro.Final(messages[i]); + } + } + + template + inline void McRosRoyTwist::send(span> msg, PRNG& prng, Channel& chl) + { + u64 n = static_cast(msg.size()); + + Scalar25519 sk(prng); + Monty25519 A[2] = { + Monty25519::wholeGroupGenerator * sk, Monty25519::wholeTwistGroupGenerator * sk }; + + chl.asyncSend(A, 2); + + std::vector recvBuff(n); + chl.recv(recvBuff.data(), recvBuff.size()); + + + Monty25519 Bz, Bo; + for (u64 i = 0; i < n; ++i) + { + auto factory = popfFactory; + factory.Update(i); + auto popf = factory.construct(); + + Bz = blockToCurve(popf.eval(recvBuff[i], 0)); + Bo = blockToCurve(popf.eval(recvBuff[i], 1)); + + // We don't need to check which curve we're on since we use the same secret for both. + Bz *= sk; + Bo *= sk; + + RandomOracle ro(sizeof(block)); + ro.Update(Bz); + ro.Update(i); + ro.Update((bool)0); + ro.Final(msg[i][0]); + + ro.Reset(); + ro.Update(Bo); + ro.Update(i); + ro.Update((bool)1); + ro.Final(msg[i][1]); + } + } + template + inline typename McRosRoyTwist::Monty25519 McRosRoyTwist::blockToCurve(Block256 b) + { + static_assert(Monty25519::size == sizeof(Block256), ""); + return Monty25519(b.data()); + } + template + inline Block256 McRosRoyTwist::curveToBlock(Monty25519 p, PRNG& prng) + { + p.data[Monty25519::size - 1] ^= prng.getBit() << 7; + + static_assert(Monty25519::size == sizeof(Block256), ""); + return Block256(p.data); + } + } + + + + + +} + +#endif diff --git a/libOTe/Base/SimplestOT.cpp b/libOTe/Base/SimplestOT.cpp index 1e7f3162..0920b1de 100644 --- a/libOTe/Base/SimplestOT.cpp +++ b/libOTe/Base/SimplestOT.cpp @@ -1,64 +1,48 @@ #include "SimplestOT.h" - +#include #include #include #include #ifdef ENABLE_SIMPLESTOT -#ifdef ENABLE_RELIC - #include -#else - #include -#endif + +#include "libOTe/Tools/DefaultCurve.h" namespace osuCrypto { - -#ifdef ENABLE_RELIC - using Curve = REllipticCurve; - using Point = REccPoint; - using Brick = REccPoint; - using Number = REccNumber; -#else - using Curve = EllipticCurve; - using Point = EccPoint; - using Brick = EccBrick; - using Number = EccNumber; -#endif - void SimplestOT::receive( const BitVector& choices, span msg, PRNG& prng, Channel& chl) { + using namespace DefaultCurve; Curve curve; - Point g = curve.getGenerator(); - u64 pointSize = g.sizeBytes(); + u64 n = msg.size(); - block comm = oc::ZeroBlock, seed; - Point A(curve); - std::vector buff(pointSize + mUniformOTs * sizeof(block)), hashBuff(pointSize); - chl.recv(buff.data(), buff.size()); - A.fromBytes(buff.data()); + u8 recvBuff[Point::size + sizeof(block)]; + chl.recv(recvBuff, Point::size + mUniformOTs * sizeof(block)); + + block comm, seed; + Point A; + A.fromBytes(recvBuff); if (mUniformOTs) - memcpy(&comm, buff.data() + pointSize, sizeof(block)); + memcpy(&comm, recvBuff + Point::size, sizeof(block)); - buff.resize(pointSize * n); - auto buffIter = buff.data(); + std::vector buff(Point::size * n); - std::vector b; b.reserve(n);; - std::array B{ curve, curve }; + std::vector b; b.reserve(n); + std::array B; for (u64 i = 0; i < n; ++i) { - b.emplace_back(curve, prng); - B[0] = g * b[i]; + b.emplace_back(prng); + B[0] = Point::mulGenerator(b[i]); B[1] = A + B[0]; - B[choices[i]].toBytes(buffIter); buffIter += pointSize; + B[choices[i]].toBytes(&buff[Point::size * i]); } chl.asyncSend(std::move(buff)); @@ -72,9 +56,8 @@ namespace osuCrypto for (u64 i = 0; i < n; ++i) { B[0] = A * b[i]; - B[0].toBytes(hashBuff.data()); RandomOracle ro(sizeof(block)); - ro.Update(hashBuff.data(), hashBuff.size()); + ro.Update(B[0]); ro.Update(i); if (mUniformOTs) ro.Update(seed); ro.Final(msg[i]); @@ -86,27 +69,30 @@ namespace osuCrypto PRNG& prng, Channel& chl) { + using namespace DefaultCurve; Curve curve; - Point g = curve.getGenerator(); - u64 pointSize = g.sizeBytes(); + u64 n = msg.size(); - block seed = prng.get(); - Number a(curve, prng); - Point A = g * a; - std::vector buff(pointSize + mUniformOTs * sizeof(block)), hashBuff(pointSize); - A.toBytes(buff.data()); + Number a(prng); + Point A = Point::mulGenerator(a); + Point B; + + u8 sendBuff[Point::size + sizeof(block)]; + A.toBytes(sendBuff); + block seed; if (mUniformOTs) { // commit to the seed + seed = prng.get(); auto comm = mAesFixedKey.ecbEncBlock(seed) ^ seed; - memcpy(buff.data() + pointSize, &comm, sizeof(block)); + memcpy(sendBuff + Point::size, &comm, sizeof(block)); } - chl.asyncSend(std::move(buff)); + chl.asyncSend(sendBuff, Point::size + mUniformOTs * sizeof(block)); - buff.resize(pointSize * n); + std::vector buff(Point::size * n); chl.recv(buff.data(), buff.size()); if (mUniformOTs) @@ -115,26 +101,21 @@ namespace osuCrypto chl.send(seed); } - auto buffIter = buff.data(); - A *= a; - Point B(curve), Ba(curve); for (u64 i = 0; i < n; ++i) { - B.fromBytes(buffIter); buffIter += pointSize; + B.fromBytes(&buff[Point::size * i]); - Ba = B * a; - Ba.toBytes(hashBuff.data()); + B *= a; RandomOracle ro(sizeof(block)); - ro.Update(hashBuff.data(), hashBuff.size()); + ro.Update(B); ro.Update(i); if (mUniformOTs) ro.Update(seed); ro.Final(msg[i][0]); - Ba -= A; - Ba.toBytes(hashBuff.data()); + B -= A; ro.Reset(); - ro.Update(hashBuff.data(), hashBuff.size()); + ro.Update(B); ro.Update(i); if (mUniformOTs) ro.Update(seed); ro.Final(msg[i][1]); @@ -146,11 +127,11 @@ namespace osuCrypto #ifdef ENABLE_SIMPLESTOT_ASM extern "C" { - #include "../SimplestOT/ot_sender.h" - #include "../SimplestOT/ot_receiver.h" - #include "../SimplestOT/ot_config.h" - #include "../SimplestOT/cpucycles.h" - #include "../SimplestOT/randombytes.h" + #include "SimplestOT/ot_sender.h" + #include "SimplestOT/ot_receiver.h" + #include "SimplestOT/ot_config.h" + #include "SimplestOT/cpucycles.h" + #include "SimplestOT/randombytes.h" } namespace osuCrypto { @@ -191,7 +172,7 @@ namespace osuCrypto for (u32 j = 0; j < min; j++) cs[j] = choices[i + j]; - + receiver_rsgen(&receiver, Rs_pack, cs, rand); chl.asyncSendCopy(Rs_pack, sizeof(Rs_pack)); receiver_keygen(&receiver, keys); @@ -231,7 +212,3 @@ namespace osuCrypto } } #endif - - - - diff --git a/libOTe/Base/SimplestOT.h b/libOTe/Base/SimplestOT.h index b0544769..62a357d5 100644 --- a/libOTe/Base/SimplestOT.h +++ b/libOTe/Base/SimplestOT.h @@ -18,8 +18,8 @@ namespace osuCrypto #if defined(ENABLE_SIMPLESTOT) //#if defined(_MSC_VER) //# error "asm base simplest OT and windows is incompatible." -#if !(defined(ENABLE_RELIC) || defined(ENABLE_MIRACL)) -# error "Non-asm base Simplest OT requires Relic or Miracl" +#if !(defined(ENABLE_SODIUM) || defined(ENABLE_RELIC)) +# error "Non-asm base Simplest OT requires libsodium or Relic" #endif class SimplestOT : public OtReceiver, public OtSender @@ -110,4 +110,4 @@ namespace osuCrypto }; #endif -} \ No newline at end of file +} diff --git a/libOTe/Base/naor-pinkas.cpp b/libOTe/Base/naor-pinkas.cpp index 2b9b1a5b..65747322 100644 --- a/libOTe/Base/naor-pinkas.cpp +++ b/libOTe/Base/naor-pinkas.cpp @@ -5,33 +5,16 @@ #include #include #include - -#include - - -#include +#include "libOTe/Tools/DefaultCurve.h" #define PARALLEL - #ifdef ENABLE_NP #include namespace osuCrypto { - -#ifdef ENABLE_RELIC - using Curve = REllipticCurve; - using Point = REccPoint; - using Brick = REccPoint; - using Number = REccNumber; -#else - using Curve = EllipticCurve; - using Point = EccPoint; - using Brick = EccBrick; - using Number = EccNumber; -#endif //static const u64 minMsgPerThread(16); NaorPinkas::NaorPinkas() @@ -53,23 +36,23 @@ namespace osuCrypto Channel& socket, u64 numThreads) { - // should generalize to 1 out of N by changing this. But isn't tested... - auto nSndVals(2); + using namespace DefaultCurve; Curve curve; - auto g = curve.getGenerator(); - u64 fieldElementSize = g.sizeBytes(); + + // should generalize to 1 out of N by changing this. But isn't tested... + const auto nSndVals(2); + const auto pointSize = Point::size; std::vector thrds(numThreads); - std::vector sendBuff(messages.size() * fieldElementSize); + std::vector sendBuff(messages.size() * pointSize); std::atomic remainingPK0s((u32)numThreads); - std::promise PK0Prom; - std::future PK0Furture(PK0Prom.get_future()); - std::vector cBuff(nSndVals * fieldElementSize); + + std::vector cBuff(nSndVals * pointSize); auto cRecvFuture = socket.asyncRecv(cBuff.data(), cBuff.size()).share(); block R; std::array comm, comm2; - socket.asyncRecv(comm); + auto commFuture = socket.asyncRecv(comm); auto RFuture = socket.asyncRecv(R).share(); for (u64 t = 0; t < numThreads; ++t) @@ -77,22 +60,17 @@ namespace osuCrypto auto seed = prng.get(); thrds[t] = std::thread( - [t, numThreads, &messages, seed, + [t, numThreads, &messages, seed, pointSize, &sendBuff, &choices, cRecvFuture, &cBuff, - &remainingPK0s, &PK0Prom, nSndVals,&RFuture,&R]() + &remainingPK0s, &socket, nSndVals,&RFuture,&R]() { auto mStart = t * messages.size() / numThreads; auto mEnd = (t + 1) * messages.size() / numThreads; PRNG prng(seed); - Curve curve; - - auto g = curve.getGenerator(); - u64 fieldElementSize = g.sizeBytes(); - Point PK0(curve); - Brick bg(g); + Curve curve; std::vector pK; std::vector @@ -106,83 +84,60 @@ namespace osuCrypto for (u64 i = mStart, j = 0; i < mEnd; ++i, ++j) { // get a random value from Z_p - pK.emplace_back(curve); - pK[j].randomize(prng); + pK.emplace_back(prng); - // using brickexp which has the base of g, compute + // compute // // PK_sigma[i] = g ^ pK[i] // // where pK[i] is just a random number in Z_p - PK_sigma.emplace_back(curve); - PK_sigma[j] = bg * pK[j]; + PK_sigma.emplace_back(Point::mulGenerator(pK[j])); } - cRecvFuture.get(); - auto pBufIdx = cBuff.begin(); for (auto u = 0; u < nSndVals; u++) { - pC.emplace_back(curve); - - pC[u].fromBytes(&*pBufIdx); - pBufIdx += fieldElementSize; + pC.emplace_back(); + pC[u].fromBytes(&cBuff[pointSize * u]); } - auto iter = sendBuff.data() + mStart * fieldElementSize; - for (u64 i = mStart, j = 0; i < mEnd; ++i, ++j) { u8 choice = choices[i]; + Point PK0 = std::move(PK_sigma[j]); if (choice != 0) { - PK0 = pC[choice] - PK_sigma[j]; - } - else { - PK0 = PK_sigma[j]; + PK0 = pC[choice] - PK0; } - PK0.toBytes(iter); - iter += fieldElementSize; + PK0.toBytes(&sendBuff[pointSize * i]); } if (--remainingPK0s == 0) - PK0Prom.set_value(); - - // resuse this space, not the data of PK0... - auto& gka = PK0; - RandomOracle sha(sizeof(block)); + socket.asyncSend(std::move(sendBuff)); - std::vectorbuff(fieldElementSize); - Brick bc(pC[0]); + RandomOracle ro(sizeof(block)); RFuture.get(); - for (u64 i = mStart, j = 0; i < mEnd; ++i, ++j) { // now compute g ^(a * k) = (g^a)^k - gka = bc * pK[j]; - gka.toBytes(buff.data()); - + Point gka = pC[0] * pK[j]; auto nounce = i * nSndVals + choices[i]; - sha.Reset(); - sha.Update((u8*)&nounce, sizeof(nounce)); - sha.Update(buff.data(), buff.size()); - sha.Update(R); - sha.Final(messages[i]); + ro.Reset(); + ro.Update((u8*)&nounce, sizeof(nounce)); + ro.Update(gka); + ro.Update(R); + ro.Final(messages[i]); } - }); + }); } - PK0Furture.get(); - - socket.asyncSend(std::move(sendBuff)); - for (auto& thrd : thrds) thrd.join(); - //block comm = *(block*)(cBuff.data() + nSndVals * fieldElementSize); + commFuture.get(); RandomOracle ro; ro.Update(R); ro.Final(comm2); @@ -198,36 +153,35 @@ namespace osuCrypto Channel& socket, u64 numThreads) { + using namespace DefaultCurve; + Curve curve; + block R = prng.get(); // one out of nSndVals OT. u64 nSndVals(2); std::vector thrds(numThreads); - auto seed = prng.get(); - Curve curve; - Number alpha(curve, prng), tmp(curve); - const Point g = curve.getGenerator(); - u64 fieldElementSize = g.sizeBytes(); - std::vector sendBuff(nSndVals * fieldElementSize); + //auto seed = prng.get(); + + Number alpha(prng); + const auto pointSize = Point::size; std::vector pC; pC.reserve(nSndVals); + pC.emplace_back(Point::mulGenerator(alpha)); - pC.emplace_back(curve); - pC[0] = g * alpha; + std::vector sendBuff(nSndVals * pointSize); pC[0].toBytes(sendBuff.data()); for (u64 u = 1; u < nSndVals; u++) { - pC.emplace_back(curve); - tmp.randomize(prng); - - pC[u] = g * tmp; - pC[u].toBytes(sendBuff.data() + u * fieldElementSize); + // TODO: Faster to use hash to curve to randomize? + pC.emplace_back(Point::mulGenerator(Number(prng))); + pC[u].toBytes(&sendBuff[pointSize * u]); } socket.asyncSend(std::move(sendBuff)); - // sends a commitment to R. This strengthens the security of NP01 to + // sends a commitment to R. This strengthens the security of NP01 to // make the protocol output uniform strings no matter what. RandomOracle ro; std::vector comm(RandomOracle::HashSize); @@ -237,34 +191,27 @@ namespace osuCrypto for (u64 u = 1; u < nSndVals; u++) - pC[u] = pC[u] * alpha; + pC[u] *= alpha; - std::vector buff(fieldElementSize * messages.size()); + std::vector buff(pointSize * messages.size()); auto recvFuture = socket.asyncRecv(buff.data(), buff.size()).share(); for (u64 t = 0; t < numThreads; ++t) { thrds[t] = std::thread([ - t, seed, fieldElementSize, &messages, recvFuture, + t, pointSize, &messages, recvFuture, numThreads, &buff, &alpha, nSndVals, &pC,&socket,&R]() { Curve curve; - Point pPK0(curve), PK0a(curve), fetmp(curve); - Number alpha2(curve, alpha); - - std::vector c; - c.reserve(nSndVals); - for (u64 i = 0; i < nSndVals; ++i) - c.emplace_back(curve, pC[i]); + Point pPK0; - std::vector hashInBuff(fieldElementSize); - RandomOracle sha(sizeof(block)); + RandomOracle ro(sizeof(block)); recvFuture.get(); if (t == 0) socket.asyncSendCopy(R); - + auto mStart = t * messages.size() / numThreads; auto mEnd = (t + 1) * messages.size() / numThreads; @@ -272,29 +219,27 @@ namespace osuCrypto for (u64 i = mStart; i < mEnd; i++) { - pPK0.fromBytes(buff.data() + i * fieldElementSize); - PK0a = pPK0 * alpha2; - PK0a.toBytes(hashInBuff.data()); + pPK0.fromBytes(&buff[pointSize * i]); + pPK0 *= alpha; auto nounce = i * nSndVals; - sha.Reset(); - sha.Update((u8*)&nounce, sizeof(nounce)); - sha.Update(hashInBuff.data(), hashInBuff.size()); - sha.Update(R); - sha.Final(messages[i][0]); + ro.Reset(); + ro.Update((u8*)&nounce, sizeof(nounce)); + ro.Update(pPK0); + ro.Update(R); + ro.Final(messages[i][0]); for (u64 u = 1; u < nSndVals; u++) { - fetmp = c[u] - PK0a; - fetmp.toBytes(hashInBuff.data()); + Point fetmp = pC[u] - pPK0; ++nounce; - sha.Reset(); - sha.Update((u8*)&nounce, sizeof(nounce)); - sha.Update(hashInBuff.data(), hashInBuff.size()); - sha.Update(R); - sha.Final(messages[i][u]); + ro.Reset(); + ro.Update((u8*)&nounce, sizeof(nounce)); + ro.Update(fetmp); + ro.Update(R); + ro.Final(messages[i][u]); } } }); diff --git a/libOTe/Base/naor-pinkas.h b/libOTe/Base/naor-pinkas.h index feec6f72..554b54da 100644 --- a/libOTe/Base/naor-pinkas.h +++ b/libOTe/Base/naor-pinkas.h @@ -1,5 +1,5 @@ #pragma once -// This file and the associated implementation has been placed in the public domain, waiving all copyright. No restrictions are placed on its use. +// This file and the associated implementation has been placed in the public domain, waiving all copyright. No restrictions are placed on its use. #include "libOTe/config.h" #include "libOTe/TwoChooseOne/OTExtInterface.h" #include @@ -7,8 +7,8 @@ #ifdef ENABLE_NP -#if !defined ENABLE_RELIC && !defined ENABLE_MIRACL - #error "NaorPinkas requires with Relic or Miracl to be enabled."; +#if !(defined(ENABLE_SODIUM) || defined(ENABLE_RELIC)) +#error "NaorPinkas requires libsodium or Relic to be enabled" #endif namespace osuCrypto @@ -19,20 +19,20 @@ namespace osuCrypto public: NaorPinkas(); - ~NaorPinkas(); + ~NaorPinkas(); void receive( - const BitVector& choices, + const BitVector& choices, span messages, - PRNG& prng, - Channel& chl, + PRNG& prng, + Channel& chl, u64 numThreads); void send( - span> messages, - PRNG& prng, - Channel& sock, + span> messages, + PRNG& prng, + Channel& sock, u64 numThreads); void receive( @@ -54,4 +54,4 @@ namespace osuCrypto }; } -#endif \ No newline at end of file +#endif diff --git a/libOTe/CMakeLists.txt b/libOTe/CMakeLists.txt index 209935bf..cb8a4c43 100644 --- a/libOTe/CMakeLists.txt +++ b/libOTe/CMakeLists.txt @@ -1,18 +1,34 @@ enable_language(ASM) -file(GLOB_RECURSE SRCS *.cpp) +file(GLOB_RECURSE SRCS *.cpp *.c) set(SRCS "${SRCS}") add_library(libOTe STATIC ${SRCS}) -target_include_directories(libOTe PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..) + +# make projects that include libOTe use this as an include folder +target_include_directories(libOTe PUBLIC + $ + $) +target_include_directories(libOTe PUBLIC + $ + $) + + target_link_libraries(libOTe cryptoTools) -if(ENABLE_SSE) - target_compile_options(libOTe PRIVATE -maes -msse2 -msse3 -msse4.1 -mpclmul) -endif() +if(MSVC) + #target_compile_options(libOTe PRIVATE -openmp:experimental) +else() + if(ENABLE_SSE) + target_compile_options(libOTe PRIVATE -maes -msse2 -msse3 -msse4.1 -mpclmul) + endif() +endif() +if (ENABLE_BITPOLYMUL) + target_link_libraries(libOTe bitpolymul) +endif () if(ENABLE_SIMPLESTOT_ASM) target_link_libraries(libOTe SimplestOT) #target_compile_options(libOTe PRIVATE -fPIC -no-pie) @@ -20,7 +36,8 @@ endif() if(ENABLE_MR_KYBER) target_link_libraries(libOTe KyberOT) -endif(ENABLE_MR_KYBER) +endif() + ############################################# @@ -28,7 +45,7 @@ endif(ENABLE_MR_KYBER) ############################################# # install library -install(TARGETS libOTe DESTINATION lib) +#install(TARGETS libOTe DESTINATION lib) # install headers -install(DIRECTORY . DESTINATION include/libOTe FILES_MATCHING PATTERN "*.h") +#install(DIRECTORY . DESTINATION include/libOTe FILES_MATCHING PATTERN "*.h") diff --git a/libOTe/NChooseK/AknOtReceiver.cpp b/libOTe/NChooseK/AknOtReceiver.cpp index 7f710032..ca29cff3 100644 --- a/libOTe/NChooseK/AknOtReceiver.cpp +++ b/libOTe/NChooseK/AknOtReceiver.cpp @@ -233,7 +233,7 @@ namespace osuCrypto //memcpy(iter, threadsZeroOnesList[i][1].data(), threadsZeroOnesList[i][1].size() * sizeof(u64)); iter += threadsZeroOnesList[i][1].size(); } - std::random_shuffle(mOnes.begin(), mOnes.begin(), prng); + std::shuffle(mOnes.begin(), mOnes.begin(), prng); } @@ -260,7 +260,7 @@ namespace osuCrypto iter += threadsZeroOnesList[i][0].size(); } - std::random_shuffle(mZeros.begin(), mZeros.begin(), prng); + std::shuffle(mZeros.begin(), mZeros.begin(), prng); } }; @@ -273,7 +273,7 @@ namespace osuCrypto for (u64 i = 0; i < thrds.size(); ++i) { // split the OT to that it can be multi threaded. - parOts[i] = std::move(ots.split()); + parOts[i] = (ots.split()); // create a seed for it. block seed = prng.get(); diff --git a/libOTe/NChooseK/AknOtSender.cpp b/libOTe/NChooseK/AknOtSender.cpp index 50c1657e..0aac7cec 100644 --- a/libOTe/NChooseK/AknOtSender.cpp +++ b/libOTe/NChooseK/AknOtSender.cpp @@ -159,7 +159,7 @@ namespace osuCrypto for (u64 i = 0; i < parOts.size(); ++i) { - parOts[i] = std::move(ots.split()); + parOts[i] = (ots.split()); auto seed = prng.get(); parThrds[i] = std::thread([&,seed, i]() { diff --git a/libOTe/NChooseOne/Kkrt/KkrtNcoOtReceiver.cpp b/libOTe/NChooseOne/Kkrt/KkrtNcoOtReceiver.cpp index ee839c07..b6708e75 100644 --- a/libOTe/NChooseOne/Kkrt/KkrtNcoOtReceiver.cpp +++ b/libOTe/NChooseOne/Kkrt/KkrtNcoOtReceiver.cpp @@ -190,12 +190,17 @@ namespace osuCrypto } raw.setBaseOts(base); } + +#ifdef OC_NO_MOVE_ELISION return std::move(raw); +#else + return raw; +#endif } std::unique_ptr KkrtNcoOtReceiver::split() { - return std::make_unique(std::move(splitBase())); + return std::make_unique((splitBase())); } diff --git a/libOTe/NChooseOne/Kkrt/KkrtNcoOtSender.cpp b/libOTe/NChooseOne/Kkrt/KkrtNcoOtSender.cpp index b754806e..820768b0 100644 --- a/libOTe/NChooseOne/Kkrt/KkrtNcoOtSender.cpp +++ b/libOTe/NChooseOne/Kkrt/KkrtNcoOtSender.cpp @@ -57,12 +57,16 @@ namespace osuCrypto } raw.setBaseOts(base, mBaseChoiceBits); } - return std::move(raw); +#ifdef OC_NO_MOVE_ELISION + return std::move(raw); +#else + return raw; +#endif } std::unique_ptr KkrtNcoOtSender::split() { - return std::make_unique(std::move(splitBase())); + return std::make_unique((splitBase())); } void KkrtNcoOtSender::init( diff --git a/libOTe/NChooseOne/Oos/OosNcoOtReceiver.cpp b/libOTe/NChooseOne/Oos/OosNcoOtReceiver.cpp index cbb8c1d8..eec6feaf 100644 --- a/libOTe/NChooseOne/Oos/OosNcoOtReceiver.cpp +++ b/libOTe/NChooseOne/Oos/OosNcoOtReceiver.cpp @@ -194,13 +194,16 @@ namespace osuCrypto } raw.setUniformBaseOts(base); } - +#ifdef OC_NO_MOVE_ELISION return std::move(raw); +#else + return raw; +#endif } std::unique_ptr OosNcoOtReceiver::split() { - return std::make_unique(std::move(splitBase())); + return std::make_unique((splitBase())); } void OosNcoOtReceiver::encode( diff --git a/libOTe/NChooseOne/Oos/OosNcoOtReceiver.h b/libOTe/NChooseOne/Oos/OosNcoOtReceiver.h index bc5f67e7..584c33d3 100644 --- a/libOTe/NChooseOne/Oos/OosNcoOtReceiver.h +++ b/libOTe/NChooseOne/Oos/OosNcoOtReceiver.h @@ -8,6 +8,7 @@ #include "libOTe/Tools/LinearCode.h" //#include "libOTe/NChooseOne/KkrtNcoOtReceiver.h" #include +#include #ifdef GetMessage #undef GetMessage #endif @@ -76,7 +77,7 @@ namespace osuCrypto v.mHasPendingSendFuture = false; v.mHasBase = false; #ifndef NDEBUG - mEncodeFlags = std::move(mEncodeFlags); + mEncodeFlags = std::move(v.mEncodeFlags); #endif } diff --git a/libOTe/NChooseOne/Oos/OosNcoOtSender.cpp b/libOTe/NChooseOne/Oos/OosNcoOtSender.cpp index 15d20c28..aaf8d69b 100644 --- a/libOTe/NChooseOne/Oos/OosNcoOtSender.cpp +++ b/libOTe/NChooseOne/Oos/OosNcoOtSender.cpp @@ -70,13 +70,17 @@ namespace osuCrypto } raw.setUniformBaseOts(base, mBaseChoiceBits); } - return std::move(raw); +#ifdef OC_NO_MOVE_ELISION + return std::move(raw); +#else + return raw; +#endif } std::unique_ptr OosNcoOtSender::split() { - return std::make_unique(std::move(splitBase())); + return std::make_unique((splitBase())); } diff --git a/libOTe/NChooseOne/RR17/Rr17NcoOtReceiver.cpp b/libOTe/NChooseOne/RR17/Rr17NcoOtReceiver.cpp index e74ad756..cb3deb44 100644 --- a/libOTe/NChooseOne/RR17/Rr17NcoOtReceiver.cpp +++ b/libOTe/NChooseOne/RR17/Rr17NcoOtReceiver.cpp @@ -30,7 +30,11 @@ namespace osuCrypto p->mEncodeSize = mEncodeSize; p->mKos = mKos.splitBase(); +#ifdef OC_NO_MOVE_ELISION return std::move(ret); +#else + return ret; +#endif } void Rr17NcoOtReceiver::init(u64 numOtExt, PRNG& prng, Channel& chl) { diff --git a/libOTe/NChooseOne/RR17/Rr17NcoOtSender.cpp b/libOTe/NChooseOne/RR17/Rr17NcoOtSender.cpp index bf193ac3..4b14fb38 100644 --- a/libOTe/NChooseOne/RR17/Rr17NcoOtSender.cpp +++ b/libOTe/NChooseOne/RR17/Rr17NcoOtSender.cpp @@ -38,8 +38,11 @@ namespace osuCrypto // ret->setBaseOts(baseOts, mKos.mBaseChoiceBits); //} //((Rr17NcoOtSender*)ret.get()) - +#ifdef OC_NO_MOVE_ELISION return std::move(ret); +#else + return ret; +#endif } void Rr17NcoOtSender::init(u64 numOtExt, PRNG& prng, Channel& chl) diff --git a/libOTe/Tools/DefaultCurve.h b/libOTe/Tools/DefaultCurve.h new file mode 100644 index 00000000..9ccdd4d4 --- /dev/null +++ b/libOTe/Tools/DefaultCurve.h @@ -0,0 +1,32 @@ +#pragma once + +#include "libOTe/config.h" +#include + +#if defined(ENABLE_SODIUM) || defined(ENABLE_RELIC) + +#if defined(ENABLE_SODIUM) +#include +#elif defined(ENABLE_RELIC) +#include +#endif + +namespace osuCrypto +{ + // Declare aliases for the default elliptic curve implementation. + namespace DefaultCurve + { +#if defined(ENABLE_SODIUM) + using Point = Sodium::Rist25519; + using Number = Sodium::Prime25519; + // Allow declaring a Curve variable. Constructor is to suppress unused variable warnings. + struct Curve { Curve() {} }; +#elif defined(ENABLE_RELIC) + using Curve = REllipticCurve; + using Point = REccPoint; + using Number = REccNumber; +#endif + } +} + +#endif diff --git a/libOTe/Tools/LDPC/Mtx.cpp b/libOTe/Tools/LDPC/Mtx.cpp new file mode 100644 index 00000000..05f3f580 --- /dev/null +++ b/libOTe/Tools/LDPC/Mtx.cpp @@ -0,0 +1,1547 @@ +#include "Mtx.h" +#include "cryptoTools/Crypto/PRNG.h" +#include "Util.h" +#include "cryptoTools/Common/Matrix.h" + +namespace osuCrypto +{ + + + // add the given point. SHould not have previously been added. + PointList::PointList(u64 r, u64 c, span pp) + : mRows(r), mCols(c) + { + for (auto p : pp) + push_back(p); + } + + void PointList::push_back(const Point& p) + { + if (p.mRow >= mRows) + { + std::cout << "row out of bounds " << p.mRow << " / " << mRows << std::endl; + throw RTE_LOC; + } + + if (p.mCol >= mCols) + { + std::cout << "col out of bounds " << p.mCol << " / " << mCols << std::endl; + throw RTE_LOC; + } +#ifndef NDEBUG + if (ss.insert({ p.mRow , p.mCol }).second == false) + { + std::cout << "duplicate (" << p.mRow << ", " << p.mCol << ") " << std::endl; + throw RTE_LOC; + } +#endif + mPoints.push_back(p); + } + + // hash the matrix. will return the same value + // as hash for DenseMtx if they are equal. + block SparseMtx::hash() const + { + oc::RandomOracle ro(sizeof(block)); + for (u64 i = 0; i < rows(); ++i) + { + for (auto j : row(i)) + { + ro.Update(j); + } + + ro.Update(i); + u64 jj = -1; + ro.Update(jj); + } + + block b; + ro.Final(b); + return b; + } + + void SparseMtx::init(u64 rows, u64 cols, span points) + { + std::vector rowSizes(rows); + std::vector colSizes(cols); + +#define OC_INSERT_DEBUG +#ifdef OC_INSERT_DEBUG + std::set> set; +#endif // !NDEBUG + + for (u64 i = 0; i < u64(points.size()); ++i) + { +#ifdef OC_INSERT_DEBUG + auto s = set.insert({ points[i].mRow , points[i].mCol }); + + if (!s.second) + { + std::cout << "dup " << points[i].mRow << " " << points[i].mCol << std::endl; + abort(); + } + + if (points[i].mRow >= rows) + { + std::cout << "row out of bounds " << points[i].mRow << " " << rows << std::endl; + abort(); + } + if (points[i].mCol >= cols) + { + std::cout << "col out of bounds " << points[i].mCol << " " << cols << std::endl; + abort(); + } +#endif + ++rowSizes[points[i].mRow]; + ++colSizes[points[i].mCol]; + + } + + mRows.resize(rows); + mCols.resize(cols); + mDataRow.resize(points.size()); + mDataCol.resize(points.size()); + auto iter = mDataRow.data(); + for (u64 i = 0; i < rows; ++i) + { + mRows[i] = Row(span(iter, iter + rowSizes[i])); + iter += rowSizes[i]; + rowSizes[i] = 0; + } + + iter = mDataCol.data(); + for (u64 i = 0; i < cols; ++i) + { + mCols[i] = Col(span(iter, iter + colSizes[i])); + iter += colSizes[i]; + colSizes[i] = 0; + } + + for (u64 i = 0; i < u64(points.size()); ++i) + { + auto r = points[i].mRow; + auto c = points[i].mCol; + auto j = rowSizes[r]++; + mRows[r][j] = c; + auto k = colSizes[c]++; + mCols[c][k] = r; + } + + for (u64 i = 0; i < rows; ++i) + { + std::sort(row(i).begin(), row(i).end()); + } + for (u64 i = 0; i < cols; ++i) + { + std::sort(col(i).begin(), col(i).end()); + } + +#ifndef NDEBUG + for (u64 i = 0; i < u64(points.size()); ++i) + { + auto row = mRows[points[i].mRow]; + auto col = mCols[points[i].mCol]; + assert(std::find(row.begin(), row.end(), points[i].mCol) != row.end()); + assert(std::find(col.begin(), col.end(), points[i].mRow) != col.end()); + } +#endif + } + + // return true if the coordinate is set. + + bool SparseMtx::isSet(u64 row, u64 col) + { + assert(row < rows()); + assert(col < cols()); + + auto iter = std::lower_bound( + mCols[col].begin(), + mCols[col].end(), + row); + return iter != mCols[col].end() && *iter == row; + } + + // check that the sparse matrix is well formed. + + bool SparseMtx::validate() + { + std::vector::iterator> colIters(cols()); + for (u64 i = 0; i < cols(); ++i) + { + colIters[i] = mCols[i].begin(); + } + + for (u64 i = 0; i < rows(); ++i) + { + if (!std::is_sorted(mRows[i].begin(), mRows[i].end())) + return false; + + for (auto cc : mRows[i]) + { + if (cc >= cols()) + return false; + if (colIters[cc] == mCols[cc].end()) + return false; + + if (*colIters[cc] != i) + return false; + + ++colIters[cc]; + } + } + + return true; + } + + // vertically concatinate this matrix and the parameter. + // this matrix will come first. The result is returned. + + SparseMtx SparseMtx::vConcat(const SparseMtx& o) const + { + if (cols() != o.cols()) + throw RTE_LOC; + + PointList pPnts = *this; + pPnts.mRows += o.rows(); + for (auto p : o.points()) + { + pPnts.push_back({ p.mRow + rows(), p.mCol }); + } + + return pPnts; + } + + SparseMtx SparseMtx::subMatrix(u64 row, u64 col, u64 rowCount, u64 colCount)const + { + if (rowCount == 0 || colCount == 0) + return {}; + + SparseMtx R; + + auto rEnd = row + rowCount; + auto cEnd = col + colCount; + + assert(rows() > row); + assert(rows() >= rEnd); + assert(cols() > col); + assert(cols() >= cEnd); + + u64 total = 0; + std::vector::iterator, 2>> rowIters(rEnd - row); + std::vector::iterator, 2>> colIters(cEnd - col); + + for (u64 i = row, ii = 0; i < rEnd; ++i, ++ii) + { + auto& rowi = mRows[i]; + auto iter = std::lower_bound(rowi.begin(), rowi.end(), col); + auto end = std::lower_bound(iter, rowi.end(), cEnd); + + rowIters[ii][0] = iter; + rowIters[ii][1] = end; + +#ifndef NDEBUG + for (auto c : span(iter, end)) + { + assert(c < cols()); + assert(c - col < colCount); + } +#endif + total += end - iter; + } + + + for (u64 i = col, ii = 0; i < cEnd; ++i, ++ii) + { + auto& coli = mCols[i]; + auto iter = std::lower_bound(coli.begin(), coli.end(), row); + auto end = std::lower_bound(iter, coli.end(), rEnd); + + colIters[ii][0] = iter; + colIters[ii][1] = end; + + +#ifndef NDEBUG + for (auto r : span(iter, end)) + { + assert(r < rows()); + assert(r - row < rowCount); + } +#endif + } + + R.mDataRow.resize(total); + R.mDataCol.resize(total); + + R.mRows.resize(rEnd - row); + R.mCols.resize(cEnd - col); + + auto iter = R.mDataRow.begin(); + for (u64 i = 0; i < rowIters.size(); ++i) + { + u64 size = (u64)std::distance(rowIters[i][0], rowIters[i][1]); + + //std::transform(rowIters[i][0], rowIters[i][1], iter, [&](const auto& src) {return src - col; }); + + for (u64 j = 0; j < size; ++j) + { + auto& cc = *(rowIters[i][0] + j); + auto& dd = *(iter + j); + dd = cc - col; + assert(dd < colCount); + } + if (size) + R.mRows[i] = Row(span(&*iter, size)); + iter += size; + } + + iter = R.mDataCol.begin(); + for (u64 i = 0; i < colIters.size(); ++i) + { + auto size = (u64)std::distance(colIters[i][0], colIters[i][1]); + //std::transform(colIters[i][0], colIters[i][1], iter, [&](const auto& src) {return src - row; }); + + for (u64 j = 0; j < size; ++j) + { + auto rr = *(colIters[i][0] + j); + *(iter + j) = rr - row; + assert(*(iter + j) < rowCount); + } + + if (size) + R.mCols[i] = Col(span(&*iter, size)); + + iter += size; + } + + assert(R.validate()); + + return R; + } + + DenseMtx SparseMtx::dense() const + { + DenseMtx mtx(rows(), cols()); + + for (u64 i = 0; i < rows(); ++i) + { + for (auto j : row(i)) + mtx(i, j) = 1; + } + + return mtx; + } + + // multiply this matrix with the given vector. + + std::vector SparseMtx::mult(span x) const + { + std::vector y(rows()); + multAdd(x, y); + return y; + } + + // multiply this matrix by x and add (xor) the result to y. + + //void SparseMtx::multAdd(span x, span y) const + //{ + // assert(cols() == x.size()); + // assert(y.size() == rows()); + // for (u64 i = 0; i < rows(); ++i) + // { + // for (auto c : row(i)) + // { + // assert(c < cols()); + // y[i] ^= x[c]; + // } + // } + //} + + // multiply this sparse matrix with y. + + SparseMtx SparseMtx::mult(const SparseMtx& X) const + { + assert(cols() == X.rows()); + + + + //SparseMtx y; + std::vector points; + //std::vector res; + for (u64 i = 0; i < rows(); ++i) + { + auto r = this->row(i); + for (u64 j = 0; j < X.cols(); ++j) + { + auto c = X.col(j); + + u64 bit = 0; + + span::iterator mIter = r.begin(); + span::iterator mEnd = r.end(); + + span::iterator xIter = c.begin(); + span::iterator xEnd = c.end(); + + while (mIter != mEnd && xIter != xEnd) + { + if (*mIter < *xIter) + ++mIter; + else if (*xIter < *mIter) + ++xIter; + else + { + bit ^= 1; + ++xIter; + ++mIter; + } + } + + if (bit) + { + points.push_back({ i,j }); + } + } + } + + return SparseMtx(rows(), X.cols(), points); + } + + SparseMtx SparseMtx::add(const SparseMtx& p) const + { + assert(rows() == p.rows()); + assert(cols() == p.cols()); + + SparseMtx r; + r.mDataCol.reserve( + p.mDataCol.size() + + mDataCol.size()); + + r.mRows.resize(rows()); + r.mCols.resize(cols()); + + u64 prev = 0; + for (u64 i = 0; i < cols(); ++i) + { + auto c0 = col(i); + auto c1 = p.col(i); + + auto b0 = c0.begin(); + auto b1 = c1.begin(); + auto e0 = c0.end(); + auto e1 = c1.end(); + + // push the non-zero loctions in order. + // skip when they are equal, i.e. 1+1=0 + while (b0 != e0 && b1 != e1) + { + if (*b0 < *b1) + r.mDataCol.push_back(*b0++); + else if (*b0 > *b1) + r.mDataCol.push_back(*b1++); + else + { + ++b0; + ++b1; + } + } + + // push any extra + while (b0 != e0) + r.mDataCol.push_back(*b0++); + while (b1 != e1) + r.mDataCol.push_back(*b1++); + + r.mCols[i] = Col(span( + r.mDataCol.begin() + prev, + r.mDataCol.end())); + + prev = r.mDataCol.size(); + } + + r.mDataRow.reserve(r.mDataCol.size()); + prev = 0; + for (u64 i = 0; i < rows(); ++i) + { + auto c0 = row(i); + auto c1 = p.row(i); + + auto b0 = c0.begin(); + auto b1 = c1.begin(); + auto e0 = c0.end(); + auto e1 = c1.end(); + + while (b0 != e0 && b1 != e1) + { + if (*b0 < *b1) + r.mDataRow.push_back(*b0++); + else if (*b0 > *b1) + r.mDataRow.push_back(*b1++); + else + { + ++b0; ++b1; + } + } + + while (b0 != e0) + r.mDataRow.push_back(*b0++); + while (b1 != e1) + r.mDataRow.push_back(*b1++); + + r.mRows[i] = Row(span( + r.mDataRow.begin() + prev, + r.mDataRow.end())); + + prev = r.mDataRow.size(); + } + + return r; + } + + SparseMtx SparseMtx::invert() const + { + auto d = dense(); + d = d.invert(); + return d.sparse(); + } + + // convert this sparse matrix into a vector of points. + + std::vector SparseMtx::points() const + { + std::vector p; p.reserve(mDataCol.size()); + for (u64 i = 0; i < rows(); ++i) + { + for (auto c : row(i)) + p.push_back({ i,c }); + } + + return p; + } + + + bool SparseMtx::operator==(const SparseMtx& X) const + { + auto eq = rows() == X.rows() && + cols() == X.cols() && + mDataCol.size() == X.mDataCol.size() && + mDataCol == X.mDataCol; + + if(eq) + { + for (u64 i = 0; i < cols(); ++i) + if (col(i).size() != X.col(i).size()) + return false; + + return true; + } + else + return false; + } + + bool SparseMtx::operator!=(const SparseMtx& X) const + { + return !(*this == X); + } + + + + std::ostream& operator<<(std::ostream& o, const SparseMtx& H) + { + for (u64 i = 0; i < H.rows(); ++i) + { + auto row = H.row(i); + for (u64 j = 0, jj = 0; j < H.cols(); ++j) + { + if (jj != (u64)row.size() && j == row[jj]) + { + if (&o == &std::cout) + o << oc::Color::Green << "1 " << oc::Color::Default; + else + o << "1 "; + ++jj; + } + else + o << "0 "; + } + o << "\n"; + } + + return o; + } + + + + + void DenseMtx::Row::swap(const Row& r) + { + assert(mMtx.cols() == r.mMtx.cols()); + + for (u64 colIdx = 0; colIdx < mMtx.cols(); ++colIdx) + { + u8 bit = r.mMtx(r.mIdx, colIdx); + r.mMtx(r.mIdx, colIdx) = mMtx(mIdx, colIdx); + mMtx(mIdx, colIdx) = bit; + } + } + + // returns true if the row is zero. + bool DenseMtx::Row::isZero() const + { + for (u64 colIdx = 0; colIdx < mMtx.cols(); ++colIdx) + { + u8 bit = mMtx(mIdx, colIdx); + if (bit) + return false; + } + return true; + } + + void DenseMtx::Row::operator^=(const Row& r) + { + for (u64 colIdx = 0; colIdx < mMtx.cols(); ++colIdx) + { + mMtx(mIdx, colIdx) ^= r.mMtx(r.mIdx, colIdx); + } + } + + void DenseMtx::resize(u64 rows, u64 cols) + { + mRows = rows; + mData.resize(cols, (rows + 127) / 128); + } + + void DenseMtx::colIndexSet(u64 c, std::vector& set) const + { + set.clear(); + oc::BitIterator iter((u8*)col(c).data()); + for (u64 i = 0; i < rows(); ++i) + { + if (*iter) + set.push_back(i); + ++iter; + } + } + + // returns a new matrix consisting of the given columns. + + DenseMtx DenseMtx::selectColumns(span perm) + { + DenseMtx r(rows(), perm.size()); + + for (u64 i = 0; i < (u64)perm.size(); ++i) + { + auto d = r.col(i); + auto s = col(perm[i]); + std::copy(s.begin(), s.end(), d.begin()); + } + return r; + } + + // clears the given matrix. + + void DenseMtx::setZero() + { + memset(mData.data(), 0, mData.size() * sizeof(oc::block)); + } + + // swap the given rows. + + void DenseMtx::rowSwap(u64 i, u64 j) + { + if (i != j) + { + row(i).swap(row(j)); + } + } + + // return the sparse representation of this matrix. + + SparseMtx DenseMtx::sparse() const + { + std::vector points; + for (u64 i = 0; i < rows(); ++i) + { + for (u64 j = 0; j < cols(); ++j) + { + if ((*this)(i, j)) + points.push_back({ i,j }); + } + } + + SparseMtx s; + s.init(rows(), cols(), points); + + return s; + } + + // multiply this matrix by m. + + DenseMtx DenseMtx::mult(const DenseMtx& m) + { + assert(cols() == m.rows()); + + DenseMtx ret(rows(), m.cols()); + + + for (u64 i = 0; i < ret.rows(); ++i) + { + for (u64 j = 0; j < ret.cols(); ++j) + { + u8 v = 0; + for (u64 k = 0; k < cols(); ++k) + { + v = v ^ ((*this)(i, k) & m(k, j)); + } + + ret(i, j) = v; + } + } + + return ret; + } + + // add this matrix with m and return the result. + + DenseMtx DenseMtx::add(DenseMtx& m) + { + assert(rows() == m.rows() && cols() == m.cols()); + + auto ret = *this; + for (u64 i = 0; i < mData.size(); ++i) + ret.mData(i) = ret.mData(i) ^ m.mData(i); + + return ret; + } + + // returns the identity matrix of the given size. + + DenseMtx DenseMtx::Identity(u64 n) + { + DenseMtx I(n, n); + + for (u64 i = 0; i < n; ++i) + I(i, i) = 1; + + return I; + } + + // Perform elementary row operations to this matrix + // to obtain a upper triangular matrix. + + DenseMtx DenseMtx::upperTriangular() const + { + auto& mtx = *this; + auto rows = mtx.rows(); + auto cols = mtx.cols(); + + u64 colIdx = 0ull; + for (u64 i = 0; i < rows; ++i) + { + while (mtx(i, colIdx) == 0) + { + for (u64 j = i + 1; j < rows; ++j) + { + if (mtx(j, colIdx) == 1) + { + mtx.row(i).swap(mtx.row(j)); + --colIdx; + break; + } + } + + ++colIdx; + + if (colIdx == cols) + return mtx; + } + + for (u64 j = i + 1; j < rows; ++j) + { + if (mtx(j, colIdx)) + { + for (u64 k = 0; k < cols; ++k) + { + mtx(j, k) ^= mtx(i, k); + } + } + } + + } + + return mtx; + + } + + // Perform gausian elimination and return the result. + DenseMtx DenseMtx::gausianElimination() const + { + auto& mtx = *this; + auto rows = mtx.rows(); + auto cols = mtx.cols(); + + u64 colIdx = 0ull; + for (u64 i = 0; i < rows; ++i) + { + while (mtx(i, colIdx) == 0) + { + for (u64 j = i + 1; j < rows; ++j) + { + if (mtx(j, colIdx) == 1) + { + mtx.row(i).swap(mtx.row(j)); + --colIdx; + break; + } + } + + ++colIdx; + + if (colIdx == cols) + return mtx; + } + + for (u64 j = 0; j < rows; ++j) + { + if (j != i && mtx(j, colIdx)) + { + for (u64 k = 0; k < cols; ++k) + { + mtx(j, k) ^= mtx(i, k); + } + } + } + + } + + return mtx; + + } + + DenseMtx DenseMtx::invert() const + { + assert(rows() == cols()); + + auto mtx = *this; + auto n = this->rows(); + + auto Inv = Identity(n); + + for (u64 i = 0; i < n; ++i) + { + if (mtx(i, i) == 0) + { + for (u64 j = i + 1; j < n; ++j) + { + if (mtx(j, i) == 1) + { + mtx.row(i).swap(mtx.row(j)); + Inv.row(i).swap(Inv.row(j)); + break; + } + } + + if (mtx(i, i) == 0) + { + //std::cout << mtx << std::endl; + return {}; + } + } + + for (u64 j = 0; j < n; ++j) + { + if (j != i && mtx(j, i)) + { + for (u64 k = 0; k < n; ++k) + { + mtx(j, k) ^= mtx(i, k); + Inv(j, k) ^= Inv(i, k); + } + } + } + + } + + return Inv; + + } + + // return the transpose of this matrix. + + DenseMtx DenseMtx::transpose() const + { + DenseMtx R(cols(), rows()); + for (u64 i = 0; i < rows(); ++i) + { + for (u64 j = 0; j < cols(); ++j) + { + R(j, i) = (*this)(i, j); + } + } + return R; + } + + // return the submatrix starting at (row,col) with the given size. + + DenseMtx DenseMtx::subMatrix(u64 row, u64 col, u64 rowCount, u64 colCount) + { + DenseMtx ret(rowCount, colCount); + + for (u64 i = 0, ii = row; i < rowCount; ++i, ++ii) + { + for (u64 j = 0, jj = col; j < colCount; ++j, ++jj) + { + ret(i, j) = (*this)(ii, jj); + } + } + return ret; + } + + std::ostream& operator<<(std::ostream& o, const DenseMtx& H) + { + for (u64 i = 0; i < H.rows(); ++i) + { + for (u64 j = 0; j < H.cols(); ++j) + { + if (H(i, j)) + { + if (&o == &std::cout) + o << oc::Color::Green << "1 " << oc::Color::Default; + else + o << "1 "; + } + else + o << "0 "; + } + o << "\n"; + } + + return o; + } + + + VecSortSet::iterator VecSortSet::begin() + { + return mData.begin(); + } + + VecSortSet::iterator VecSortSet::end() + { + return mData.end(); + } + + VecSortSet::iterator VecSortSet::find(u64 i) + { + auto iter = lowerBound(i); + if (iter != end() && *iter != i) + iter = end(); + return iter; + } + + VecSortSet::iterator VecSortSet::lowerBound(u64 i) + { + return std::lower_bound(begin(), end(), i); + } + + VecSortSet::constIerator VecSortSet::begin() const + { + return mData.begin(); + } + + VecSortSet::constIerator VecSortSet::end() const + { + return mData.end(); + } + + VecSortSet::constIerator VecSortSet::find(u64 i) const + { + auto iter = lowerBound(i); + if (iter != end() && *iter != i) + iter = end(); + return iter; + } + + VecSortSet::constIerator VecSortSet::lowerBound(u64 i) const + { + return std::lower_bound(begin(), end(), i); + } + + void VecSortSet::clear() + { + mData.clear(); + } + + void VecSortSet::insert(u64 i) + { + auto iter = lowerBound(i); + implInsert(i, iter); + } + + // insert i at the given hint. iter should lowerbound i. + + void VecSortSet::insertHint(u64 i, iterator iter) + { + assert(lowerBound(i) == iter); + implInsert(i, iter); + } + + void VecSortSet::implInsert(u64 i, iterator iter) + { + if (iter == end()) + { + mData.push_back(i); + } + else if (*iter > i) + { + auto p = iter - begin(); + mData.emplace_back(); + iter = begin() + p; + + while (iter != end()) + { + std::swap(i, *iter); + ++iter; + } + } + } + + void VecSortSet::erase(u64 i) + { + auto iter = lowerBound(i); + assert(iter != end()); + erase(iter); + } + + void VecSortSet::erase(iterator iter) + { + auto e = end() - 1; + while (iter < e) + { + *iter = *(iter + 1); + ++iter; + } + mData.pop_back(); + } + + void VecSortSet::operator^=(const VecSortSet& o) + { + u64 i0 = 0; + u64 i1 = 0; + + while (i0 != size() && i1 != o.size()) + { + if (mData[i0] < o.mData[i1]) + { + ++i0; + } + else if (mData[i0] == o.mData[i1]) + { + erase(begin() + i0); + ++i1; + } + else + { + insertHint(o.mData[i1], begin() + i0); + ++i1; + ++i0; + } + } + + insert(o.begin() + i1, o.end()); + } + + DynSparseMtx::DynSparseMtx(const SparseMtx& m) + { + resize(m.rows(), m.cols()); + for (u64 i = 0; i < rows(); ++i) + { + auto r = m.row(i); + row(i).insert(r.begin(), r.end()); + } + for (u64 i = 0; i < cols(); ++i) + { + auto c = m.col(i); + col(i).insert(c.begin(), c.end()); + } + } + + + DynSparseMtx& DynSparseMtx::operator=(const SparseMtx& m) + { + resize(m.rows(), m.cols()); + for (u64 i = 0; i < rows(); ++i) + { + auto r = m.row(i); + row(i).clear(); + row(i).insert(r.begin(), r.end()); + } + for (u64 i = 0; i < cols(); ++i) + { + auto c = m.col(i); + col(i).clear(); + col(i).insert(c.begin(), c.end()); + } + return *this; + } + + + DynSparseMtx& DynSparseMtx::operator=(const DenseMtx& m) + { + resize(m.rows(), m.cols()); + for (u64 i = 0; i < rows(); ++i) + { + row(i).clear(); + } + for (u64 i = 0; i < cols(); ++i) + { + //auto c = m.col(i); + col(i).clear(); + } + + for (u64 i = 0; i < rows(); ++i) + { + for (u64 j = 0; j < cols(); ++j) + { + if (m(i, j)) + { + col(j).insert(i); + row(i).insert(j); + } + } + } + + return *this; + } + + void DynSparseMtx::resize(u64 rows, u64 cols) + { + if (mRows.size() < rows) + { + for (u64 i = mRows.size() - 1; i <= rows; --i) + clearRow(i); + } + if (mCols.size() < cols) + { + for (u64 i = mCols.size() - 1; i <= cols; --i) + clearCol(i); + } + + mRows.resize(rows); + mCols.resize(cols); + } + + void DynSparseMtx::reserve(u64 rows, u64 cols) + { + mRows.reserve(rows); + mCols.reserve(cols); + } + + // clears the given row and maintains the invariances. + + void DynSparseMtx::clearRow(u64 i) + { + assert(i < mRows.size()); + for (auto c : mRows[i]) + { + mCols[c].erase(i); + } + } + + // clears the given column and maintains the invariances. + + void DynSparseMtx::clearCol(u64 i) + { + assert(i < mCols.size()); + for (auto r : mCols[i]) + { + mRows[r].erase(i); + } + } + + void DynSparseMtx::pushBackCol(span col) + { + auto c = mCols.size(); + mCols.emplace_back(); + mCols.back().insert(col.begin(), col.end()); + + for (u64 i = 0; i < (u64)col.size(); ++i) + { + mRows[col[i]].insert(c); + } + } + + // add the given row to the end of the matrix. + + void DynSparseMtx::pushBackRow(span row) + { + auto r = mRows.size(); + mRows.emplace_back(); + mRows.back().insert(row.begin(), row.end()); + + for (u64 i = 0; i < (u64)row.size(); ++i) + { + mCols[row[i]].insert(r); + } + } + + // add the row indexed by r1 to r0. + + void DynSparseMtx::rowAdd(u64 r0, u64 r1) + { + + u64 i0 = 0; + u64 i1 = 0; + auto& rr0 = row(r0); + auto& rr1 = row(r1); + + while (i0 != rr0.size() && i1 != rr1.size()) + { + auto colIdx0 = rr0.mData[i0]; + auto colIdx1 = rr1.mData[i1]; + if (colIdx0 < colIdx1) + { + ++i0; + } + else if (colIdx0 == colIdx1) + { + col(colIdx0).erase(r0); + rr0.erase(rr0.begin() + i0); + ++i1; + } + else + { + col(colIdx1).insert(r0); + rr0.insertHint(colIdx1, rr0.begin() + i0); + ++i1; + ++i0; + } + } + + rr0.insert(rr1.begin() + i1, rr1.end()); + while (i1 != rr1.size()) + { + auto colIdx = rr1.mData[i1]; + col(colIdx).insert(r0); + ++i1; + } + //validate(); + } + + // swap the rows indexed by r1, r0. + + void DynSparseMtx::rowSwap(u64 r0, u64 r1) + { + //validate(); + + assert(r0 < rows()); + assert(r1 < rows()); + + if (r0 == r1) + return; + + u64 col0 = 0; + u64 col1 = 0; + + auto& rr0 = mRows[r0]; + auto& rr1 = mRows[r1]; + + while (col0 != rr0.size() && col1 != rr1.size()) + { + if (rr0[col0] < rr1[col1]) + { + auto& c0 = mCols[rr0[col0]]; + c0.erase(r0); + c0.insert(r1); + ++col0; + } + else if (rr0[col0] > rr1[col1]) + { + auto& c1 = mCols[rr1[col1]]; + c1.erase(r1); + c1.insert(r0); + ++col1; + } + else + { + ++col1; + ++col0; + } + } + + + + + while (col0 != rr0.size()) + { + auto& c0 = mCols[rr0[col0]]; + c0.erase(r0); + c0.insert(r1); + ++col0; + } + while (col1 != rr1.size()) + { + auto& c1 = mCols[rr1[col1]]; + c1.erase(r1); + c1.insert(r0); + ++col1; + } + + std::swap(mRows[r0], mRows[r1]); + + //validate(); + } + + // check that the row/column invariances are maintained. + + void DynSparseMtx::validate() + { + for (u64 i = 0; i < rows(); ++i) + { + for (auto j : mRows[i]) + { + if (mCols[j].find(i) == mCols[j].end()) + throw RTE_LOC; + } + } + + for (u64 i = 0; i < cols(); ++i) + { + for (auto j : mCols[i]) + { + if (mRows[j].find(i) == mRows[j].end()) + throw RTE_LOC; + } + } + } + + // construct a new matrix which is formed by the given + // columns, as indexed by perm. + + DynSparseMtx DynSparseMtx::selectColumns(span perm) const + { + DynSparseMtx r; + r.mRows.resize(rows()); + for (u64 i = 0; i < (u64)perm.size(); ++i) + { + r.pushBackCol(col(perm[i])); + } + return r; + } + + // return the "sparse" representation of this matirx. + + SparseMtx DynSparseMtx::sparse() const + { + std::vector points; + for (u64 i = 0; i < rows(); ++i) + { + for (auto j : row(i)) + points.push_back({ i,j }); + } + + SparseMtx s; + s.init(rows(), cols(), points); + + return s; + } + + std::ostream& operator<<(std::ostream& o, const DynSparseMtx& H) + { + for (u64 i = 0; i < H.rows(); ++i) + { + auto row = H.row(i); + for (u64 j = 0, jj = 0; j < H.cols(); ++j) + { + if (jj != row.size() && j == row[jj]) + { + if (&o == &std::cout) + o << oc::Color::Green << "1 " << oc::Color::Default; + else + o << "1 "; + ++jj; + } + else + o << "0 "; + } + o << "\n"; + } + return o; + } + + + + void tests::Mtx_make_test() + { + + u64 n1 = 221, + n2 = 31; + + oc::PRNG prng(block(0, 0)); + + //Eigen::SparseMatrix eigen; + //eigen.resize(n1, n2); + + oc::Matrix base(n1, n2); + + DenseMtx dense(n1, n2); + DynSparseMtx sparse1, sparse2; + sparse1.reserve(n1, n2); sparse1.resize(0, n2); + sparse2.reserve(n1, n2); sparse2.resize(n1, 0); + std::vector points; + + for (u64 i = 0; i < n1; ++i) + { + std::vector row; + for (u64 j = 0; j < n2; ++j) + { + base(i, j) = prng.getBit(); + dense(i, j) = base(i, j); + + + if (base(i, j)) + { + row.push_back(j); + points.push_back({ i,j }); + //eigen.insert(i, j); + } + } + sparse1.pushBackRow(row); + } + + SparseMtx sparse3; + sparse3.init(n1, n2, points); + + + for (u64 j = 0; j < n2; ++j) + { + std::vector col; + for (u64 i = 0; i < n1; ++i) + { + if (base(i, j)) + { + col.push_back(i); + } + } + sparse2.pushBackCol(col); + } + + for (u64 i = 0; i < n1; ++i) + { + for (u64 j = 0; j < n2; ++j) + { + if (base(i, j) != dense(i, j)) + { + std::cout << i << " " << j << " " << LOCATION << std::endl; + abort(); + } + } + } + + + if (!(sparse1.sparse() == sparse2.sparse())) + { + std::cout << LOCATION << std::endl; + abort(); + } + if (!(sparse1.sparse() == dense.sparse())) + { + std::cout << LOCATION << std::endl; + abort(); + } + + } + + void tests::Mtx_add_test() + { + + u64 n1 = 20, + n2 = 30; + + oc::PRNG prng(block(0, 0)); + + DenseMtx d1(n1, n2); + DenseMtx d2(n1, n2); + + for (u64 i = 0; i < n1; ++i) + for (u64 j = 0; j < n2; ++j) + { + d1(i, j) = prng.getBit(); + d2(i, j) = prng.getBit(); + } + + auto s1 = d1.sparse(); + auto s2 = d2.sparse(); + + + + auto d3 = d1 + d2; + auto s3 = s1 + s2; + + assert(s3 == d3.sparse()); + assert(d3 == s3.dense()); + } + void tests::Mtx_mult_test() + { + u64 n1 = 20, + n2 = 30, + n3 = 40; + + oc::PRNG prng(block(0, 0)); + + DenseMtx d1(n1, n2); + DenseMtx d2(n2, n3); + + for (u64 i = 0; i < n1; ++i) + for (u64 j = 0; j < n2; ++j) + d1(i, j) = prng.getBit(); + + for (u64 i = 0; i < n2; ++i) + for (u64 j = 0; j < n3; ++j) + d2(i, j) = prng.getBit(); + + auto s1 = d1.sparse(); + auto s2 = d2.sparse(); + + + + auto d3 = d1 * d2; + auto s3 = s1 * s2; + + assert(s3 == d3.sparse()); + assert(d3 == s3.dense()); + } + + void tests::Mtx_invert_test() + { + + u64 n1 = 40; + + oc::PRNG prng(block(0, 0)); + + DenseMtx d1(n1, n1); + + for (u64 i = 0; i < n1; ++i) + { + for (u64 j = 0; j < n1; ++j) + { + auto b = prng.getBit(); + //std::cout << int(b) << " "; + d1(i, j) = b; + } + //std::cout << "\n"; + + } + //std::cout << "\nin \n" << d1 << std::endl; + + auto inv = d1.invert(); + + auto I = d1 * inv; + + assert(I == DenseMtx::Identity(n1)); + + } + + + +} + + diff --git a/libOTe/Tools/LDPC/Mtx.h b/libOTe/Tools/LDPC/Mtx.h new file mode 100644 index 00000000..04f3890c --- /dev/null +++ b/libOTe/Tools/LDPC/Mtx.h @@ -0,0 +1,566 @@ +#pragma once + +#include +#include +#include "cryptoTools/Common/Defines.h" +#include "cryptoTools/Common/BitIterator.h" +#include "cryptoTools/Common/Log.h" +#include "cryptoTools/Common/Matrix.h" +#include "cryptoTools/Crypto/RandomOracle.h" +#include +#include +#include + +#include + +namespace osuCrypto +{ + struct Point + { + u64 mRow, mCol; + }; + class SparseMtx; + + // A sparse matrix represented as an unordered list of points. + struct PointList + { + using iterator = std::vector::iterator; + + PointList(const PointList&) = default; + PointList(PointList&&) = default; + + PointList(u64 r, u64 c) + : mRows(r), mCols(c) + {} + + PointList(u64 r, u64 c, span pp); + + u64 mRows, mCols; + std::vector mPoints; +#ifndef NDEBUG + std::set> ss; +#endif + + // add the given point. SHould not have previously been added. + void push_back(const Point& p); + + operator span() { return mPoints; } + + iterator begin() { return mPoints.begin(); } + iterator end() { return mPoints.end(); } + + }; + + + class DenseMtx; + + + // A class representing a sparse binary matrix. + // The points are represented in both column and row major. + class SparseMtx + { + public: + + // reference class to a sparse row. + class Row : public span + { + public: + Row() = default; + Row(const Row& r) = default; + Row& operator=(const Row& r) = default; + explicit Row(const span& r) { (span&)* this = r; } + }; + + // reference class to a sparse column. + class Col : public span + { + public: + Col() = default; + Col(const Col& r) = default; + Col& operator=(const Col& r) = default; + explicit Col(const span& r) { (span&)* this = r; } + }; + + // const reference class to a sparse row. + class ConstRow : public span + { + public: + ConstRow() = default; + ConstRow(const ConstRow&) = default; + ConstRow(const Row& r) : span(r) { }; + ConstRow& operator=(const ConstRow&) = default; + ConstRow& operator=(const Row& r) { (span&)* this = r; return *this; }; + }; + // const reference class to a sparse column. + class ConstCol : public span + { + public: + ConstCol() = default; + ConstCol(const ConstCol&) = default; + ConstCol(const Col& r) : span(r) { }; + ConstCol& operator=(const ConstCol&) = default; + ConstCol& operator=(const Col& c) { (span&)* this = c; return *this; }; + }; + + SparseMtx() = default; + SparseMtx(const SparseMtx&) = default; + SparseMtx(SparseMtx&&) = default; + SparseMtx& operator=(const SparseMtx&) = default; + SparseMtx& operator=(SparseMtx&&) = default; + + + SparseMtx(PointList& list) + { + init(list); + } + + SparseMtx(u64 rows, u64 cols, span points) + { + init(rows, cols, points); + } + + // The row/column data is represented in a flat vector. + std::vector mDataRow, mDataCol; + + // Each row is a reference into the flat vectors. + std::vector mRows; + + // Each column is a reference into the flat vectors. + std::vector mCols; + + // the number of rows. + u64 rows() const { return mRows.size(); } + // the number of column. + u64 cols() const { return mCols.size(); } + + // get the ith row by reference + Row& row(u64 i) { return mRows[i]; } + + // get the ith column by reference + Col& col(u64 i) { return mCols[i]; } + + // get the ith row by reference + ConstRow row(u64 i) const { return mRows[i]; } + + // get the ith column by reference + ConstCol col(u64 i) const { return mCols[i]; } + + bool operator()(u64 i, u64 j) const + { + if (i >= mRows.size() || j >= mCols.size()) + throw RTE_LOC; + auto iter = std::find(mRows[i].begin(), mRows[i].end(), j); + return iter != mRows[i].end(); + } + + // hash the matrix. will return the same value + // as hash for DenseMtx if they are equal. + block hash() const; + + + void init(PointList& list) + { + init(list.mRows, list.mCols, list.mPoints); + } + + // constuct the matrix with the given points/size. + void init(u64 rows, u64 cols, span points); + + // return the submatrix that are specified by the given columns. + template + SparseMtx getCols(span idx) const + { + PointList pnts(mRows.size(), idx.size()); + for (u64 i = 0; i < idx.size(); ++i) + { + for (auto r : mCols[idx[i]]) + { + pnts.push_back({ r,i }); + } + } + return pnts; + } + + // return true if the coordinate is set. + bool isSet(u64 row, u64 col); + + // check that the sparse matrix is well formed. + bool validate(); + + // vertically concatinate this matrix and the parameter. + // this matrix will come first. The result is returned. + SparseMtx vConcat(const SparseMtx& o) const; + + // returns the submatrix starting at (row, col) and of + // the given size. + SparseMtx subMatrix(u64 row, u64 col, u64 rowCount, u64 colCount) const; + + // return the dense representation of this matix. + DenseMtx dense() const; + + // multiply this matrix with the given vector. + std::vector mult(span x) const; + + // multiply this matrix by x and add (xor) the result to y. + template + void multAdd(const ConstVec& x, Vec& y) const + { + assert(cols() == x.size()); + assert(y.size() == rows()); + for (u64 i = 0; i < rows(); ++i) + { + for (auto c : row(i)) + { + assert(c < cols()); + y[i] = y[i] ^ x[c]; + } + } + } + + + std::vector operator*(span x) const { return mult(x); } + + // multiply this sparse matrix with X. + SparseMtx mult(const SparseMtx& X) const; + + // multiply this sparse matrix with X. + SparseMtx operator*(const SparseMtx& X) const { return mult(X); } + + // add this sparse matrix with X. + SparseMtx operator+(const SparseMtx& X) const { return add(X); } + + // add this sparse matrix with X. + SparseMtx add(const SparseMtx& X) const; + + // add X to this matrix + SparseMtx& operator+=(const SparseMtx& X) + { + *this = add(X); + return *this; + } + + // invert this matrix. if not invertable then + // the resturned value will have zero size. + SparseMtx invert() const; + + // convert this sparse matrix into a vector of points. + std::vector points() const; + + // converts this matrix into a point list. + operator PointList() const + { + return PointList(mRows.size(), mCols.size(), points()); + } + + bool operator==(const SparseMtx& X) const; + bool operator!=(const SparseMtx& X) const; + }; + + std::ostream& operator<<(std::ostream& o, const SparseMtx& H); + + + + // a class that represents a dense binary matrix. + // The data is stored in column major format. + class DenseMtx + { + public: + // column major, which means we call mData.row(i) + // to get column i and vise versa. + Matrix mData; + + // the number of rows. This will be + // mData.cols() * 128 or a bit less. + u64 mRows = 0; + + DenseMtx() = default; + DenseMtx(const DenseMtx&) = default; + DenseMtx(DenseMtx&&) = default; + + DenseMtx& operator=(const DenseMtx&) = default; + DenseMtx& operator=(DenseMtx&&) = default; + + DenseMtx(u64 rows, u64 cols) + { + resize(rows, cols); + } + + // resize the given matrix. If the number of rows + // changed then the data is invalidated. + void resize(u64 rows, u64 cols); + + // the number of rows. + u64 rows() const { return mRows; } + + // the number of columns. + u64 cols() const { return mData.rows(); } + + // returns a refernce to the given bit. + oc::BitReference operator()(u64 row, u64 col) const + { + assert(row < rows()); + assert(col < cols()); + return oc::BitReference((u8*)&mData(col, 0), row); + } + + bool operator==(const DenseMtx& m) const + { + return rows() == m.rows() + && cols() == m.cols() + && std::memcmp(mData.data(), m.mData.data(), mData.size() * sizeof(oc::block)) == 0; + } + + // A referenced to the given row. + struct Row + { + u64 mIdx; + DenseMtx& mMtx; + + // swap the data of the underlying rows. + void swap(const Row& r); + + // returns true if the row is zero. + bool isZero() const; + + // xor the given row into this one. + void operator^=(const Row& r); + }; + + // returns a refernce to the given row. + Row row(u64 i) const + { + return Row{ i, (DenseMtx&)*this }; + } + + // returns a refernce to the given column. + span col(u64 i) + { + return mData[i]; + } + + // returns a refernce to the given column. + span col(u64 i) const + { + return mData[i]; + } + + // return the "sparse vector" of the given column c. + // The result is written to set. + void colIndexSet(u64 c, std::vector& set)const; + + // returns a new matrix consisting of the given columns. + DenseMtx selectColumns(span perm); + + // clears the given matrix. + void setZero(); + + // swap the given rows. + void rowSwap(u64 i, u64 j); + + // return the sparse representation of this matrix. + SparseMtx sparse() const; + + // multiply this matrix by m and return the result. + DenseMtx mult(const DenseMtx& m); + + // multiply this matrix by m and return the result. + DenseMtx operator*(const DenseMtx& m) { return mult(m); } + + // add this matrix with m and return the result. + DenseMtx add(DenseMtx& m); + + // add this matrix with m and return the result. + DenseMtx operator+(DenseMtx& m) { return add(m); } + + // returns the identity matrix of the given size. + static DenseMtx Identity(u64 n); + + // Perform elementary row operations to this matrix + // to obtain a upper triangular matrix. + DenseMtx upperTriangular() const; + + // Perform gausian elimination and return the result. + DenseMtx gausianElimination() const; + + // return the inverse of this matrix. + DenseMtx invert() const; + + // return the transpose of this matrix. + DenseMtx transpose() const; + + // return the submatrix starting at (row,col) with the given size. + DenseMtx subMatrix(u64 row, u64 col, u64 rowCount, u64 colCount); + }; + + std::ostream& operator<<(std::ostream& o, const DenseMtx& H); + + // a small set class which stores the data sorted inside a vector. + struct VecSortSet + { + std::vector mData; + using iterator = std::vector::iterator; + using constIerator = std::vector::const_iterator; + + iterator begin(); + iterator end(); + constIerator begin() const; + constIerator end()const; + + iterator find(u64 i); + constIerator find(u64 i)const; + + iterator lowerBound(u64 i); + constIerator lowerBound(u64 i)const; + + void clear(); + + // insert the items [b,e). iterators should + // derefence to u64's. + template + void insert(Iter b, Iter e) + { + auto s = e - b; + mData.reserve(mData.size() + s); + while (b != e) + { + if (size() == 0 || *b > mData.back()) + mData.push_back(*b); + else + insert(*b); + ++b; + } + } + + // insert i. + void insert(u64 i); + + // insert i at the given hint. iter should lowerbound i. + void insertHint(u64 i, iterator iter); + + // private function. + void implInsert(u64 i, iterator iter); + + // erate i from the set. Assumes it is in the set. + void erase(u64 i); + + // erase the given iterator. + void erase(iterator iter); + + // the size of the set. + u64 size() const { return mData.size(); } + + // returns the i'th sorted item in the set. + u64& operator[](u64 i) { return mData[i]; } + + // compute the symetric set differnce and assign the result + // to this set. + void operator^=(const VecSortSet& o); + }; + + + // A sparse matrix class thats design to have + // effecient manipulation operations. + struct DynSparseMtx + { + // each row is stored as a set. + std::vector mRows; + + // each column is stored as a set. + std::vector mCols; + + DynSparseMtx() = default; + DynSparseMtx(const DynSparseMtx&) = default; + DynSparseMtx(DynSparseMtx&&) = default; + + DynSparseMtx(const SparseMtx& m); + + DynSparseMtx& operator=(const SparseMtx& m); + DynSparseMtx& operator=(const DenseMtx& m); + DynSparseMtx& operator=(const DynSparseMtx&) = default; + DynSparseMtx& operator=(DynSparseMtx&&) = default; + + // returns the ith row. + VecSortSet& row(u64 i) { return mRows[i]; } + + // returns the ith column. + VecSortSet& col(u64 i) { return mCols[i]; } + + // returns the ith row. + const VecSortSet& row(u64 i)const { return mRows[i]; } + + // returns the ith column. + const VecSortSet& col(u64 i)const { return mCols[i]; } + + // returns the number of rows. + u64 rows()const { return mRows.size(); } + + // returns the number of columns. + u64 cols()const { return mCols.size(); } + + // resizes the matrix and maintain the invariances. + void resize(u64 rows, u64 cols); + + // reserve space for the given matrix size. + void reserve(u64 rows, u64 cols); + + // clears the given row and maintains the invariances. + void clearRow(u64 i); + + // clears the given column and maintains the invariances. + void clearCol(u64 i); + + // add the given column to the end of the matrix. + void pushBackCol(const VecSortSet& col) { pushBackCol(span(col.mData)); } + + // add the given column to the end of the matrix. + void pushBackCol(span col); + + // add the given row to the end of the matrix. + void pushBackRow(const VecSortSet& row) { pushBackRow(row.mData); } + + // add the given row to the end of the matrix. + void pushBackRow(span row); + + // add the row indexed by r1 to r0. + void rowAdd(u64 r0, u64 r1); + + // swap the rows indexed by r1, r0. + void rowSwap(u64 r0, u64 r1); + + bool operator()(u64 r, u64 c) const + { + return mRows[r].find(c) != mRows[r].end(); + } + + // check that the row/column invariances are maintained. + void validate(); + + // construct a new matrix which is formed by the given + // columns, as indexed by perm. + DynSparseMtx selectColumns(span perm) const; + + // return the "sparse" representation of this matirx. + SparseMtx sparse() const; + }; + + + std::ostream& operator<<(std::ostream& o, const DynSparseMtx& H); + + + + + + namespace tests + { + void Mtx_make_test(); + void Mtx_add_test(); + void Mtx_mult_test(); + void Mtx_invert_test(); + } + + + + + + +} diff --git a/libOTe/Tools/LDPC/Util.cpp b/libOTe/Tools/LDPC/Util.cpp new file mode 100644 index 00000000..d2d7c4dd --- /dev/null +++ b/libOTe/Tools/LDPC/Util.cpp @@ -0,0 +1,396 @@ +#include "Util.h" +//#include +#include "cryptoTools/Common/Log.h" +#include "cryptoTools/Common/Matrix.h" +#include "cryptoTools/Crypto/PRNG.h" +#include "cryptoTools/Common/BitIterator.h" +#include +#include +#include +#include + +#include "Mtx.h" +#include + +#ifdef ENABLE_ALGO994 +extern "C" { +#include "libOTe/Tools/LDPC/Algo994/utils.h" +#include "libOTe/Tools/LDPC/Algo994/generations.h" +#include "libOTe/Tools/LDPC/Algo994/data_defs.h" +} +#endif + +#include + +namespace osuCrypto +{ + + + + + //using Mtx = Eigen::Matrix; + +#ifdef ENABLE_ALGO994 + int alg994 = ALG_SAVED_UNROLLED; + int num_saved_generators = 5; + int num_cores = 4; + int num_permutations = 5; + int print_matrices = 0; +#endif + + int minDist(std::string path, u64 numTHreads, bool verbose) + { +#ifdef ENABLE_ALGO994 + + char* inputMatrix; + int info, k, n, dist; + num_cores = numTHreads; + + // Read input matrix. + info = read_char_matrix((char*)path.c_str(), &inputMatrix, &k, &n); + if (info != 0) { + fprintf(stderr, "\n"); + fprintf(stderr, "ERROR in read_char_matrix: "); + fprintf(stderr, "Error while reading input file with matrix.\n\n\n"); + } + + assert( + alg994 == ALG_BASIC || // 1 + alg994 == ALG_OPTIMIZED || // 2 + alg994 == ALG_STACK || // 3 + alg994 == ALG_SAVED || // 4 + alg994 == ALG_SAVED_UNROLLED || // 5 + alg994 == ALG_GRAY // 10 + ); + + // Compute distance of input matrix. + dist = compute_distance_of_matrix_impl(inputMatrix, k, n, + alg994, + num_saved_generators, + num_cores, + num_permutations, + print_matrices); + + // Remove matrices. + free(inputMatrix); + + return dist; +#else + throw std::runtime_error("also 994 not enabled. " LOCATION); +#endif + } + + int minDist2(const DenseMtx& mtx, u64 nt, bool verbose) + { + std::string outPath("./deleteMe"); + std::fstream out(outPath, std::fstream::trunc | std::fstream::out); + + if (out.is_open() == false) + { + std::cout << "failed to open: " << outPath << std::endl; + return 0; + } + + std::vector> swaps; + auto G = computeGen(mtx, swaps); + + out << G.rows() << " " << G.cols() << " matrix dimensions\n" + << G << std::endl; + + out.close(); + + u64 d; + + d = minDist(outPath, nt, false); + + std::remove(outPath.c_str()); + return (int)d; + } + + + u64 numNonzeroRows(const DenseMtx& mtx) + { + u64 r = 0; + for (u64 i = 0; i < mtx.rows(); ++i) + { + if (mtx.row(i).isZero()) + ++r; + } + + return mtx.rows() - r; + } + + //u64 rank(const DenseMtx& mtx) + //{ + // DenseMtx m2 = gaussianElim(mtx); + // return numNonzeroRows(m2); + //} + + void ithCombination(u64 index, u64 n, std::vector& set) + { + //'''Yields the items of the single combination that would be at the provided + //(0-based) index in a lexicographically sorted list of combinations of choices + //of k items from n items [0,n), given the combinations were sorted in + //descending order. Yields in descending order. + //''' + u64 nCk = 1; + u64 nMinusI = n; + u64 iPlus1 = 1; + + auto k = set.size(); + + // nMinusI, iPlus1 in zip(range(n, n - k, -1), range(1, k + 1)): + for (; nMinusI != n - k; --nMinusI, ++iPlus1) + { + nCk *= nMinusI; + nCk /= iPlus1; + } + + //std::cout << "nCk " << nCk << std::endl; + + auto curIndex = nCk; + for (auto kk = k; kk != 0ull; --kk)//in range(k, 0, -1): + { + //std::cout << "kk " << kk << " " << nCk << std::endl; + nCk *= kk; + nCk /= n; + while (curIndex - nCk > index) { + curIndex -= nCk; + nCk *= (n - kk); + nCk -= nCk % kk; + n -= 1; + nCk /= n; + } + n -= 1; + + set[kk - 1] = n; + } + } + + + std::vector ithCombination(u64 index, u64 n, u64 k) + { + std::vector set(k); + ithCombination(index, n, set); + return set; + } + + u64 choose(u64 n, u64 k) + { + if (k == 0) return 1; + return (n * choose(n - 1, k - 1)) / k; + } + + struct NChooseK + { + u64 mN; + u64 mK; + u64 mI, mEnd; + std::vector mSet; + + NChooseK(u64 n, u64 k, u64 begin = 0, u64 end = -1) + : mN(n) + , mK(k) + , mI(begin) + , mEnd(std::min(choose(n, k), end)) + { + assert(k <= n); + mSet = ithCombination(begin, n, k); + } + + const std::vector& operator*() const + { + return mSet; + } + + void operator++() + { + ++mI; + assert(mI <= mEnd); + + u64 i = 0; + while (i < mK - 1 && mSet[i] + 1 == mSet[i + 1]) + ++i; + + //if (i == mK - 1 && mSet.back() == mN - 1) + //{ + // mSet.clear(); + // return; + // //assert(mSet.back() != mN - 1); + //} + + ++mSet[i]; + for (u64 j = 0; j < i; ++j) + mSet[j] = j; + } + + explicit operator bool() const + { + return mI < mEnd; + } + + }; + + + DenseMtx computeGen(DenseMtx& H) + { + assert(H.rows() < H.cols()); + + auto n = H.cols(); + auto m = H.rows(); + auto k = n - m; + + auto mtx = H.subMatrix(0, k, m, m); + + auto P = H.subMatrix(0, 0, m, k); + + for (u64 i = 0; i < m; ++i) + { + if (mtx(i, i) == 0) + { + for (u64 j = i + 1; j < m; ++j) + { + if (mtx(j, i) == 1) + { + mtx.row(i).swap(mtx.row(j)); + P.row(i).swap(P.row(j)); + break; + } + } + + if (mtx(i, i) == 0) + { + //std::cout << mtx << std::endl; + return {}; + } + } + + for (u64 j = 0; j < m; ++j) + { + if (j != i && mtx(j, i)) + { + for (u64 l = 0; l < m; ++l) + { + mtx(j, l) ^= mtx(i, l); + } + + for (u64 l = 0; l < k; ++l) + P(j, l) ^= P(i, l); + } + } + + } + + + DenseMtx G(k, n); + for (u64 i = 0; i < k; ++i) + G(i, i) = 1; + + for (u64 i = 0; i < m; ++i) + { + for (u64 j = 0; j < k; ++j) + { + G(j, i + k) = P(i, j); + } + } + + + return G; + } + + + + DenseMtx computeGen(DenseMtx H, std::vector>& colSwaps) + { + assert(H.rows() < H.cols()); + + auto n = H.cols(); + auto m = H.rows(); + auto k = n - m; + colSwaps.clear(); + + for (u64 row = 0, col = k; row < m; ++row, ++col) + { + //std::cout << row << std::endl << H << std::endl;; + + if (H(row, col) == 0) + { + bool found = false; + // look fow a row swap + for (u64 row2 = row + 1; row2 < m && found == false; ++row2) + { + if (H(row2, col) == 1) + { + H.row(row).swap(H.row(row2)); + found = true; + } + } + + + if (found == false) + { + // look for a col swap + + for (u64 col2 = 0; col2 < k && found == false; ++col2) + { + for (u64 row2 = row; row2 < m && found == false; ++row2) + { + if (H(row2, col2) == 1) + { + H.row(row).swap(H.row(row2)); + + // swap columns. + colSwaps.push_back({ col,col2 }); + auto c0 = H.col(col); + auto c1 = H.col(col2); + std::swap_ranges(c0.begin(), c0.end(), c1.begin()); + found = true; + } + } + } + } + + if (found == false) + { + // can not be put in systematic form. + //std::cout << H << std::endl; + + return {}; + } + } + + + // clear all other ones from the current column. + for (u64 row2 = 0; row2 < m; ++row2) + { + if (row2 != row && H(row2, col)) + { + // row2 = row ^ row2 + for (u64 col2 = 0; col2 < n; ++col2) + { + H(row2, col2) ^= H(row, col2); + } + } + } + + } + + auto P = H.subMatrix(0, 0, m, k); + + DenseMtx G(k, n); + for (u64 i = 0; i < k; ++i) + G(i, i) = 1; + + for (u64 i = 0; i < m; ++i) + { + for (u64 j = 0; j < k; ++j) + { + G(j, i + k) = P(i, j); + } + } + + + return G; + } + +} \ No newline at end of file diff --git a/libOTe/Tools/LDPC/Util.h b/libOTe/Tools/LDPC/Util.h new file mode 100644 index 00000000..ecd4da02 --- /dev/null +++ b/libOTe/Tools/LDPC/Util.h @@ -0,0 +1,29 @@ + + +#include "libOTe/config.h" +#include "cryptoTools/Common/CLP.h" +#include +#include "Mtx.h" +namespace osuCrypto +{ + DenseMtx computeGen(DenseMtx& H); + DenseMtx computeGen(DenseMtx H, std::vector>& colSwaps); + + int minDist(std::string path, u64 numTHreads, bool verbose); + int minDist2(const DenseMtx& mtx, u64 numTHreads, bool verbose); + + + void ithCombination(u64 index, u64 n, std::vector& set); + std::vector ithCombination(u64 index, u64 n, u64 k); + u64 choose(u64 n, u64 k); + +#ifdef ENABLE_ALGO994 + extern int alg994; + extern int num_saved_generators; + extern int num_cores; + extern int num_permutations; + extern int print_matrices; +#endif + +} + diff --git a/libOTe/Tools/LinearCode.cpp b/libOTe/Tools/LinearCode.cpp index dee68f20..6c3af77e 100644 --- a/libOTe/Tools/LinearCode.cpp +++ b/libOTe/Tools/LinearCode.cpp @@ -306,7 +306,7 @@ namespace osuCrypto - static std::array sBlockMasks{ { ZeroBlock, AllOneBlock } }; + //static std::array sBlockMasks{ { ZeroBlock, AllOneBlock } }; void LinearCode::encode( const span& plaintxt, diff --git a/libOTe/Tools/Popf/EKEPopf.h b/libOTe/Tools/Popf/EKEPopf.h new file mode 100644 index 00000000..c1eb208f --- /dev/null +++ b/libOTe/Tools/Popf/EKEPopf.h @@ -0,0 +1,71 @@ +#pragma once +#include "libOTe/config.h" +#if defined(ENABLE_MRR_TWIST) && defined(ENABLE_SSE) + +#include +#include +#include +#include + +namespace osuCrypto +{ + class EKEPopf + { + public: + typedef Block256 PopfFunc; + typedef bool PopfIn; // TODO: Make this more general. + typedef Block256 PopfOut; + + EKEPopf(const RandomOracle& ro_) : ro(ro_) {} + EKEPopf(RandomOracle&& ro_) : ro(ro_) {} + + PopfOut eval(PopfFunc f, PopfIn x) const + { + Rijndael256Dec ic(getKey(x)); + return ic.decBlock(f); + } + + PopfFunc program(PopfIn x, PopfOut y, PRNG& prng) const + { + return program(x, y); + } + + PopfFunc program(PopfIn x, PopfOut y) const + { + Rijndael256Enc ic(getKey(x)); + return ic.encBlock(y); + } + + private: + Block256 getKey(PopfIn x) const + { + Block256 key; + RandomOracle roKey = ro; + roKey.Update(x); + roKey.Final(key); + + return key; + } + + RandomOracle ro; + }; + class DomainSepEKEPopf: public RandomOracle + { + using RandomOracle::Final; + using RandomOracle::outputLength; + + public: + typedef EKEPopf ConstructedPopf; + const static size_t hashLength = sizeof(Block256); + DomainSepEKEPopf() : RandomOracle(hashLength) {} + + ConstructedPopf construct() + { + return EKEPopf(*this); + } + }; + +} + + +#endif diff --git a/libOTe/Tools/Popf/FeistelMulPopf.h b/libOTe/Tools/Popf/FeistelMulPopf.h new file mode 100644 index 00000000..f216c072 --- /dev/null +++ b/libOTe/Tools/Popf/FeistelMulPopf.h @@ -0,0 +1,97 @@ +#pragma once +#include "libOTe/config.h" +#if defined(ENABLE_MRR) || defined(ENABLE_MRR_TWIST) + +#include +#include +#include + +namespace osuCrypto +{ + class FeistelMulPopf + { + public: + struct PopfFunc + { + Block256 t; + Block256 s; + }; + + typedef bool PopfIn; + typedef Block256 PopfOut; + + FeistelMulPopf(const RandomOracle& ro_) : ro(ro_) {} + FeistelMulPopf(RandomOracle&& ro_) : ro(ro_) {} + + PopfOut eval(PopfFunc f, PopfIn x) const + { + mulXor(f, x); + xorH(f, x); + + return f.t; + } + + PopfFunc program(PopfIn x, PopfOut y, PRNG& prng) const + { + PopfFunc f; + f.t = y; + prng.get(&f.s, 1); + + xorH(f, x); + mulXor(f, x); + + return f; + } + + private: + void xorH(PopfFunc &f, PopfIn x) const + { + RandomOracle h = ro; + h.Update(x); + + Block256 hOut; + h.Update(f.s); + h.Final(hOut); + + for (int i = 0; i < 2; i++) + f.t[i] = f.t[i] ^ hOut[i]; + } + + void mulXor(PopfFunc &f, PopfIn x) const + { + uint64_t mask64 = -(uint64_t) x; + block mask(mask64, mask64); + + for (int i = 0; i < 2; i++) + f.s[i] = f.s[i] ^ (mask & f.t[i]); + } + + RandomOracle ro; + }; + + class DomainSepFeistelMulPopf: public RandomOracle + { + using RandomOracle::Final; + using RandomOracle::outputLength; + + public: + typedef FeistelMulPopf ConstructedPopf; + const static size_t hashLength = sizeof(Block256); + DomainSepFeistelMulPopf() : RandomOracle(hashLength) {} + + ConstructedPopf construct() + { + return FeistelMulPopf(*this); + } + }; +} + +#else + +// Allow unit tests to use DomainSepFeistelMulPopf as a template argument. +namespace osuCrypto +{ + class DomainSepFeistelMulPopf; +} + +#endif diff --git a/libOTe/Tools/Popf/FeistelMulRistPopf.h b/libOTe/Tools/Popf/FeistelMulRistPopf.h new file mode 100644 index 00000000..8baf92d7 --- /dev/null +++ b/libOTe/Tools/Popf/FeistelMulRistPopf.h @@ -0,0 +1,102 @@ +#pragma once +#include "libOTe/config.h" +#ifdef ENABLE_MRR + +#include +#include +#include + +#include "libOTe/Tools/DefaultCurve.h" + +namespace osuCrypto +{ + class FeistelMulRistPopf + { + using Point = DefaultCurve::Point; + + public: + struct PopfFunc + { + unsigned char t[Point::size]; + unsigned char s[Point::size]; + }; + + typedef bool PopfIn; + typedef Point PopfOut; + + FeistelMulRistPopf(const RandomOracle& ro_) : ro(ro_) {} + FeistelMulRistPopf(RandomOracle&& ro_) : ro(ro_) {} + + PopfOut eval(PopfFunc f, PopfIn x) const + { + mulXor(f, x); + + Point t; + t.fromBytes(f.t); + addH(t, f.s, x, false); + + return t; + } + + PopfFunc program(PopfIn x, PopfOut y, PRNG& prng) const + { + PopfFunc f; + prng.get(f.s, Point::size); + + addH(y, f.s, x, true); + y.toBytes(f.t); + mulXor(f, x); + + return f; + } + + private: + void addH(Point& t, const unsigned char s[], PopfIn x, bool negate) const + { + RandomOracle h = ro; + h.Update(x); + h.Update(s, Point::size); + Point v = Point::fromHash(h); + + if (negate) + t -= v; + else + t += v; + } + + void mulXor(PopfFunc &f, PopfIn x) const + { + unsigned char mask = -(unsigned char) x; + for (size_t i = 0; i < Point::size; i++) + f.s[i] ^= mask & f.t[i]; + } + + RandomOracle ro; + }; + + class DomainSepFeistelMulRistPopf: public RandomOracle + { + using RandomOracle::Final; + using RandomOracle::outputLength; + + public: + typedef FeistelMulRistPopf ConstructedPopf; + const static size_t hashLength = DefaultCurve::Point::fromHashLength; + DomainSepFeistelMulRistPopf() : RandomOracle(hashLength) {} + + ConstructedPopf construct() + { + return FeistelMulRistPopf(*this); + } + }; +} + +#else + +// Allow unit tests to use DomainSepFeistelMulRistPopf as a template argument. +namespace osuCrypto +{ + class DomainSepFeistelMulRistPopf; +} + +#endif diff --git a/libOTe/Tools/Popf/FeistelPopf.h b/libOTe/Tools/Popf/FeistelPopf.h new file mode 100644 index 00000000..178f64f7 --- /dev/null +++ b/libOTe/Tools/Popf/FeistelPopf.h @@ -0,0 +1,104 @@ +#pragma once +#include "libOTe/config.h" +#if defined(ENABLE_MRR) || defined(ENABLE_MRR_TWIST) + +#include +#include +#include + +namespace osuCrypto +{ + class FeistelPopf + { + public: + struct PopfFunc + { + Block256 t; + block s[3]; + }; + + typedef bool PopfIn; + typedef Block256 PopfOut; + + FeistelPopf(const RandomOracle& ro_) : ro(ro_) {} + FeistelPopf(RandomOracle&& ro_) : ro(ro_) {} + + PopfOut eval(PopfFunc f, PopfIn x) const + { + RandomOracle h = ro; + h.Update(x); + + xorHPrime(f, h); + xorH(f, h); + + return f.t; + } + + PopfFunc program(PopfIn x, PopfOut y, PRNG& prng) const + { + RandomOracle h = ro; + h.Update(x); + + PopfFunc f; + f.t = y; + prng.get(f.s, 3); + + xorH(f, h); + xorHPrime(f, h); + + return f; + } + + private: + void xorH(PopfFunc &f, RandomOracle h) const + { + // Third block is unused. + block hOut[3]; + h.Update((unsigned char) 0); + h.Update(f.s); + h.Final(hOut); + + for (int i = 0; i < 2; i++) + f.t[i] = f.t[i] ^ hOut[i]; + } + + void xorHPrime(PopfFunc &f, RandomOracle hPrime) const + { + block hPrimeOut[3]; + hPrime.Update((unsigned char) 1); + hPrime.Update(f.t); + hPrime.Final(hPrimeOut); + + for (int i = 0; i < 3; i++) + f.s[i] = f.s[i] ^ hPrimeOut[i]; + } + + RandomOracle ro; + }; + + class DomainSepFeistelPopf: public RandomOracle + { + using RandomOracle::Final; + using RandomOracle::outputLength; + + public: + typedef FeistelPopf ConstructedPopf; + const static size_t hashLength = sizeof(block[3]); + DomainSepFeistelPopf() : RandomOracle(hashLength) {} + + ConstructedPopf construct() + { + return FeistelPopf(*this); + } + }; +} + +#else + +// Allow unit tests to use DomainSepFeistelPopf as a template argument. +namespace osuCrypto +{ + class DomainSepFeistelPopf; +} + +#endif diff --git a/libOTe/Tools/Popf/FeistelRistPopf.h b/libOTe/Tools/Popf/FeistelRistPopf.h new file mode 100644 index 00000000..583d6b13 --- /dev/null +++ b/libOTe/Tools/Popf/FeistelRistPopf.h @@ -0,0 +1,116 @@ +#pragma once +#include "libOTe/config.h" +#ifdef ENABLE_MRR + +#include +#include +#include +#include "libOTe/Tools/DefaultCurve.h" + +namespace osuCrypto +{ + class FeistelRistPopf + { + using Point = DefaultCurve::Point; + friend class DomainSepFeistelRistPopf; + + const static size_t hashLength = + Point::fromHashLength >= sizeof(block[3]) ? Point::fromHashLength : sizeof(block[3]); + + public: + struct PopfFunc + { + unsigned char t[Point::size]; + block s[3]; + }; + + typedef bool PopfIn; + typedef Point PopfOut; + + FeistelRistPopf(const RandomOracle& ro_) : ro(ro_) {} + FeistelRistPopf(RandomOracle&& ro_) : ro(ro_) {} + + PopfOut eval(PopfFunc f, PopfIn x) const + { + RandomOracle h = ro; + h.Update(x); + xorHPrime(f, h); + + Point t; + t.fromBytes(f.t); + addH(t, f.s, h, false); + + return t; + } + + PopfFunc program(PopfIn x, PopfOut y, PRNG& prng) const + { + RandomOracle h = ro; + h.Update(x); + + PopfFunc f; + prng.get(f.s, 3); + + addH(y, f.s, h, true); + y.toBytes(f.t); + xorHPrime(f, h); + + return f; + } + + private: + void addH(Point& t, const block s[], RandomOracle h, bool negate) const + { + unsigned char hOut[hashLength]; + h.Update((unsigned char) 0); + h.Update(s, 3); + h.Final(hOut); + + Point v = Point::fromHash(hOut); + if (negate) + t -= v; + else + t += v; + } + + void xorHPrime(PopfFunc &f, RandomOracle hPrime) const + { + block hPrimeOut[divCeil(hashLength, sizeof(block))]; + hPrime.Update((unsigned char) 1); + hPrime.Update(f.t, Point::size); + hPrime.Final((unsigned char*) &hPrimeOut); + + for (int i = 0; i < 3; i++) + f.s[i] = f.s[i] ^ hPrimeOut[i]; + } + + RandomOracle ro; + }; + + class DomainSepFeistelRistPopf: public RandomOracle + { + using RandomOracle::Final; + using RandomOracle::outputLength; + using Point = DefaultCurve::Point; + + public: + typedef FeistelRistPopf ConstructedPopf; + const static size_t hashLength = FeistelRistPopf::hashLength; + DomainSepFeistelRistPopf() : RandomOracle(hashLength) {} + + ConstructedPopf construct() + { + return FeistelRistPopf(*this); + } + }; +} + +#else + +// Allow unit tests to use DomainSepFeistelRistPopf as a template argument. +namespace osuCrypto +{ + class DomainSepFeistelRistPopf; +} + +#endif diff --git a/libOTe/Tools/Popf/MRPopf.h b/libOTe/Tools/Popf/MRPopf.h new file mode 100644 index 00000000..bf7ecb89 --- /dev/null +++ b/libOTe/Tools/Popf/MRPopf.h @@ -0,0 +1,81 @@ +#pragma once +#include "libOTe/config.h" +#if defined(ENABLE_MRR) || defined(ENABLE_MRR_TWIST) + +#include "libOTe/TwoChooseOne/OTExtInterface.h" +#include +#include +#include +#include + +namespace osuCrypto +{ + class MRPopf + { + public: + typedef std::array PopfFunc; + typedef bool PopfIn; + typedef Block256 PopfOut; + + MRPopf(const RandomOracle& ro_) : ro(ro_) {} + MRPopf(RandomOracle&& ro_) : ro(ro_) {} + + PopfOut eval(PopfFunc f, PopfIn x) const + { + Block256 mask; + RandomOracle roMask = ro; + roMask.Update(f[1-x]); + roMask.Final(mask); + + f[x][0] = f[x][0] ^ mask[0]; + f[x][1] = f[x][1] ^ mask[1]; + return f[x]; + } + + PopfFunc program(PopfIn x, PopfOut y, PRNG& prng) const + { + PopfFunc r; + prng.get(r[1-x].data(),32); + + Block256 mask; + RandomOracle roMask = ro; + roMask.Update(r[1-x]); + roMask.Final(mask); + + r[x] = y; + r[x][0] = r[x][0] ^ mask[0]; + r[x][1] = r[x][1] ^ mask[1]; + + return r; + } + + private: + RandomOracle ro; + }; + + class DomainSepMRPopf: public RandomOracle + { + using RandomOracle::Final; + using RandomOracle::outputLength; + + public: + typedef MRPopf ConstructedPopf; + const static size_t hashLength = sizeof(Block256); + DomainSepMRPopf() : RandomOracle(hashLength) {} + + ConstructedPopf construct() + { + return MRPopf(*this); + } + }; +} + +#else + +// Allow unit tests to use DomainSepMRPopf as a template argument. +namespace osuCrypto +{ + class DomainSepMRPopf; +} + +#endif diff --git a/libOTe/Tools/SilentPprf.cpp b/libOTe/Tools/SilentPprf.cpp index f4a623af..33dffde5 100644 --- a/libOTe/Tools/SilentPprf.cpp +++ b/libOTe/Tools/SilentPprf.cpp @@ -29,7 +29,6 @@ namespace osuCrypto mDomain = domainSize; mDepth = log2ceil(mDomain); mPntCount = pointCount; - //mPntCount8 = roundUpTo(pointCount, 8); mBaseOTs.resize(0, 0); } @@ -57,7 +56,7 @@ namespace osuCrypto throw RTE_LOC; mBaseOTs.resize(mPntCount, mDepth); - for (u64 i = 0; i < static_cast(baseMessages.size()); ++i) + for (u64 i = 0; i < static_cast(mBaseOTs.size()); ++i) mBaseOTs(i) = baseMessages[i]; } @@ -67,30 +66,29 @@ namespace osuCrypto throw RTE_LOC; mBaseOTs.resize(mPntCount, mDepth); - memcpy(mBaseOTs.data(), baseMessages.data(), baseMessages.size() * sizeof(block)); + memcpy(mBaseOTs.data(), baseMessages.data(), mBaseOTs.size() * sizeof(block)); } // This function copies the leaf values of the GGM tree // to the output location. There are two modes for this - // funcation. If transpose == false, then each tree is + // funcation. If interleaved == false, then each tree is // copied to a different contiguous regious of the output. - // If transpose == true, then trees are interleaved such that .... + // If interleaved == true, then trees are interleaved such that .... // @lvl - the GGM tree leafs. // @output - the location that the GGM leafs should be written to. // @numTrees - How many trees there are in total. // @tIdx - the index of the first tree. - // @transpose - do we interleave the output? + // @oFormat - do we interleave the output? // @mal - ... - block copyOut( + void copyOut( span> lvl, MatrixView output, u64 totalTrees, u64 tIdx, - bool transpose, - bool mal) + PprfOutputFormat oFormat) { - if (transpose) + if (oFormat == PprfOutputFormat::InterleavedTransposed) { // not having an even (8) number of trees is not supported. if (totalTrees % 8) @@ -104,84 +102,40 @@ namespace osuCrypto //auto sectionSize = - if (lvl.size() >= 16) - { + if (lvl.size() < 16) + throw RTE_LOC; - if (mal) - { - throw RTE_LOC; - auto section = tIdx / 8; - auto size = lvl.size() / 16; - auto begin = section * size; - auto end = std::min(begin + size, output.cols()); - - RandomOracle ro(sizeof(block)); - AES hc(toBlock(tIdx)); - std::array a, c; - AES ha(toBlock(345343)), hb(toBlock(6453323)); - block aSum0, aSum1, bSum0, bSum1, r0, r1; - for (u64 i = begin, k = 0; i < end; ++i, ++k) - { - auto& io = *(std::array*)(&lvl[k * 16]); - hc.ecbEncCounterMode(i, io.size(), c.data()); - ro.Update(io.data(), io.size()); - ha.ecbEncBlocks(io.data(), io.size(), a.data()); - for (u64 j = 0; j < 128; ++j) - { - mul128(a[j], c[j], r0, r1); - aSum0 = aSum0 ^ r0; - aSum1 = aSum1 ^ r1; - } - hb.ecbEncBlocks(io.data(), io.size(), a.data()); - for (u64 j = 0; j < 128; ++j) - { - mul128(a[j], c[j], r0, r1); - bSum0 = bSum0 ^ r0; - bSum1 = bSum1 ^ r1; - } - //{ + auto setIdx = tIdx / 8; + auto blocksPerSet = lvl.size() * 8 / 128; - //} - transpose128(io); - for (u64 j = 0; j < 128; ++j) - output(j, i) = io[j]; - } - block cc; - ro.Final(cc); - return aSum0 ^ aSum1^ bSum0^ bSum1 ^ cc; - } - else - { - auto setIdx = tIdx / 8; - auto blocksPerSet = lvl.size() * 8 / 128; - auto numSets = totalTrees / 8; - - auto begin = setIdx; - auto step = numSets; - auto end = std::min(begin + step * blocksPerSet, output.cols()); + auto numSets = totalTrees / 8; + auto begin = setIdx; + auto step = numSets; - for (u64 i = begin, k = 0; i < end; i += step, ++k) - { - auto& io = *(std::array*)(&lvl[k * 16]); - transpose128(io); - for (u64 j = 0; j < 128; ++j) - output(j, i) = io[j]; - } + if (oFormat == PprfOutputFormat::InterleavedTransposed) + { + auto end = std::min(begin + step * blocksPerSet, output.cols()); - return ZeroBlock; + for (u64 i = begin, k = 0; i < end; i += step, ++k) + { + auto& io = *(std::array*)(&lvl[k * 16]); + transpose128(io); + for (u64 j = 0; j < 128; ++j) + output(j, i) = io[j]; } - } else - throw RTE_LOC; + { + // no op + } + + } - else + else if (oFormat == PprfOutputFormat::Plain) { - if (mal) - throw RTE_LOC; auto curSize = std::min(totalTrees - tIdx, 8); if (curSize == 8) @@ -211,46 +165,66 @@ namespace osuCrypto oi[j] = ii[j]; } } - return ZeroBlock; } + else if (oFormat == PprfOutputFormat::Interleaved) + { + // no op + } + else + throw RTE_LOC; } - u64 transposePoint(u64 point, u64 treeIdx, u64 totalTrees) + u64 interleavedPoint(u64 point, u64 treeIdx, u64 totalTrees, u64 domain, PprfOutputFormat format) { - //auto totalTrees = points.size(); - auto numSets = totalTrees / 8; - auto setIdx = treeIdx / 8; - auto subIdx = treeIdx % 8; - auto sectionIdx = point / 16; - auto posIdx = point % 16; + switch (format) + { + case osuCrypto::PprfOutputFormat::Interleaved: + { + if (domain <= point) + return ~u64(0); - auto setOffset = setIdx * 128; - auto subOffset = subIdx + 8 * posIdx; - auto secOffset = sectionIdx * numSets * 128; + auto subTree = treeIdx % 8; + auto forest = treeIdx / 8; - return setOffset + subOffset + secOffset; - } + return (forest * domain + point) * 8 + subTree; + } + break; + case osuCrypto::PprfOutputFormat::InterleavedTransposed: + { + auto numSets = totalTrees / 8; - void transposePoints(span points) - { + auto setIdx = treeIdx / 8; + auto subIdx = treeIdx % 8; - for (i64 i = 0; i < points.size(); ++i) - { - points[i] = transposePoint(points[i], i, points.size()); + auto sectionIdx = point / 16; + auto posIdx = point % 16; + + + auto setOffset = setIdx * 128; + auto subOffset = subIdx + 8 * posIdx; + auto secOffset = sectionIdx * numSets * 128; + + return setOffset + subOffset + secOffset; + } + default: + throw RTE_LOC; + break; } + //auto totalTrees = points.size(); + } - void SilentMultiPprfReceiver::getTransposedPoints(span points) + void interleavedPoints(span points, u64 domain, PprfOutputFormat format) { - if (points.size() % 8) - throw RTE_LOC; - getPoints(points); - transposePoints(points); + for (i64 i = 0; i < points.size(); ++i) + { + points[i] = interleavedPoint(points[i], i, points.size(), domain, format); + } } u64 getActivePath(const span& choiceBits) @@ -265,38 +239,82 @@ namespace osuCrypto return point; } - void SilentMultiPprfReceiver::getPoints(span points) + void SilentMultiPprfReceiver::getPoints(span points, PprfOutputFormat format) { - memset(points.data(), 0, points.size() * sizeof(u64)); - for (u64 j = 0; j < mPntCount; ++j) + + switch (format) { - points[j] = getActivePath(mBaseChoices[j]); + case PprfOutputFormat::Plain: + + memset(points.data(), 0, points.size() * sizeof(u64)); + for (u64 j = 0; j < mPntCount; ++j) + { + points[j] = getActivePath(mBaseChoices[j]); + } + + break; + case PprfOutputFormat::InterleavedTransposed: + case PprfOutputFormat::Interleaved: + + if ((u64)points.size() != mPntCount) + throw RTE_LOC; + if (points.size() % 8) + throw RTE_LOC; + + getPoints(points, PprfOutputFormat::Plain); + interleavedPoints(points, mDomain, format); + + break; + default: + throw RTE_LOC; + break; } } - BitVector SilentMultiPprfReceiver::sampleChoiceBits(u64 modulus, bool transposed, PRNG& prng) + BitVector SilentMultiPprfReceiver::sampleChoiceBits(u64 modulus, PprfOutputFormat format, PRNG& prng) { BitVector choices(mPntCount * mDepth); - //Matrix baseChoices(mPntCount, mDepth); + mBaseChoices.resize(mPntCount, mDepth); for (u64 i = 0; i < mPntCount; ++i) { - auto base = transposePoint(0, i, mPntCount); - if (transposed && base >= modulus) - throw RTE_LOC; - u64 idx; - do { - for (u64 j = 0; j < mDepth; ++j) - mBaseChoices(i, j) = prng.getBit(); + switch (format) + { + case osuCrypto::PprfOutputFormat::Plain: + do { + for (u64 j = 0; j < mDepth; ++j) + mBaseChoices(i, j) = prng.getBit(); + idx = getActivePath(mBaseChoices[i]); + } while (idx >= modulus); + + break; + case osuCrypto::PprfOutputFormat::Interleaved: + case osuCrypto::PprfOutputFormat::InterleavedTransposed: + + // make sure that atleast the first element of this tree + // is within the modulus. + idx = interleavedPoint(0, i, mPntCount, mDomain, format); + if (idx >= modulus) + throw RTE_LOC; + + + do { + for (u64 j = 0; j < mDepth; ++j) + mBaseChoices(i, j) = prng.getBit(); + idx = getActivePath(mBaseChoices[i]); + + idx = interleavedPoint(idx, i, mPntCount, mDomain, format); + } while (idx >= modulus); - idx = getActivePath(mBaseChoices[i]); - - if (transposed) - idx = transposePoint(idx, i, mPntCount); - } while (idx >= modulus); + break; + default: + throw RTE_LOC; + break; + } + } for (u64 i = 0; i < mBaseChoices.size(); ++i) @@ -307,53 +325,83 @@ namespace osuCrypto return choices; } - block SilentMultiPprfSender::expand( - Channel& chl, + //block SilentMultiPprfSender::expand( + // Channel& chl, + // block value, + // PRNG& prng, + // MatrixView output, + // PprfOutputFormat oFormat, bool mal) + //{ + // return expand({ &chl, 1 }, value, prng, output, oFormat, mal); + //} + + void SilentMultiPprfSender::expand( + Channel& chls, block value, PRNG& prng, MatrixView output, - bool transpose, - bool mal) + PprfOutputFormat oFormat, + u64 numThreads) { - return expand({ &chl, 1 }, value, prng, output, transpose, mal); + std::vector vv(mPntCount, value); + expand(chls, vv, prng, output, oFormat, numThreads); } - block SilentMultiPprfSender::expand( - span chls, - block value, + void SilentMultiPprfSender::expand( + Channel& chl, + span value, PRNG& prng, MatrixView output, - bool transpose, - bool mal) + PprfOutputFormat oFormat, + u64 numThreads) { setValue(value); setTimePoint("pprf.send.start"); + gTimer.setTimePoint("send.enter"); - - if (transpose) + + if (oFormat == PprfOutputFormat::Plain) { - if (output.rows() != 128) + if (output.rows() != mDomain) throw RTE_LOC; - if (output.cols() > (mDomain * mPntCount + 127) / 128) + if (output.cols() != mPntCount) throw RTE_LOC; + } + else if (oFormat == PprfOutputFormat::InterleavedTransposed) + { + if (output.rows() != 128) + throw RTE_LOC; + + //if (output.cols() > (mDomain * mPntCount + 127) / 128) + // throw RTE_LOC; if (mPntCount & 7) throw RTE_LOC; } - else + else if (oFormat == PprfOutputFormat::Interleaved) { - if (output.rows() != mDomain) + if (output.cols() != 1) + throw RTE_LOC; + if (mDomain & 1) throw RTE_LOC; - if (output.cols() != mPntCount) + auto rows = output.rows(); + if (rows > (mDomain * mPntCount) || + rows / 128 != (mDomain * mPntCount) / 128) + throw RTE_LOC; + if (mPntCount & 7) throw RTE_LOC; } + else + { + throw RTE_LOC; + } + // ss will hold the malicious check block. Will be // the ZeroBlock if semi-honest - block ss = ZeroBlock; block seed = prng.get(); // A public PRF/PRG that we will use for deriving the GGM tree. @@ -361,6 +409,24 @@ namespace osuCrypto aes[0].setKey(toBlock(3242342)); aes[1].setKey(toBlock(8993849)); + struct TreeGrp + { + u64 g; + std::array>, 2> sums; + std::vector> lastOts; + }; + std::mutex sendMtx; + + //auto& chl = chls[0]; + auto sendOne = [&](TreeGrp& tg) + { + std::lock_guard lock(sendMtx); + chl.asyncSendCopy(tg.g); + chl.asyncSend(std::move(tg.sums[0])); + chl.asyncSend(std::move(tg.sums[1])); + chl.asyncSend(std::move(tg.lastOts)); + }; + // The function that each thread will run. Each thread will // process 8 GGM trees in parallel. auto routine = [&](u64 threadIdx) @@ -369,19 +435,24 @@ namespace osuCrypto PRNG prng(seed ^ toBlock(threadIdx)); // get our channel for this thread. - auto& chl = chls[threadIdx]; + //auto& chl = chls[threadIdx]; + + TreeGrp treeGrp; // mySums will hold the left and right GGM tree sums // for each level. For example sums[0][i][5] will // hold the sum of the left children for level i of // the 5th tree. - std::array>, 2> sums; + std::array>, 2>& sums = treeGrp.sums; - // tree will hold the full GGM tree. Not that there are 8 + auto dd = mDepth + (oFormat == PprfOutputFormat::Interleaved ? 0 : 1); + // tree will hold the full GGM tree. Note that there are 8 // indepenendent trees that are being processed together. // The trees are flattenned to that the children of j are // located at 2*j and 2*j+1. - std::vector> tree((1ull << (mDepth + 1))); + //std::vector> tree((1ull << (dd))); + std::unique_ptr uPtr(new block[8 * (1ull << (dd))]); + span> tree((std::array*)uPtr.get(), 1ull << (dd)); #ifdef DEBUG_PRINT_PPRF chl.asyncSendCopy(mValue); @@ -390,11 +461,20 @@ namespace osuCrypto // Returns the i'th level of the current 8 trees. The // children of node j on level i are located at 2*j and // 2*j+1 on level i+1. - auto getLevel = [&](u64 i) + auto getLevel = [&](u64 i, u64 g) { + + if (oFormat == PprfOutputFormat::Interleaved && i == mDepth) + { + auto b = (std::array*)output.data(); + auto forest = g / 8; + assert(g % 8 == 0); + b += forest * mDomain; + return span>(b, mDomain); + } + auto size = (1ull << i); auto offset = (size - 1); - auto b = tree.begin() + offset; auto e = b + size; return span>(b, e); @@ -415,13 +495,16 @@ namespace osuCrypto // This thread will process 8 trees at a time. It will interlace // thich sets of trees are processed with the other threads. - for (u64 g = threadIdx * 8; g < mPntCount; g += 8 * chls.size()) + for (u64 g = threadIdx * 8; g < mPntCount; g += 8 * numThreads) { + treeGrp.g = g; + // The number of real trees for this iteration. auto min = std::min(8, mPntCount - g); + gTimer.setTimePoint("send.start" + std::to_string(g)); // Populate the zero'th level of the GGM tree with random seeds. - prng.get(getLevel(0)); + prng.get(getLevel(0, g)); // Allocate space for our sums of each level. sums[0].resize(mDepth); @@ -431,63 +514,64 @@ namespace osuCrypto for (u64 d = 0; d < mDepth; ++d) { // The previous level of the GGM tree. - auto level0 = getLevel(d); + auto level0 = getLevel(d, g); // The next level of theGGM tree that we are populating. - auto level1 = getLevel(d + 1); + auto level1 = getLevel(d + 1, g); // The total number of children in this level. auto width = static_cast(level1.size()); // For each child, populate the child by expanding the parent. - for (u64 childIdx = 0; childIdx < width; ++childIdx) + for (u64 childIdx = 0; childIdx < width; ) { - // The bit that indicates if we are on the left child (0) - // or on the right child (1). - u8 keep = childIdx & 1; - // Index of the parent in the previous level. auto parentIdx = childIdx >> 1; // The value of the parent. auto& parent = level0[parentIdx]; - // The child that we will write in this iteration. - auto& child = level1[childIdx]; - - // The sum that this child node belongs to. - auto& sum = sums[keep][d]; - - // Each parent is expanded into the left and right children - // using a different AES fixed-key. Therefore our OWF is: - // - // H(x) = (AES(k0, x) + x) || (AES(k1, x) + x); - // - // where each half defines one of the children. - aes[keep].ecbEncBlocks(parent.data(), 8, child.data()); - child[0] = child[0] ^ parent[0]; - child[1] = child[1] ^ parent[1]; - child[2] = child[2] ^ parent[2]; - child[3] = child[3] ^ parent[3]; - child[4] = child[4] ^ parent[4]; - child[5] = child[5] ^ parent[5]; - child[6] = child[6] ^ parent[6]; - child[7] = child[7] ^ parent[7]; - - // Update the running sums for this level. We keep - // a left and right totals for each level. - sum[0] = sum[0] ^ child[0]; - sum[1] = sum[1] ^ child[1]; - sum[2] = sum[2] ^ child[2]; - sum[3] = sum[3] ^ child[3]; - sum[4] = sum[4] ^ child[4]; - sum[5] = sum[5] ^ child[5]; - sum[6] = sum[6] ^ child[6]; - sum[7] = sum[7] ^ child[7]; - + // The bit that indicates if we are on the left child (0) + // or on the right child (1). + for (u64 keep = 0; keep < 2; ++keep, ++childIdx) + { + // The child that we will write in this iteration. + auto& child = level1[childIdx]; + + // The sum that this child node belongs to. + auto& sum = sums[keep][d]; + + // Each parent is expanded into the left and right children + // using a different AES fixed-key. Therefore our OWF is: + // + // H(x) = (AES(k0, x) + x) || (AES(k1, x) + x); + // + // where each half defines one of the children. + aes[keep].ecbEnc8Blocks(parent.data(), child.data()); + child[0] = child[0] ^ parent[0]; + child[1] = child[1] ^ parent[1]; + child[2] = child[2] ^ parent[2]; + child[3] = child[3] ^ parent[3]; + child[4] = child[4] ^ parent[4]; + child[5] = child[5] ^ parent[5]; + child[6] = child[6] ^ parent[6]; + child[7] = child[7] ^ parent[7]; + + // Update the running sums for this level. We keep + // a left and right totals for each level. + sum[0] = sum[0] ^ child[0]; + sum[1] = sum[1] ^ child[1]; + sum[2] = sum[2] ^ child[2]; + sum[3] = sum[3] ^ child[3]; + sum[4] = sum[4] ^ child[4]; + sum[5] = sum[5] ^ child[5]; + sum[6] = sum[6] ^ child[6]; + sum[7] = sum[7] ^ child[7]; + } } } + #ifdef DEBUG_PRINT_PPRF // If we are debugging, then send over the full tree // to make sure its correct on the other side. @@ -512,7 +596,7 @@ namespace osuCrypto } } - // For the last level, we aregoinf to do something special. + // For the last level, we are going to do something special. // The other party is currently missing both leaf children of // the active parent. Since this is the last level, we want // the inactive child to just be the normal value but the @@ -520,16 +604,17 @@ namespace osuCrypto // This will be done by sending the sums and the sums plus // delta and ensure that they can only decrypt the correct ones. auto d = mDepth - 1; - std::vector> lastOts(min); + std::vector>& lastOts = treeGrp.lastOts; + lastOts.resize(min); for (u64 j = 0; j < min; ++j) { // Construct the sums where we will allow the delta (mValue) // to either be on the left child or right child depending // on which has the active path. lastOts[j][0] = sums[0][d][j]; - lastOts[j][1] = sums[1][d][j] ^ mValue; + lastOts[j][1] = sums[1][d][j] ^ mValue[g + j]; lastOts[j][2] = sums[1][d][j]; - lastOts[j][3] = sums[0][d][j] ^ mValue; + lastOts[j][3] = sums[0][d][j] ^ mValue[g + j]; // We are going to expand the 128 bit OT string // into a 256 bit OT string using AES. @@ -564,23 +649,24 @@ namespace osuCrypto sums[1].resize(mDepth - 1); // Send the sums to the other party. - chl.asyncSend(std::move(sums[0])); - chl.asyncSend(std::move(sums[1])); + sendOne(treeGrp); + //chl.asyncSend(std::move(sums[0])); + //chl.asyncSend(std::move(sums[1])); - // send the special OT messages for the last level. - chl.asyncSend(std::move(lastOts)); + //// send the special OT messages for the last level. + //chl.asyncSend(std::move(lastOts)); + gTimer.setTimePoint("send.expand_send"); // copy the last level to the output. If desired, this is // where the tranpose is performed. - auto lvl = getLevel(mDepth); + auto lvl = getLevel(mDepth, g); // s is a checksum that is used for malicous security. - auto s = copyOut(lvl, output, mPntCount, g, transpose, mal); - ss = ss ^ s; + copyOut(lvl, output, mPntCount, g, oFormat); } }; - std::vector thrds(chls.size() - 1); + std::vector thrds(numThreads-1); for (u64 i = 0; i < thrds.size(); ++i) thrds[i] = std::thread(routine, i); @@ -589,76 +675,99 @@ namespace osuCrypto for (u64 i = 0; i < thrds.size(); ++i) thrds[i].join(); - return ss; + + + + mBaseOTs = {}; } - void SilentMultiPprfSender::setValue(block value) + void SilentMultiPprfSender::setValue(span value) { - mValue = value; + if ((u64)value.size() != mPntCount) + throw RTE_LOC; + + mValue.resize(mPntCount); + std::copy(value.begin(), value.end(), mValue.begin()); } void SilentMultiPprfSender::clear() { mBaseOTs.resize(0, 0); mDomain = 0; - mDepth = 0; + mDepth = 0; mPntCount = 0; } - block SilentMultiPprfReceiver::expand(Channel& chl, PRNG& prng, MatrixView output, bool transpose, - bool mal) - { - return expand({ &chl, 1 }, prng, output, transpose, mal); - } - - block SilentMultiPprfReceiver::expand(span chls, PRNG& prng, MatrixView output, bool transpose, - bool mal) + void SilentMultiPprfReceiver::expand(Channel& chl, PRNG& prng, MatrixView output, + PprfOutputFormat oFormat, + u64 numThreads) { setTimePoint("pprf.recv.start"); //lout << " d " << mDomain << " p " << mPntCount << " do " << mDepth << std::endl; - if (transpose) + if (oFormat == PprfOutputFormat::Plain) { - if (output.rows() != 128) + if (output.rows() != mDomain) throw RTE_LOC; - if (output.cols() > (mDomain * mPntCount + 127) / 128) + if (output.cols() != mPntCount) throw RTE_LOC; + } + else if (oFormat == PprfOutputFormat::InterleavedTransposed) + { + if (output.rows() != 128) + throw RTE_LOC; + + //if (output.cols() > (mDomain * mPntCount + 127) / 128) + // throw RTE_LOC; if (mPntCount & 7) throw RTE_LOC; } - else + else if (oFormat == PprfOutputFormat::Interleaved) { - if (output.rows() != mDomain) + if (output.cols() != 1) throw RTE_LOC; - - if (output.cols() != mPntCount) + if (mDomain & 1) + throw RTE_LOC; + auto rows = output.rows(); + if (rows > (mDomain * mPntCount) || + rows / 128 != (mDomain * mPntCount) / 128) throw RTE_LOC; + if (mPntCount & 7) + throw RTE_LOC; + } + else + { + throw RTE_LOC; } + gTimer.setTimePoint("recv.enter"); + // The vector holding the indices of the active // leaves. Each index is in [0,mDomain). std::vector points(mPntCount); - getPoints(points); - - // ss will hold the malicious check block. Will be - // the ZeroBlock if semi-honest - block ss = ZeroBlock; + getPoints(points, PprfOutputFormat::Plain); // A public PRF/PRG that we will use for deriving the GGM tree. std::array aes; aes[0].setKey(toBlock(3242342)); aes[1].setKey(toBlock(8993849)); + Timer& timer = gTimer; + //block X = prng.get(); + + + std::mutex recvMtx; // The function that each thread will run. Each thread will // process 8 GGM trees in parallel. auto routine = [&](u64 threadIdx) { // get our channel for this thread. - auto& chl = chls[threadIdx]; + //auto& chl = chls[threadIdx]; + gTimer.setTimePoint("recv.routine"); // mySums will hold the left and right GGM tree sums // for each level. For example mySums[5][0] will @@ -674,11 +783,18 @@ namespace osuCrypto theirSums[0].resize(mDepth - 1); theirSums[1].resize(mDepth - 1); + auto dd = mDepth + (oFormat == PprfOutputFormat::Interleaved ? 0 : 1); // tree will hold the full GGM tree. Not that there are 8 // indepenendent trees that are being processed together. // The trees are flattenned to that the children of j are // located at 2*j and 2*j+1. - std::vector> tree(1ull << (mDepth + 1)); + //std::vector> tree(1ull << (dd)); + std::unique_ptr uPtr(new block[8 * (1ull << (dd))]); + span> tree((std::array*)uPtr.get(), 1ull << (dd)); + + gTimer.setTimePoint("recv.alloc"); + + //std::vector> stack(mDepth); #ifdef DEBUG_PRINT_PPRF // This will be the full tree and is sent by the reciever to help debug. @@ -692,12 +808,22 @@ namespace osuCrypto // Returns the i'th level of the current 8 trees. The // children of node j on level i are located at 2*j and // 2*j+1 on level i+1. - auto getLevel = [&](u64 i, bool f = false) + auto getLevel = [&](u64 i, u64 g, bool f = false) { auto size = (1ull << i), offset = (size - 1); #ifdef DEBUG_PRINT_PPRF auto b = (f ? ftree.begin() : tree.begin()) + offset; #else + if (oFormat == PprfOutputFormat::Interleaved && i == mDepth) + { + auto b = (std::array*)output.data(); + auto forest = g / 8; + assert(g % 8 == 0); + b += forest * mDomain; + auto zone = span>(b, mDomain); + return zone; + } + auto b = tree.begin() + offset; #endif return span>(b, b + size); @@ -736,25 +862,37 @@ namespace osuCrypto }; #endif + + // The number of real trees for this iteration. + std::vector> lastOts(8); // This thread will process 8 trees at a time. It will interlace // thich sets of trees are processed with the other threads. - for (u64 g = threadIdx * 8; g < mPntCount; g += 8 * chls.size()) + for (u64 gg = threadIdx * 8; gg < mPntCount; gg += 8 * numThreads) { #ifdef DEBUG_PRINT_PPRF chl.recv(ftree); auto l1f = getLevel(1, true); #endif + //timer.setTimePoint("recv.start" + std::to_string(g)); // Receive their full set of sums for these 8 trees. - chl.recv(theirSums[0].data(), theirSums[0].size()); - chl.recv(theirSums[1].data(), theirSums[1].size()); - TODO("Optimize this recv so that if we have fewer than 8 trees then less data is sent.."); + u64 g; + { + std::lock_guard lock(recvMtx); + chl.recv(g); + chl.recv(theirSums[0].data(), theirSums[0].size()); + chl.recv(theirSums[1].data(), theirSums[1].size()); + chl.recv(lastOts.data(), lastOts.size()); + } + //TODO("Optimize this recv so that if we have fewer than 8 trees then less data is sent.."); - // The number of real trees for this iteration. - auto min = std::min(8, mPntCount - g); - auto l1 = getLevel(1); - for (u64 i = 0; i < min; ++i) + timer.setTimePoint("recv.recv"); + + + auto l1 = getLevel(1, g); + + for (u64 i = 0; i < 8; ++i) { // For the non-active path, set the child of the root node // as the OT message XOR'ed with the correction sum. @@ -784,10 +922,10 @@ namespace osuCrypto { // The already constructed level. Only missing the // GGM tree node value along the active path. - auto level0 = getLevel(d); + auto level0 = getLevel(d, g); // The next level that we want to construct. - auto level1 = getLevel(d + 1); + auto level1 = getLevel(d + 1, g); // Zero out the previous sums. memset(mySums[0].data(), 0, mySums[0].size() * sizeof(block)); @@ -798,57 +936,65 @@ namespace osuCrypto // active node will also be expanded. Later we will just // overwrite whatever the value was. This is an optimization. auto width = static_cast(level1.size()); - for (u64 childIdx = 0; childIdx < width; ++childIdx) + for (u64 childIdx = 0; childIdx < width; ) { - // The bit that indicates if we are on the left child (0) - // or on the right child (1). - u8 keep = childIdx & 1; // Index of the parent in the previous level. auto parentIdx = childIdx >> 1; // The value of the parent. - auto& parent = level0[parentIdx]; + auto parent = level0[parentIdx]; + + for (u64 keep = 0; keep < 2; ++keep, ++childIdx) + { + + //// The bit that indicates if we are on the left child (0) + //// or on the right child (1). + //u8 keep = childIdx & 1; + + + // The child that we will write in this iteration. + auto& child = level1[childIdx]; + + // Each parent is expanded into the left and right children + // using a different AES fixed-key. Therefore our OWF is: + // + // H(x) = (AES(k0, x) + x) || (AES(k1, x) + x); + // + // where each half defines one of the children. + aes[keep].ecbEnc8Blocks(parent.data(), child.data()); + child[0] = child[0] ^ parent[0]; + child[1] = child[1] ^ parent[1]; + child[2] = child[2] ^ parent[2]; + child[3] = child[3] ^ parent[3]; + child[4] = child[4] ^ parent[4]; + child[5] = child[5] ^ parent[5]; + child[6] = child[6] ^ parent[6]; + child[7] = child[7] ^ parent[7]; + - // The child that we will write in this iteration. - auto& child = level1[childIdx]; - - // Each parent is expanded into the left and right children - // using a different AES fixed-key. Therefore our OWF is: - // - // H(x) = (AES(k0, x) + x) || (AES(k1, x) + x); - // - // where each half defines one of the children. - aes[keep].ecbEncBlocks(parent.data(), 8, child.data()); - child[0] = child[0] ^ parent[0]; - child[1] = child[1] ^ parent[1]; - child[2] = child[2] ^ parent[2]; - child[3] = child[3] ^ parent[3]; - child[4] = child[4] ^ parent[4]; - child[5] = child[5] ^ parent[5]; - child[6] = child[6] ^ parent[6]; - child[7] = child[7] ^ parent[7]; #ifdef DEBUG_PRINT_PPRF - // For debugging, set the active path to zero. - for (u64 i = 0; i < 8; ++i) - if (eq(parent[i], ZeroBlock)) - child[i] = ZeroBlock; + // For debugging, set the active path to zero. + for (u64 i = 0; i < 8; ++i) + if (eq(parent[i], ZeroBlock)) + child[i] = ZeroBlock; #endif - // Update the running sums for this level. We keep - // a left and right totals for each level. Note that - // we are actually XOR in the incorrect value of the - // children of the active parent (assuming !DEBUG_PRINT_PPRF). - // This is ok since we will later XOR off these incorrect values. - auto& sum = mySums[keep]; - sum[0] = sum[0] ^ child[0]; - sum[1] = sum[1] ^ child[1]; - sum[2] = sum[2] ^ child[2]; - sum[3] = sum[3] ^ child[3]; - sum[4] = sum[4] ^ child[4]; - sum[5] = sum[5] ^ child[5]; - sum[6] = sum[6] ^ child[6]; - sum[7] = sum[7] ^ child[7]; + // Update the running sums for this level. We keep + // a left and right totals for each level. Note that + // we are actually XOR in the incorrect value of the + // children of the active parent (assuming !DEBUG_PRINT_PPRF). + // This is ok since we will later XOR off these incorrect values. + auto& sum = mySums[keep]; + sum[0] = sum[0] ^ child[0]; + sum[1] = sum[1] ^ child[1]; + sum[2] = sum[2] ^ child[2]; + sum[3] = sum[3] ^ child[3]; + sum[4] = sum[4] ^ child[4]; + sum[5] = sum[5] ^ child[5]; + sum[6] = sum[6] ^ child[6]; + sum[7] = sum[7] ^ child[7]; + } } // For everything but the last level we have to @@ -858,7 +1004,7 @@ namespace osuCrypto if (d != mDepth - 1) { - for (u64 i = 0; i < min; ++i) + for (u64 i = 0; i < 8; ++i) { // the index of the leaf node that is active. auto leafIdx = points[i + g]; @@ -906,17 +1052,18 @@ namespace osuCrypto } + timer.setTimePoint("recv.expanded"); + // Now processes the last level. This one is special // because we we must XOR in the correction value as // before but we must also fixed the child value for // the active child. To do this, we will receive 4 // values. Two for each case (left active or right active). - std::vector> lastOts(min); - chl.recv(lastOts); + timer.setTimePoint("recv.recvLast"); - auto level = getLevel(mDepth); + auto level = getLevel(mDepth, g); auto d = mDepth - 1; - for (u64 j = 0; j < min; ++j) + for (u64 j = 0; j < 8; ++j) { // The index of the child on the active path. auto activeChildIdx = points[j + g]; @@ -976,29 +1123,28 @@ namespace osuCrypto #endif } + timer.setTimePoint("recv.expandLast"); + // copy the last level to the output. If desired, this is // where the tranpose is performed. - auto lvl = getLevel(mDepth); + auto lvl = getLevel(mDepth, g); // s is a checksum that is used for malicous security. - block s = copyOut(lvl, output, mPntCount, g, transpose, mal); - ss = ss ^ s; + copyOut(lvl, output, mPntCount, g, oFormat); } }; - - - std::vector thrds(chls.size() - 1); + std::vector thrds(numThreads -1); for (u64 i = 0; i < thrds.size(); ++i) thrds[i] = std::thread(routine, i); - //routine(i); routine(thrds.size()); for (u64 i = 0; i < thrds.size(); ++i) thrds[i].join(); - return ss; + mBaseOTs = {}; + mBaseChoices = {}; } } diff --git a/libOTe/Tools/SilentPprf.h b/libOTe/Tools/SilentPprf.h index 95491c1a..ecbbebdb 100644 --- a/libOTe/Tools/SilentPprf.h +++ b/libOTe/Tools/SilentPprf.h @@ -12,11 +12,36 @@ namespace osuCrypto { + + enum class PprfOutputFormat + { + Plain, + Interleaved, + InterleavedTransposed + }; + + enum class OTType + { + Random, Correlated + }; + + enum class ChoiceBitPacking + { + False, True + }; + + enum class SilentSecType + { + SemiHonest, + Malicious, + //MaliciousFS + }; + class SilentMultiPprfSender : public TimerAdapter { public: u64 mDomain = 0, mDepth = 0, mPntCount = 0;// , mPntCount8; - block mValue; + std::vector mValue; bool mPrint = false; @@ -43,14 +68,25 @@ namespace osuCrypto void setBase(span> baseMessages); // expand the whole PPRF and store the result in output - block expand(Channel& chl, block value, PRNG& prng, MatrixView output, bool transpose, bool mal); - block expand(span chls, block value, PRNG& prng, MatrixView output, bool transpose, bool mal); + void expand(Channel& chl, block value, PRNG& prng, span output, PprfOutputFormat oFormat, u64 numThreads) + { + MatrixView o(output.data(), output.size(), 1); + expand(chl, value, prng, o, oFormat, numThreads); + } - void setValue(block value); + void expand(Channel& chl, block value, PRNG& prng, MatrixView output, PprfOutputFormat oFormat, u64 numThreads); + + void expand(Channel& chls, span value, PRNG& prng, span output, PprfOutputFormat oFormat, u64 numThreads) + { + MatrixView o(output.data(), output.size(), 1); + expand(chls, value, prng, o, oFormat, numThreads); + } + void expand(Channel& chl, span value, PRNG& prng, MatrixView output, PprfOutputFormat oFormat, u64 numThreads); + + + void setValue(span value); - // expand the next output.size() number of outputs and store the result in output. - //void yeild(Channel& chl, PRNG& prng, span output); void clear(); }; @@ -59,7 +95,7 @@ namespace osuCrypto class SilentMultiPprfReceiver : public TimerAdapter { public: - u64 mDomain = 0, mDepth = 0, mPntCount = 0;//, mPntCount8; + u64 mDomain = 0, mDepth = 0, mPntCount = 0; Matrix mBaseOTs; Matrix mBaseChoices; @@ -74,7 +110,7 @@ namespace osuCrypto void configure(u64 domainSize, u64 pointCount); - BitVector sampleChoiceBits(u64 modulus, bool tranposed, PRNG& prng); + BitVector sampleChoiceBits(u64 modulus, PprfOutputFormat format, PRNG& prng); // the number of base OTs that should be set. u64 baseOtCount() const; @@ -86,11 +122,14 @@ namespace osuCrypto void setBase(span baseMessages); - void getPoints(span points); - void getTransposedPoints(span points); + void getPoints(span points, PprfOutputFormat format); - block expand(Channel& chl, PRNG& prng, MatrixView output, bool transpose, bool mal); - block expand(span chl, PRNG& prng, MatrixView output, bool transpose, bool mal); + void expand(Channel& chl, PRNG& prng, span output, PprfOutputFormat oFormat, u64 numThreads) + { + MatrixView o(output.data(), output.size(), 1); + return expand(chl, prng, o, oFormat, numThreads); + } + void expand(Channel& chl, PRNG& prng, MatrixView output, PprfOutputFormat oFormat, u64 numThreads); void clear() { diff --git a/libOTe/Tools/Tools.cpp b/libOTe/Tools/Tools.cpp index 49d13b15..18756aaa 100644 --- a/libOTe/Tools/Tools.cpp +++ b/libOTe/Tools/Tools.cpp @@ -11,12 +11,109 @@ #include #include - +#include "libOTe/Tools/Tools.h" using std::array; namespace osuCrypto { + //bool gUseBgicksPprf(true); + +//using namespace std; + +// Utility function to do modular exponentiation. +// It returns (x^y) % p + u64 power(u64 x, u64 y, u64 p) + { + u64 res = 1; // Initialize result + x = x % p; // Update x if it is more than or + // equal to p + while (y > 0) + { + // If y is odd, multiply x with result + if (y & 1) + res = (res * x) % p; + + // y must be even now + y = y >> 1; // y = y/2 + x = (x * x) % p; + } + return res; + } + + // This function is called for all k trials. It returns + // false if n is composite and returns false if n is + // probably prime. + // d is an odd number such that d*2r = n-1 + // for some r >= 1 + bool millerTest(u64 d, PRNG& prng, u64 n) + { + // Pick a random number in [2..n-2] + // Corner cases make sure that n > 4 + u64 a = 2 + prng.get() % (n - 4); + + // Compute a^d % n + u64 x = power(a, d, n); + + if (x == 1 || x == n - 1) + return true; + + // Keep squaring x while one of the following doesn't + // happen + // (i) d does not reach n-1 + // (ii) (x^2) % n is not 1 + // (iii) (x^2) % n is not n-1 + while (d != n - 1) + { + x = (x * x) % n; + d *= 2; + + if (x == 1) return false; + if (x == n - 1) return true; + } + + // Return composite + return false; + } + + // It returns false if n is composite and returns true if n + // is probably prime. k is an input parameter that determines + // accuracy level. Higher value of k indicates more accuracy. + bool isPrime(u64 n, PRNG& prng, u64 k) + { + // Corner cases + if (n <= 1 || n == 4) return false; + if (n <= 3) return true; + + // Find r such that n = 2^d * r + 1 for some r >= 1 + u64 d = n - 1; + while (d % 2 == 0) + d /= 2; + + // Iterate given nber of 'k' times + for (u64 i = 0; i < k; i++) + if (!millerTest(d, prng, n)) + return false; + + return true; + } + + bool isPrime(u64 n) + { + PRNG prng(ZeroBlock); + return isPrime(n, prng); + } + + + u64 nextPrime(u64 n) + { + PRNG prng(ZeroBlock); + + while (isPrime(n, prng) == false) + ++n; + return n; + } + void print(array& inOut) { BitVector temp(128); diff --git a/libOTe/Tools/Tools.h b/libOTe/Tools/Tools.h index d991f85e..e90575a2 100644 --- a/libOTe/Tools/Tools.h +++ b/libOTe/Tools/Tools.h @@ -65,6 +65,10 @@ namespace osuCrypto { // c1 = _mm_xor_si128(c1, c4); // c2 = _mm_xor_si128(c2, c5); //} + class PRNG; + bool isPrime(u64 n, PRNG& prng, u64 k = 20); + bool isPrime(u64 n); + u64 nextPrime(u64 n); void print(std::array& inOut); diff --git a/libOTe/Tools/bitpolymul.cpp b/libOTe/Tools/bitpolymul.cpp index 7e009dca..bd5fce03 100644 --- a/libOTe/Tools/bitpolymul.cpp +++ b/libOTe/Tools/bitpolymul.cpp @@ -1,5 +1,5 @@ #include "bitpolymul.h" -#ifdef ENABLE_SILENTOT +#ifdef ENABLE_BITPOLYMUL #include #include #include @@ -14,8 +14,9 @@ #include using namespace oc; +using namespace bpm; -namespace bpm +namespace osuCrypto { void FFTPoly::resize(u64 n) { @@ -146,8 +147,8 @@ namespace bpm void bitpolymul(uint64_t* c, const uint64_t* a, const uint64_t* b, uint64_t _n_64) { i64 n = i64(_n_64); - bpm::FFTPoly A(span(a, n)); - bpm::FFTPoly B(span(b, n)); + FFTPoly A(span(a, n)); + FFTPoly B(span(b, n)); A.multEq(B); @@ -155,123 +156,5 @@ namespace bpm } - void bitpolymul_2_128(uint64_t* c, const uint64_t* a, const uint64_t* b, u64 _n_64) - { - if (0 == _n_64) return; - u64 n_64 = 0; - if (1 == _n_64) - n_64 = _n_64; - else { - n_64 = 1ull << oc::log2ceil(_n_64); - } - - if (256 > n_64) n_64 = 256; - - auto a_bc = bpm::aligned_vector(n_64); - auto b_bc = bpm::aligned_vector(n_64); - - memcpy(a_bc.data(), a, sizeof(uint64_t) * _n_64); - for (u64 i = _n_64; i < n_64; i++) a_bc[i] = 0; - bc_to_lch_2_unit256(a_bc.data(), n_64); - - memcpy(b_bc.data(), b, sizeof(uint64_t) * _n_64); - for (u64 i = _n_64; i < n_64; i++) b_bc[i] = 0; - bc_to_lch_2_unit256(b_bc.data(), n_64); - - - u64 n_terms = n_64; - u64 log_n = __builtin_ctzll(n_terms); - auto a_fx = bpm::aligned_vector(2 * n_terms); - auto b_fx = bpm::aligned_vector(2 * n_terms); - - encode_128_half_input_zero(a_fx.data(), a_bc.data(), n_terms); - encode_128_half_input_zero(b_fx.data(), b_bc.data(), n_terms); - - btfy_128(b_fx.data(), n_terms, 64 + log_n + 1); - btfy_128(a_fx.data(), n_terms, 64 + log_n + 1); - - for (u64 i = 0; i < n_terms; i++) - { - gf2ext128_mul_sse( - (uint8_t*)& a_fx[i * 2], - (uint8_t*)& a_fx[i * 2], - (uint8_t*)& b_fx[i * 2]); - } - - i_btfy_128(a_fx.data(), n_terms, 64 + log_n + 1); - - decode_128(b_fx.data(), a_fx.data(), n_terms); - - bc_to_mono_2_unit256(b_fx.data(), 2 * n_64); - - for (u64 i = 0; i < (2 * _n_64); i++) { - c[i] = b_fx[i]; - } - - } - - - - - - - /////////////////////////////////////////////////// - - - void bitpolymul_2_64(uint64_t* c, const uint64_t* a, const uint64_t* b, u64 _n_64) - { - if (0 == _n_64) return; - if (_n_64 > (1 << 26)) { printf("un-supported length of polynomials."); exit(-1); } - u64 n_64 = 0; - if (1 == _n_64) n_64 = _n_64; - else { - n_64 = 1ull << oc::log2ceil(_n_64); - } - - if (256 > n_64) n_64 = 256; - - auto a_bc_ = bpm::aligned_vector(n_64); - auto b_bc_ = bpm::aligned_vector(n_64); - uint64_t* a_bc = a_bc_.data(); - uint64_t* b_bc = b_bc_.data(); - - memcpy(a_bc, a, sizeof(uint64_t) * _n_64); - for (u64 i = _n_64; i < n_64; i++) a_bc[i] = 0; - bc_to_lch_2_unit256(a_bc, n_64); - - memcpy(b_bc, b, sizeof(uint64_t) * _n_64); - for (u64 i = _n_64; i < n_64; i++) b_bc[i] = 0; - bc_to_lch_2_unit256(b_bc, n_64); - - - u64 n_terms = n_64 * 2; - u64 log_n = __builtin_ctzll(n_terms); - - auto a_fx_ = bpm::aligned_vector(n_terms); - auto b_fx_ = bpm::aligned_vector(n_terms); - uint64_t* a_fx = a_fx_.data(); - uint64_t* b_fx = b_fx_.data(); - - encode_64_half_input_zero(a_fx, a_bc, n_terms); - encode_64_half_input_zero(b_fx, b_bc, n_terms); - - btfy_64(b_fx, n_terms, 32 + log_n + 1); - btfy_64(a_fx, n_terms, 32 + log_n + 1); - - for (u64 i = 0; i < n_terms; i += 4) { - cache_prefetch(&a_fx[i + 4], _MM_HINT_T0); - cache_prefetch(&b_fx[i + 4], _MM_HINT_T0); - gf2ext64_mul_4x4_avx2((uint8_t*)& a_fx[i], (uint8_t*)& a_fx[i], (uint8_t*)& b_fx[i]); - } - i_btfy_64(a_fx, n_terms, 32 + log_n + 1); - decode_64(b_fx, a_fx, n_terms); - - bc_to_mono_2_unit256(b_fx, n_terms); - - for (u64 i = 0; i < (2 * _n_64); i++) { - c[i] = b_fx[i]; - } - } - } #endif \ No newline at end of file diff --git a/libOTe/Tools/bitpolymul.h b/libOTe/Tools/bitpolymul.h index bc558f3f..f28ec4ae 100644 --- a/libOTe/Tools/bitpolymul.h +++ b/libOTe/Tools/bitpolymul.h @@ -1,48 +1,25 @@ #pragma once -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - - #include "libOTe/config.h" -#ifdef ENABLE_SILENTOT +#ifdef ENABLE_BITPOLYMUL #include #include #include #include -#include "bitpolymul/bpmDefines.h" +#include "bitpolymul/bitpolymul.h" -namespace bpm +namespace osuCrypto { + template + using aligned_vector = std::vector>; - void bitpolymul_2_128(uint64_t* c, const uint64_t* a, const uint64_t* b, u64 n_64); - - void bitpolymul_2_64(uint64_t* c, const uint64_t* a, const uint64_t* b, u64 n_64); - void bitpolymul(uint64_t* c, const uint64_t* a, const uint64_t* b, uint64_t n_64); - class FFTPoly { public: @@ -83,7 +60,13 @@ namespace bpm inline std::ostream& operator<<(std::ostream& o, const FFTPoly& p) { - o << toStr(p.mPoly); + //o << toStr(p.mPoly); + o << "[" << p.mPoly.size() << "]["; + for (const auto& v : p.mPoly) + { + o << v << ", "; + } + o << "]"; return o; } } diff --git a/libOTe/Tools/bitpolymul/bc.cpp b/libOTe/Tools/bitpolymul/bc.cpp deleted file mode 100644 index 99308b62..00000000 --- a/libOTe/Tools/bitpolymul/bc.cpp +++ /dev/null @@ -1,308 +0,0 @@ -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - -#include "bc.h" -#include "bpmDefines.h" - -#include -#include -#define BC_CODE_GEN - -#define LOG2(X) ((u64) (8*sizeof (u64) - __builtin_clzll((X)) - 1)) -#define MAX(x,y) (((x)>(y))?(x):(y)) -#define MIN(x,y) (((x)<(y))?(x):(y)) - -namespace bpm -{ - - - inline - void __xor_down_256(__m256i* poly, u64 dest_idx, u64 src_idx, u64 len) - { - for (u64 i = len; i > 0;) { - i--; - poly[dest_idx + i] = xor256(poly[dest_idx + i], poly[src_idx + i]); - } - } - - //USED; - inline - void __xor_up_256(__m256i* poly, u64 dest_idx, u64 src_idx, u64 len) - { - for (u64 i = 0; i < len; i++) { - poly[dest_idx + i] = xor256(poly[dest_idx + i], poly[src_idx + i]); - } - } - - inline - void __xor_down_256_2(__m256i* poly, u64 len, u64 l_st) { - __xor_down_256(poly, l_st, len, len); - } - - inline - void xor_up_256(__m256i* poly, u64 st, u64 len, u64 diff) - { - __xor_up_256(poly, st, diff + st, len); - } - - inline - void __xor_up_256_2(__m256i* poly, u64 len, u64 l_st) { - __xor_up_256(poly, l_st, len, len); - } - - - - __m256i _mm256_alignr_255bit_zerohigh(__m256i zerohigh, __m256i low) - { - __m256i l_shr_15 = _mm256_srli_epi16(low, 15); - __m256i r_1 = _mm256_permute2x128_si256(l_shr_15, zerohigh, 0x21); - return _mm256_srli_si256(r_1, 14); - } - - - __m256i _mm256_alignr_254bit_zerohigh(__m256i zerohigh, __m256i low) - { - __m256i l_shr_14 = _mm256_srli_epi16(low, 14); - __m256i r_2 = _mm256_permute2x128_si256(l_shr_14, zerohigh, 0x21); - return _mm256_srli_si256(r_2, 14); - } - - - __m256i _mm256_alignr_252bit_zerohigh(__m256i zerohigh, __m256i low) - { - __m256i l_shr_12 = _mm256_srli_epi16(low, 12); - __m256i r_4 = _mm256_permute2x128_si256(l_shr_12, zerohigh, 0x21); - return _mm256_srli_si256(r_4, 14); - } - - - __m256i _mm256_alignr_255bit(__m256i high, __m256i low) - { - __m256i l_shr_15 = _mm256_srli_epi16(low, 15); - __m256i h_shr_15 = _mm256_srli_epi16(high, 15); - __m256i h_shl_1 = _mm256_slli_epi16(high, 1); - __m256i r = xor256(h_shl_1, _mm256_slli_si256(h_shr_15, 2)); - - __m256i r_1 = _mm256_permute2x128_si256(l_shr_15, h_shr_15, 0x21); - r = xor256(r, _mm256_srli_si256(r_1, 14)); - return r; - } - - - __m256i _mm256_alignr_254bit(__m256i high, __m256i low) - { - __m256i l_shr_14 = _mm256_srli_epi16(low, 14); - __m256i h_shr_14 = _mm256_srli_epi16(high, 14); - __m256i h_shl_2 = _mm256_slli_epi16(high, 2); - __m256i r = xor256(h_shl_2, _mm256_slli_si256(h_shr_14, 2)); - - __m256i r_2 = _mm256_permute2x128_si256(l_shr_14, h_shr_14, 0x21); - r = xor256(r, _mm256_srli_si256(r_2, 14)); - return r; - } - - - __m256i _mm256_alignr_252bit(__m256i high, __m256i low) - { - __m256i l_shr_12 = _mm256_srli_epi16(low, 12); - __m256i h_shr_12 = _mm256_srli_epi16(high, 12); - __m256i h_shl_4 = _mm256_slli_epi16(high, 4); - __m256i r = xor256(h_shl_4, _mm256_slli_si256(h_shr_12, 2)); - - __m256i r_4 = _mm256_permute2x128_si256(l_shr_12, h_shr_12, 0x21); - r = xor256(r, _mm256_srli_si256(r_4, 14)); - return r; - } - - - __m256i _mm256_alignr_31byte(__m256i high, __m256i low) - { - __m256i l0 = _mm256_permute2x128_si256(low, high, 0x21); - return _mm256_alignr_epi8(high, l0, 15); - } - - - __m256i _mm256_alignr_30byte(__m256i high, __m256i low) - { - __m256i l0 = _mm256_permute2x128_si256(low, high, 0x21); - return _mm256_alignr_epi8(high, l0, 14); - } - - - __m256i _mm256_alignr_28byte(__m256i high, __m256i low) - { - __m256i l0 = _mm256_permute2x128_si256(low, high, 0x21); - return _mm256_alignr_epi8(high, l0, 12); - } - - - __m256i _mm256_alignr_24byte(__m256i high, __m256i low) - { - __m256i l0 = _mm256_permute2x128_si256(low, high, 0x21); - return _mm256_alignr_epi8(high, l0, 8); - } - - - __m256i _mm256_alignr_16byte(__m256i high, __m256i low) - { - return _mm256_permute2x128_si256(low, high, 0x21); - } - - //USED; - - __m256i (*_sh_op[8]) (__m256i h, __m256i l) = { - _mm256_alignr_255bit, _mm256_alignr_254bit, _mm256_alignr_252bit, _mm256_alignr_31byte, _mm256_alignr_30byte, _mm256_alignr_28byte, _mm256_alignr_24byte, _mm256_alignr_16byte - }; - - //USED; - - __m256i (*_sh_op_zerohigh[8]) (__m256i h, __m256i l) = { - _mm256_alignr_255bit_zerohigh , _mm256_alignr_254bit_zerohigh , _mm256_alignr_252bit_zerohigh , _mm256_alignr_31byte, _mm256_alignr_30byte, _mm256_alignr_28byte, _mm256_alignr_24byte, _mm256_alignr_16byte - }; - - - //USED; - inline - void __sh_xor_down(__m256i* poly256, u64 unit, u64 _op, __m256i zero) - { - u64 unit_2 = unit >> 1; - poly256[unit_2] = xor256(poly256[unit_2], _sh_op_zerohigh[_op](zero, poly256[unit - 1])); - for (u64 i = 0; i < unit_2 - 1; i++) { - poly256[unit_2 - 1 - i] = xor256(poly256[unit_2 - 1 - i], _sh_op[_op](poly256[unit - 1 - i], poly256[unit - 2 - i])); - } - poly256[0] = xor256(poly256[0], _sh_op[_op](poly256[unit_2], zero)); - } - - - //USED; - - void varsub_x256(__m256i* poly256, u64 n_256) - { - if (1 >= n_256) return; - u64 log_n = __builtin_ctzll(n_256); - __m256i zero = _mm256_setzero_si256(); - - while (log_n > 8) { - u64 unit = 1ull << log_n; - u64 num = n_256 / unit; - u64 unit_2 = unit >> 1; - for (u64 j = 0; j < num; j++) __xor_down_256_2(poly256 + j * unit, unit_2, (1ull << (log_n - 9))); - log_n--; - } - - for (u64 i = log_n; i > 0; i--) { - u64 unit = (1ull << i); - u64 num = n_256 / unit; - for (u64 j = 0; j < num; j++) __sh_xor_down(poly256 + j * unit, unit, i - 1, zero); - } - - } - - - //USED; - inline - void __sh_xor_up(__m256i* poly256, u64 unit, u64 _op, __m256i zero) - { - u64 unit_2 = unit >> 1; - poly256[0] = xor256(poly256[0], _sh_op[_op](poly256[unit_2], zero)); - for (u64 i = 0; i < unit_2 - 1; i++) { - poly256[i + 1] = xor256(poly256[i + 1], _sh_op[_op](poly256[unit_2 + i + 1], poly256[unit_2 + i])); - } - poly256[unit_2] = xor256(poly256[unit_2], _sh_op_zerohigh[_op](zero, poly256[unit - 1])); - } - - - - //USED; - - void i_varsub_x256(__m256i* poly256, u64 n_256) - { - if (1 >= n_256) return; - u64 log_n = __builtin_ctzll(n_256); - __m256i zero = _mm256_setzero_si256(); - - u64 _log_n = (log_n > 8) ? 8 : log_n; - for (u64 i = 1; i <= _log_n; i++) { - u64 unit = (1ull << i); - u64 num = n_256 / unit; - for (u64 j = 0; j < num; j++) __sh_xor_up(poly256 + j * unit, unit, i - 1, zero); - } - - for (u64 i = 9; i <= log_n; i++) { - u64 unit = 1ull << i; - u64 num = n_256 / unit; - u64 unit_2 = unit >> 1; - for (u64 j = 0; j < num; j++) __xor_up_256_2(poly256 + j * unit, unit_2, (1ull << (i - 9))); - } - } - - //USED; - void bc_to_lch_2_unit256(bc_sto_t* poly, u64 n_terms) - { - assert(0 == (n_terms & (n_terms - 1))); - assert(4 <= n_terms); - - __m256i* poly256 = (__m256i*) poly; - u64 n_256 = n_terms >> 2; - - varsub_x256(poly256, n_256); -#ifdef BC_CODE_GEN - int logn = LOG2(n_256); - bc_to_lch_256_30_12(poly256, logn); - for (int i = 0; i < (1 << (MAX(0, logn - 19))); ++i) { - bc_to_lch_256_19_17(poly256 + i * (1ull << 19), MIN(19, logn)); - } - for (int i = 0; i < (1 << (MAX(0, logn - 16))); ++i) { - bc_to_lch_256_16(poly256 + i * (1ull << 16), MIN(16, logn)); - } -#else - _bc_to_lch_256(poly256, n_256, 1); -#endif - } - - - //USED; - void bc_to_mono_2_unit256(bc_sto_t* poly, u64 n_terms) - { - assert(0 == (n_terms & (n_terms - 1))); - assert(4 <= n_terms); - - __m256i* poly256 = (__m256i*) poly; - u64 n_256 = n_terms >> 2; - -#ifdef BC_CODE_GEN - int logn = LOG2(n_256); - for (int i = 0; i < (1 << (MAX(0, logn - 16))); ++i) { - bc_to_mono_256_16(poly256 + i * (1ull << 16), MIN(16, logn)); - } - for (int i = 0; i < (1 << (MAX(0, logn - 19))); ++i) { - bc_to_mono_256_19_17(poly256 + i * (1ull << 19), MIN(19, logn)); - } - bc_to_mono_256_30_20(poly256, logn); -#else - _bc_to_mono_256(poly256, n_256, 1); -#endif - i_varsub_x256(poly256, n_256); - } - -} -#endif \ No newline at end of file diff --git a/libOTe/Tools/bitpolymul/bc.h b/libOTe/Tools/bitpolymul/bc.h deleted file mode 100644 index 2b864747..00000000 --- a/libOTe/Tools/bitpolymul/bc.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - -#include -#include "bpmDefines.h" - -namespace bpm { - - - typedef uint64_t bc_sto_t; - void bc_to_lch_256_30_12(__m256i* poly, int logn); - void bc_to_lch_256_19_17(__m256i* poly, int logn); - void bc_to_lch_256_16(__m256i* poly, int logn); - void bc_to_mono_256_16(__m256i* poly, int logn); - void bc_to_mono_256_19_17(__m256i* poly, int logn); - void bc_to_mono_256_30_20(__m256i* poly, int logn); - - void bc_to_lch_2_unit256(bc_sto_t* poly, u64 n_terms); - - void bc_to_mono_2_unit256(bc_sto_t* poly, u64 n_terms); - -} - - -#endif diff --git a/libOTe/Tools/bitpolymul/bc_to_gen_code.h b/libOTe/Tools/bitpolymul/bc_to_gen_code.h deleted file mode 100644 index 5e67e5d8..00000000 --- a/libOTe/Tools/bitpolymul/bc_to_gen_code.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - -#include -#define x(v1, v2) _mm256_xor_si256(v1,v2) -#define m __m256i - -#define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b) -#define BOOST_PP_CAT_I(a, b) a ## b - -#if _MSC_VER -# define BOOST_PP_VARIADIC_SIZE(...) BOOST_PP_CAT(BOOST_PP_VARIADIC_SIZE_I(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,),) -#else -# define BOOST_PP_VARIADIC_SIZE(...) BOOST_PP_VARIADIC_SIZE_I(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,) -#endif -#define BOOST_PP_VARIADIC_SIZE_I(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63, size, ...) size - - -inline void xorEq_1(m* v1, m v2) { *v1 = x(*v1, v2); } -inline void xorEq_2(m* v1, m v2, m v3) { *v1 = x(x(*v1, v2), v3); } -inline void xorEq_3(m* v1, m v2, m v3, m v4) { *v1 = x(x(x(*v1, v2), v3), v4); } -inline void xorEq_4(m* v1, m v2, m v3, m v4, m v5) { *v1 = x(x(x(x(*v1, v2), v3), v4), v5); } -inline void xorEq_5(m* v1, m v2, m v3, m v4, m v5, m v6) { *v1 = x(x(x(x(x(*v1, v2), v3), v4), v5), v6); } -inline void xorEq_6(m* v1, m v2, m v3, m v4, m v5, m v6, m v7) { *v1 = x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7); } -inline void xorEq_7(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8) { *v1 = x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8); } -inline void xorEq_8(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9) { *v1 = x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9); } -inline void xorEq_9(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10) { *v1 = x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10); } -inline void xorEq_10(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11) { *v1 = x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11); } -inline void xorEq_11(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12) { *v1 = x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12); } -inline void xorEq_12(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13); } -inline void xorEq_13(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14); } -inline void xorEq_14(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15); } -inline void xorEq_15(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16); } -inline void xorEq_16(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17); } -inline void xorEq_17(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18); } -inline void xorEq_18(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18, m v19) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18), v19); } -inline void xorEq_19(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18, m v19, m v20) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18), v19), v20); } -inline void xorEq_20(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18, m v19, m v20, m v21) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18), v19), v20), v21); } -inline void xorEq_21(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18, m v19, m v20, m v21, m v22) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18), v19), v20), v21), v22); } -inline void xorEq_22(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18, m v19, m v20, m v21, m v22, m v23) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18), v19), v20), v21), v22), v23); } - -#define xorEq(v1, ...) BOOST_PP_CAT(xorEq_, BOOST_PP_VARIADIC_SIZE(__VA_ARGS__))(&v1, __VA_ARGS__) - -#undef m -#undef x - -#endif \ No newline at end of file diff --git a/libOTe/Tools/bitpolymul/bc_to_lch_gen_code.cpp b/libOTe/Tools/bitpolymul/bc_to_lch_gen_code.cpp deleted file mode 100644 index fe5b184a..00000000 --- a/libOTe/Tools/bitpolymul/bc_to_lch_gen_code.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/* -Copyright (C) 2018 Wen-Ding Li - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - -#include "bc_to_gen_code.h" -namespace bpm { -void bc_to_lch_256_30_12(__m256i* poly, int logn){ -for(int offset=(1<<30);offset<(1<=offset+(1<<30)-1006632960;--i)xorEq(poly[i],poly[i+805306368]); -for(int i=offset+(1<<30)-1-1006632960;i>=offset+(1<<30)-1056964608;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960]); -for(int i=offset+(1<<30)-1-1056964608;i>=offset+(1<<30)-1069547520;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608]); -for(int i=offset+(1<<30)-1-1069547520;i>=offset+(1<<30)-1072693248;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520]); -for(int i=offset+(1<<30)-1-1072693248;i>=offset+(1<<30)-1073479680;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248]); -for(int i=offset+(1<<30)-1-1073479680;i>=offset+(1<<30)-1073676288;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680]); -for(int i=offset+(1<<30)-1-1073676288;i>=offset+(1<<30)-1073725440;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288]); -for(int i=offset+(1<<30)-1-1073725440;i>=offset+(1<<30)-1073737728;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440]); -for(int i=offset+(1<<30)-1-1073737728;i>=offset+(1<<30)-1073740800;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728]); -for(int i=offset+(1<<30)-1-1073740800;i>=offset+(1<<30)-1073741568;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800]); -for(int i=offset+(1<<30)-1-1073741568;i>=offset+(1<<30)-1073741760;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568]); -for(int i=offset+(1<<30)-1-1073741760;i>=offset+(1<<30)-1073741808;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760]); -for(int i=offset+(1<<30)-1-1073741808;i>=offset+(1<<30)-1073741820;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808]); -for(int i=offset+(1<<30)-1-1073741820;i>=offset+(1<<30)-1073741823;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820]); -for(int i=offset+(1<<30)-1-1073741823;i>=offset+(1<<30)-1073741824;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-0;i>=offset-805306368;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-805306368;i>=offset-1006632960;--i)xorEq(poly[i],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1006632960;i>=offset-1056964608;--i)xorEq(poly[i],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1056964608;i>=offset-1069547520;--i)xorEq(poly[i],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1069547520;i>=offset-1072693248;--i)xorEq(poly[i],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1072693248;i>=offset-1073479680;--i)xorEq(poly[i],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1073479680;i>=offset-1073676288;--i)xorEq(poly[i],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1073676288;i>=offset-1073725440;--i)xorEq(poly[i],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1073725440;i>=offset-1073737728;--i)xorEq(poly[i],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1073737728;i>=offset-1073740800;--i)xorEq(poly[i],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1073740800;i>=offset-1073741568;--i)xorEq(poly[i],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1073741568;i>=offset-1073741760;--i)xorEq(poly[i],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1073741760;i>=offset-1073741808;--i)xorEq(poly[i],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1073741808;i>=offset-1073741820;--i)xorEq(poly[i],poly[i+1073741820],poly[i+1073741823]); -for(int i=offset-1-1073741820;i>=offset-1073741823;--i)xorEq(poly[i],poly[i+1073741823]); - -} -for(int offset=(1<<29);offset<(1<=offset+(1<<29)-503316480;--i)xorEq(poly[i],poly[i+268435456]); -for(int i=offset+(1<<29)-1-503316480;i>=offset+(1<<29)-520093696;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480]); -for(int i=offset+(1<<29)-1-520093696;i>=offset+(1<<29)-534773760;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696]); -for(int i=offset+(1<<29)-1-534773760;i>=offset+(1<<29)-535822336;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760]); -for(int i=offset+(1<<29)-1-535822336;i>=offset+(1<<29)-536739840;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336]); -for(int i=offset+(1<<29)-1-536739840;i>=offset+(1<<29)-536805376;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840]); -for(int i=offset+(1<<29)-1-536805376;i>=offset+(1<<29)-536862720;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376]); -for(int i=offset+(1<<29)-1-536862720;i>=offset+(1<<29)-536866816;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720]); -for(int i=offset+(1<<29)-1-536866816;i>=offset+(1<<29)-536870400;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816]); -for(int i=offset+(1<<29)-1-536870400;i>=offset+(1<<29)-536870656;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400]); -for(int i=offset+(1<<29)-1-536870656;i>=offset+(1<<29)-536870880;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656]); -for(int i=offset+(1<<29)-1-536870880;i>=offset+(1<<29)-536870896;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880]); -for(int i=offset+(1<<29)-1-536870896;i>=offset+(1<<29)-536870910;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896]); -for(int i=offset+(1<<29)-1-536870910;i>=offset+(1<<29)-536870911;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910]); -for(int i=offset+(1<<29)-1-536870911;i>=offset+(1<<29)-536870912;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-0;i>=offset-268435456;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-268435456;i>=offset-503316480;--i)xorEq(poly[i],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-503316480;i>=offset-520093696;--i)xorEq(poly[i],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-520093696;i>=offset-534773760;--i)xorEq(poly[i],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-534773760;i>=offset-535822336;--i)xorEq(poly[i],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-535822336;i>=offset-536739840;--i)xorEq(poly[i],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-536739840;i>=offset-536805376;--i)xorEq(poly[i],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-536805376;i>=offset-536862720;--i)xorEq(poly[i],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-536862720;i>=offset-536866816;--i)xorEq(poly[i],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-536866816;i>=offset-536870400;--i)xorEq(poly[i],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-536870400;i>=offset-536870656;--i)xorEq(poly[i],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-536870656;i>=offset-536870880;--i)xorEq(poly[i],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-536870880;i>=offset-536870896;--i)xorEq(poly[i],poly[i+536870896],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-536870896;i>=offset-536870910;--i)xorEq(poly[i],poly[i+536870910],poly[i+536870911]); -for(int i=offset-1-536870910;i>=offset-536870911;--i)xorEq(poly[i],poly[i+536870911]); - -} -for(int offset=(1<<28);offset<(1<=offset+(1<<28)-267386880;--i)xorEq(poly[i],poly[i+251658240]); -for(int i=offset+(1<<28)-1-267386880;i>=offset+(1<<28)-268369920;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880]); -for(int i=offset+(1<<28)-1-268369920;i>=offset+(1<<28)-268431360;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920]); -for(int i=offset+(1<<28)-1-268431360;i>=offset+(1<<28)-268435200;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920],poly[i+268431360]); -for(int i=offset+(1<<28)-1-268435200;i>=offset+(1<<28)-268435440;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920],poly[i+268431360],poly[i+268435200]); -for(int i=offset+(1<<28)-1-268435440;i>=offset+(1<<28)-268435455;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920],poly[i+268431360],poly[i+268435200],poly[i+268435440]); -for(int i=offset+(1<<28)-1-268435455;i>=offset+(1<<28)-268435456;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920],poly[i+268431360],poly[i+268435200],poly[i+268435440],poly[i+268435455]); -for(int i=offset-1-0;i>=offset-251658240;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920],poly[i+268431360],poly[i+268435200],poly[i+268435440],poly[i+268435455]); -for(int i=offset-1-251658240;i>=offset-267386880;--i)xorEq(poly[i],poly[i+267386880],poly[i+268369920],poly[i+268431360],poly[i+268435200],poly[i+268435440],poly[i+268435455]); -for(int i=offset-1-267386880;i>=offset-268369920;--i)xorEq(poly[i],poly[i+268369920],poly[i+268431360],poly[i+268435200],poly[i+268435440],poly[i+268435455]); -for(int i=offset-1-268369920;i>=offset-268431360;--i)xorEq(poly[i],poly[i+268431360],poly[i+268435200],poly[i+268435440],poly[i+268435455]); -for(int i=offset-1-268431360;i>=offset-268435200;--i)xorEq(poly[i],poly[i+268435200],poly[i+268435440],poly[i+268435455]); -for(int i=offset-1-268435200;i>=offset-268435440;--i)xorEq(poly[i],poly[i+268435440],poly[i+268435455]); -for(int i=offset-1-268435440;i>=offset-268435455;--i)xorEq(poly[i],poly[i+268435455]); - -} -for(int offset=(1<<27);offset<(1<=offset+(1<<27)-100663296;--i)xorEq(poly[i],poly[i+67108864]); -for(int i=offset+(1<<27)-1-100663296;i>=offset+(1<<27)-117440512;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296]); -for(int i=offset+(1<<27)-1-117440512;i>=offset+(1<<27)-133693440;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512]); -for(int i=offset+(1<<27)-1-133693440;i>=offset+(1<<27)-133955584;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440]); -for(int i=offset+(1<<27)-1-133955584;i>=offset+(1<<27)-134086656;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584]); -for(int i=offset+(1<<27)-1-134086656;i>=offset+(1<<27)-134152192;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656]); -for(int i=offset+(1<<27)-1-134152192;i>=offset+(1<<27)-134215680;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192]); -for(int i=offset+(1<<27)-1-134215680;i>=offset+(1<<27)-134216704;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680]); -for(int i=offset+(1<<27)-1-134216704;i>=offset+(1<<27)-134217216;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704]); -for(int i=offset+(1<<27)-1-134217216;i>=offset+(1<<27)-134217472;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216]); -for(int i=offset+(1<<27)-1-134217472;i>=offset+(1<<27)-134217720;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472]); -for(int i=offset+(1<<27)-1-134217720;i>=offset+(1<<27)-134217724;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720]); -for(int i=offset+(1<<27)-1-134217724;i>=offset+(1<<27)-134217726;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724]); -for(int i=offset+(1<<27)-1-134217726;i>=offset+(1<<27)-134217727;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726]); -for(int i=offset+(1<<27)-1-134217727;i>=offset+(1<<27)-134217728;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-0;i>=offset-67108864;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-67108864;i>=offset-100663296;--i)xorEq(poly[i],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-100663296;i>=offset-117440512;--i)xorEq(poly[i],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-117440512;i>=offset-133693440;--i)xorEq(poly[i],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-133693440;i>=offset-133955584;--i)xorEq(poly[i],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-133955584;i>=offset-134086656;--i)xorEq(poly[i],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-134086656;i>=offset-134152192;--i)xorEq(poly[i],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-134152192;i>=offset-134215680;--i)xorEq(poly[i],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-134215680;i>=offset-134216704;--i)xorEq(poly[i],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-134216704;i>=offset-134217216;--i)xorEq(poly[i],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-134217216;i>=offset-134217472;--i)xorEq(poly[i],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-134217472;i>=offset-134217720;--i)xorEq(poly[i],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-134217720;i>=offset-134217724;--i)xorEq(poly[i],poly[i+134217724],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-134217724;i>=offset-134217726;--i)xorEq(poly[i],poly[i+134217726],poly[i+134217727]); -for(int i=offset-1-134217726;i>=offset-134217727;--i)xorEq(poly[i],poly[i+134217727]); - -} -for(int offset=(1<<26);offset<(1<=offset+(1<<26)-66846720;--i)xorEq(poly[i],poly[i+50331648]); -for(int i=offset+(1<<26)-1-66846720;i>=offset+(1<<26)-67043328;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720]); -for(int i=offset+(1<<26)-1-67043328;i>=offset+(1<<26)-67107840;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328]); -for(int i=offset+(1<<26)-1-67107840;i>=offset+(1<<26)-67108608;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328],poly[i+67107840]); -for(int i=offset+(1<<26)-1-67108608;i>=offset+(1<<26)-67108860;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328],poly[i+67107840],poly[i+67108608]); -for(int i=offset+(1<<26)-1-67108860;i>=offset+(1<<26)-67108863;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328],poly[i+67107840],poly[i+67108608],poly[i+67108860]); -for(int i=offset+(1<<26)-1-67108863;i>=offset+(1<<26)-67108864;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328],poly[i+67107840],poly[i+67108608],poly[i+67108860],poly[i+67108863]); -for(int i=offset-1-0;i>=offset-50331648;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328],poly[i+67107840],poly[i+67108608],poly[i+67108860],poly[i+67108863]); -for(int i=offset-1-50331648;i>=offset-66846720;--i)xorEq(poly[i],poly[i+66846720],poly[i+67043328],poly[i+67107840],poly[i+67108608],poly[i+67108860],poly[i+67108863]); -for(int i=offset-1-66846720;i>=offset-67043328;--i)xorEq(poly[i],poly[i+67043328],poly[i+67107840],poly[i+67108608],poly[i+67108860],poly[i+67108863]); -for(int i=offset-1-67043328;i>=offset-67107840;--i)xorEq(poly[i],poly[i+67107840],poly[i+67108608],poly[i+67108860],poly[i+67108863]); -for(int i=offset-1-67107840;i>=offset-67108608;--i)xorEq(poly[i],poly[i+67108608],poly[i+67108860],poly[i+67108863]); -for(int i=offset-1-67108608;i>=offset-67108860;--i)xorEq(poly[i],poly[i+67108860],poly[i+67108863]); -for(int i=offset-1-67108860;i>=offset-67108863;--i)xorEq(poly[i],poly[i+67108863]); - -} -for(int offset=(1<<25);offset<(1<=offset+(1<<25)-33423360;--i)xorEq(poly[i],poly[i+16777216]); -for(int i=offset+(1<<25)-1-33423360;i>=offset+(1<<25)-33488896;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360]); -for(int i=offset+(1<<25)-1-33488896;i>=offset+(1<<25)-33553920;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896]); -for(int i=offset+(1<<25)-1-33553920;i>=offset+(1<<25)-33554176;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896],poly[i+33553920]); -for(int i=offset+(1<<25)-1-33554176;i>=offset+(1<<25)-33554430;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896],poly[i+33553920],poly[i+33554176]); -for(int i=offset+(1<<25)-1-33554430;i>=offset+(1<<25)-33554431;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896],poly[i+33553920],poly[i+33554176],poly[i+33554430]); -for(int i=offset+(1<<25)-1-33554431;i>=offset+(1<<25)-33554432;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896],poly[i+33553920],poly[i+33554176],poly[i+33554430],poly[i+33554431]); -for(int i=offset-1-0;i>=offset-16777216;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896],poly[i+33553920],poly[i+33554176],poly[i+33554430],poly[i+33554431]); -for(int i=offset-1-16777216;i>=offset-33423360;--i)xorEq(poly[i],poly[i+33423360],poly[i+33488896],poly[i+33553920],poly[i+33554176],poly[i+33554430],poly[i+33554431]); -for(int i=offset-1-33423360;i>=offset-33488896;--i)xorEq(poly[i],poly[i+33488896],poly[i+33553920],poly[i+33554176],poly[i+33554430],poly[i+33554431]); -for(int i=offset-1-33488896;i>=offset-33553920;--i)xorEq(poly[i],poly[i+33553920],poly[i+33554176],poly[i+33554430],poly[i+33554431]); -for(int i=offset-1-33553920;i>=offset-33554176;--i)xorEq(poly[i],poly[i+33554176],poly[i+33554430],poly[i+33554431]); -for(int i=offset-1-33554176;i>=offset-33554430;--i)xorEq(poly[i],poly[i+33554430],poly[i+33554431]); -for(int i=offset-1-33554430;i>=offset-33554431;--i)xorEq(poly[i],poly[i+33554431]); - -} -for(int offset=(1<<24);offset<(1<=offset+(1<<24)-16776960;--i)xorEq(poly[i],poly[i+16711680]); -for(int i=offset+(1<<24)-1-16776960;i>=offset+(1<<24)-16777215;--i)xorEq(poly[i],poly[i+16711680],poly[i+16776960]); -for(int i=offset+(1<<24)-1-16777215;i>=offset+(1<<24)-16777216;--i)xorEq(poly[i],poly[i+16711680],poly[i+16776960],poly[i+16777215]); -for(int i=offset-1-0;i>=offset-16711680;--i)xorEq(poly[i],poly[i+16711680],poly[i+16776960],poly[i+16777215]); -for(int i=offset-1-16711680;i>=offset-16776960;--i)xorEq(poly[i],poly[i+16776960],poly[i+16777215]); -for(int i=offset-1-16776960;i>=offset-16777215;--i)xorEq(poly[i],poly[i+16777215]); - -} -for(int offset=(1<<23);offset<(1<=offset+(1<<23)-6291456;--i)xorEq(poly[i],poly[i+4194304]); -for(int i=offset+(1<<23)-1-6291456;i>=offset+(1<<23)-7340032;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456]); -for(int i=offset+(1<<23)-1-7340032;i>=offset+(1<<23)-7864320;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032]); -for(int i=offset+(1<<23)-1-7864320;i>=offset+(1<<23)-8126464;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320]); -for(int i=offset+(1<<23)-1-8126464;i>=offset+(1<<23)-8257536;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464]); -for(int i=offset+(1<<23)-1-8257536;i>=offset+(1<<23)-8323072;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536]); -for(int i=offset+(1<<23)-1-8323072;i>=offset+(1<<23)-8388480;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072]); -for(int i=offset+(1<<23)-1-8388480;i>=offset+(1<<23)-8388544;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480]); -for(int i=offset+(1<<23)-1-8388544;i>=offset+(1<<23)-8388576;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544]); -for(int i=offset+(1<<23)-1-8388576;i>=offset+(1<<23)-8388592;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576]); -for(int i=offset+(1<<23)-1-8388592;i>=offset+(1<<23)-8388600;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592]); -for(int i=offset+(1<<23)-1-8388600;i>=offset+(1<<23)-8388604;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600]); -for(int i=offset+(1<<23)-1-8388604;i>=offset+(1<<23)-8388606;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604]); -for(int i=offset+(1<<23)-1-8388606;i>=offset+(1<<23)-8388607;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606]); -for(int i=offset+(1<<23)-1-8388607;i>=offset+(1<<23)-8388608;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-0;i>=offset-4194304;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-4194304;i>=offset-6291456;--i)xorEq(poly[i],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-6291456;i>=offset-7340032;--i)xorEq(poly[i],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-7340032;i>=offset-7864320;--i)xorEq(poly[i],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-7864320;i>=offset-8126464;--i)xorEq(poly[i],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-8126464;i>=offset-8257536;--i)xorEq(poly[i],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-8257536;i>=offset-8323072;--i)xorEq(poly[i],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-8323072;i>=offset-8388480;--i)xorEq(poly[i],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-8388480;i>=offset-8388544;--i)xorEq(poly[i],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-8388544;i>=offset-8388576;--i)xorEq(poly[i],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-8388576;i>=offset-8388592;--i)xorEq(poly[i],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-8388592;i>=offset-8388600;--i)xorEq(poly[i],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-8388600;i>=offset-8388604;--i)xorEq(poly[i],poly[i+8388604],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-8388604;i>=offset-8388606;--i)xorEq(poly[i],poly[i+8388606],poly[i+8388607]); -for(int i=offset-1-8388606;i>=offset-8388607;--i)xorEq(poly[i],poly[i+8388607]); - -} -for(int offset=(1<<22);offset<(1<=offset+(1<<22)-3932160;--i)xorEq(poly[i],poly[i+3145728]); -for(int i=offset+(1<<22)-1-3932160;i>=offset+(1<<22)-4128768;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160]); -for(int i=offset+(1<<22)-1-4128768;i>=offset+(1<<22)-4194240;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768]); -for(int i=offset+(1<<22)-1-4194240;i>=offset+(1<<22)-4194288;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768],poly[i+4194240]); -for(int i=offset+(1<<22)-1-4194288;i>=offset+(1<<22)-4194300;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768],poly[i+4194240],poly[i+4194288]); -for(int i=offset+(1<<22)-1-4194300;i>=offset+(1<<22)-4194303;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768],poly[i+4194240],poly[i+4194288],poly[i+4194300]); -for(int i=offset+(1<<22)-1-4194303;i>=offset+(1<<22)-4194304;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768],poly[i+4194240],poly[i+4194288],poly[i+4194300],poly[i+4194303]); -for(int i=offset-1-0;i>=offset-3145728;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768],poly[i+4194240],poly[i+4194288],poly[i+4194300],poly[i+4194303]); -for(int i=offset-1-3145728;i>=offset-3932160;--i)xorEq(poly[i],poly[i+3932160],poly[i+4128768],poly[i+4194240],poly[i+4194288],poly[i+4194300],poly[i+4194303]); -for(int i=offset-1-3932160;i>=offset-4128768;--i)xorEq(poly[i],poly[i+4128768],poly[i+4194240],poly[i+4194288],poly[i+4194300],poly[i+4194303]); -for(int i=offset-1-4128768;i>=offset-4194240;--i)xorEq(poly[i],poly[i+4194240],poly[i+4194288],poly[i+4194300],poly[i+4194303]); -for(int i=offset-1-4194240;i>=offset-4194288;--i)xorEq(poly[i],poly[i+4194288],poly[i+4194300],poly[i+4194303]); -for(int i=offset-1-4194288;i>=offset-4194300;--i)xorEq(poly[i],poly[i+4194300],poly[i+4194303]); -for(int i=offset-1-4194300;i>=offset-4194303;--i)xorEq(poly[i],poly[i+4194303]); - -} -for(int offset=(1<<21);offset<(1<=offset+(1<<21)-1966080;--i)xorEq(poly[i],poly[i+1048576]); -for(int i=offset+(1<<21)-1-1966080;i>=offset+(1<<21)-2031616;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080]); -for(int i=offset+(1<<21)-1-2031616;i>=offset+(1<<21)-2097120;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616]); -for(int i=offset+(1<<21)-1-2097120;i>=offset+(1<<21)-2097136;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616],poly[i+2097120]); -for(int i=offset+(1<<21)-1-2097136;i>=offset+(1<<21)-2097150;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616],poly[i+2097120],poly[i+2097136]); -for(int i=offset+(1<<21)-1-2097150;i>=offset+(1<<21)-2097151;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616],poly[i+2097120],poly[i+2097136],poly[i+2097150]); -for(int i=offset+(1<<21)-1-2097151;i>=offset+(1<<21)-2097152;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616],poly[i+2097120],poly[i+2097136],poly[i+2097150],poly[i+2097151]); -for(int i=offset-1-0;i>=offset-1048576;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616],poly[i+2097120],poly[i+2097136],poly[i+2097150],poly[i+2097151]); -for(int i=offset-1-1048576;i>=offset-1966080;--i)xorEq(poly[i],poly[i+1966080],poly[i+2031616],poly[i+2097120],poly[i+2097136],poly[i+2097150],poly[i+2097151]); -for(int i=offset-1-1966080;i>=offset-2031616;--i)xorEq(poly[i],poly[i+2031616],poly[i+2097120],poly[i+2097136],poly[i+2097150],poly[i+2097151]); -for(int i=offset-1-2031616;i>=offset-2097120;--i)xorEq(poly[i],poly[i+2097120],poly[i+2097136],poly[i+2097150],poly[i+2097151]); -for(int i=offset-1-2097120;i>=offset-2097136;--i)xorEq(poly[i],poly[i+2097136],poly[i+2097150],poly[i+2097151]); -for(int i=offset-1-2097136;i>=offset-2097150;--i)xorEq(poly[i],poly[i+2097150],poly[i+2097151]); -for(int i=offset-1-2097150;i>=offset-2097151;--i)xorEq(poly[i],poly[i+2097151]); - -} -for(int offset=(1<<20);offset<(1<=offset+(1<<20)-1048560;--i)xorEq(poly[i],poly[i+983040]); -for(int i=offset+(1<<20)-1-1048560;i>=offset+(1<<20)-1048575;--i)xorEq(poly[i],poly[i+983040],poly[i+1048560]); -for(int i=offset+(1<<20)-1-1048575;i>=offset+(1<<20)-1048576;--i)xorEq(poly[i],poly[i+983040],poly[i+1048560],poly[i+1048575]); -for(int i=offset-1-0;i>=offset-983040;--i)xorEq(poly[i],poly[i+983040],poly[i+1048560],poly[i+1048575]); -for(int i=offset-1-983040;i>=offset-1048560;--i)xorEq(poly[i],poly[i+1048560],poly[i+1048575]); -for(int i=offset-1-1048560;i>=offset-1048575;--i)xorEq(poly[i],poly[i+1048575]); - -} -for(int offset=(1<<19);offset<(1<=offset+(1<<19)-393216;--i)xorEq(poly[i],poly[i+262144]); -for(int i=offset+(1<<19)-1-393216;i>=offset+(1<<19)-458752;--i)xorEq(poly[i],poly[i+262144],poly[i+393216]); -for(int i=offset+(1<<19)-1-458752;i>=offset+(1<<19)-524280;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752]); -for(int i=offset+(1<<19)-1-524280;i>=offset+(1<<19)-524284;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752],poly[i+524280]); -for(int i=offset+(1<<19)-1-524284;i>=offset+(1<<19)-524286;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752],poly[i+524280],poly[i+524284]); -for(int i=offset+(1<<19)-1-524286;i>=offset+(1<<19)-524287;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752],poly[i+524280],poly[i+524284],poly[i+524286]); -for(int i=offset+(1<<19)-1-524287;i>=offset+(1<<19)-524288;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752],poly[i+524280],poly[i+524284],poly[i+524286],poly[i+524287]); -for(int i=offset-1-0;i>=offset-262144;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752],poly[i+524280],poly[i+524284],poly[i+524286],poly[i+524287]); -for(int i=offset-1-262144;i>=offset-393216;--i)xorEq(poly[i],poly[i+393216],poly[i+458752],poly[i+524280],poly[i+524284],poly[i+524286],poly[i+524287]); -for(int i=offset-1-393216;i>=offset-458752;--i)xorEq(poly[i],poly[i+458752],poly[i+524280],poly[i+524284],poly[i+524286],poly[i+524287]); -for(int i=offset-1-458752;i>=offset-524280;--i)xorEq(poly[i],poly[i+524280],poly[i+524284],poly[i+524286],poly[i+524287]); -for(int i=offset-1-524280;i>=offset-524284;--i)xorEq(poly[i],poly[i+524284],poly[i+524286],poly[i+524287]); -for(int i=offset-1-524284;i>=offset-524286;--i)xorEq(poly[i],poly[i+524286],poly[i+524287]); -for(int i=offset-1-524286;i>=offset-524287;--i)xorEq(poly[i],poly[i+524287]); - -} -} - -void bc_to_lch_256_19_17(__m256i* poly, int logn){ -for(int offset=(1<<18);offset<(1<=offset+(1<<18)-262140;--i)xorEq(poly[i],poly[i+196608]); -for(int i=offset+(1<<18)-1-262140;i>=offset+(1<<18)-262143;--i)xorEq(poly[i],poly[i+196608],poly[i+262140]); -for(int i=offset+(1<<18)-1-262143;i>=offset+(1<<18)-262144;--i)xorEq(poly[i],poly[i+196608],poly[i+262140],poly[i+262143]); -for(int i=offset-1-0;i>=offset-196608;--i)xorEq(poly[i],poly[i+196608],poly[i+262140],poly[i+262143]); -for(int i=offset-1-196608;i>=offset-262140;--i)xorEq(poly[i],poly[i+262140],poly[i+262143]); -for(int i=offset-1-262140;i>=offset-262143;--i)xorEq(poly[i],poly[i+262143]); - -} -for(int offset=(1<<17);offset<(1<=offset+(1<<17)-131070;--i)xorEq(poly[i],poly[i+65536]); -for(int i=offset+(1<<17)-1-131070;i>=offset+(1<<17)-131071;--i)xorEq(poly[i],poly[i+65536],poly[i+131070]); -for(int i=offset+(1<<17)-1-131071;i>=offset+(1<<17)-131072;--i)xorEq(poly[i],poly[i+65536],poly[i+131070],poly[i+131071]); -for(int i=offset-1-0;i>=offset-65536;--i)xorEq(poly[i],poly[i+65536],poly[i+131070],poly[i+131071]); -for(int i=offset-1-65536;i>=offset-131070;--i)xorEq(poly[i],poly[i+131070],poly[i+131071]); -for(int i=offset-1-131070;i>=offset-131071;--i)xorEq(poly[i],poly[i+131071]); - -} -for(int offset=(1<<16);offset<(1<=offset+(1<<16)-65536;--i)xorEq(poly[i],poly[i+65535]); -for(int i=offset-1-0;i>=offset-65535;--i)xorEq(poly[i],poly[i+65535]); - -} -} - -void bc_to_lch_256_16(__m256i* poly, int logn){ -for(int offset=(1<<15);offset<(1<=offset+(1<<15)-24576;--i)xorEq(poly[i],poly[i+16384]); -for(int i=offset+(1<<15)-1-24576;i>=offset+(1<<15)-28672;--i)xorEq(poly[i],poly[i+16384],poly[i+24576]); -for(int i=offset+(1<<15)-1-28672;i>=offset+(1<<15)-30720;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672]); -for(int i=offset+(1<<15)-1-30720;i>=offset+(1<<15)-31744;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720]); -for(int i=offset+(1<<15)-1-31744;i>=offset+(1<<15)-32256;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744]); -for(int i=offset+(1<<15)-1-32256;i>=offset+(1<<15)-32512;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256]); -for(int i=offset+(1<<15)-1-32512;i>=offset+(1<<15)-32640;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512]); -for(int i=offset+(1<<15)-1-32640;i>=offset+(1<<15)-32704;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640]); -for(int i=offset+(1<<15)-1-32704;i>=offset+(1<<15)-32736;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704]); -for(int i=offset+(1<<15)-1-32736;i>=offset+(1<<15)-32752;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736]); -for(int i=offset+(1<<15)-1-32752;i>=offset+(1<<15)-32760;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752]); -for(int i=offset+(1<<15)-1-32760;i>=offset+(1<<15)-32764;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760]); -for(int i=offset+(1<<15)-1-32764;i>=offset+(1<<15)-32766;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764]); -for(int i=offset+(1<<15)-1-32766;i>=offset+(1<<15)-32767;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766]); -for(int i=offset+(1<<15)-1-32767;i>=offset+(1<<15)-32768;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-0;i>=offset-16384;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-16384;i>=offset-24576;--i)xorEq(poly[i],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-24576;i>=offset-28672;--i)xorEq(poly[i],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-28672;i>=offset-30720;--i)xorEq(poly[i],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-30720;i>=offset-31744;--i)xorEq(poly[i],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-31744;i>=offset-32256;--i)xorEq(poly[i],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-32256;i>=offset-32512;--i)xorEq(poly[i],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-32512;i>=offset-32640;--i)xorEq(poly[i],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-32640;i>=offset-32704;--i)xorEq(poly[i],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-32704;i>=offset-32736;--i)xorEq(poly[i],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-32736;i>=offset-32752;--i)xorEq(poly[i],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-32752;i>=offset-32760;--i)xorEq(poly[i],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-32760;i>=offset-32764;--i)xorEq(poly[i],poly[i+32764],poly[i+32766],poly[i+32767]); -for(int i=offset-1-32764;i>=offset-32766;--i)xorEq(poly[i],poly[i+32766],poly[i+32767]); -for(int i=offset-1-32766;i>=offset-32767;--i)xorEq(poly[i],poly[i+32767]); - -} -for(int offset=(1<<14);offset<(1<=offset+(1<<14)-15360;--i)xorEq(poly[i],poly[i+12288]); -for(int i=offset+(1<<14)-1-15360;i>=offset+(1<<14)-16128;--i)xorEq(poly[i],poly[i+12288],poly[i+15360]); -for(int i=offset+(1<<14)-1-16128;i>=offset+(1<<14)-16320;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128]); -for(int i=offset+(1<<14)-1-16320;i>=offset+(1<<14)-16368;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128],poly[i+16320]); -for(int i=offset+(1<<14)-1-16368;i>=offset+(1<<14)-16380;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128],poly[i+16320],poly[i+16368]); -for(int i=offset+(1<<14)-1-16380;i>=offset+(1<<14)-16383;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128],poly[i+16320],poly[i+16368],poly[i+16380]); -for(int i=offset+(1<<14)-1-16383;i>=offset+(1<<14)-16384;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128],poly[i+16320],poly[i+16368],poly[i+16380],poly[i+16383]); -for(int i=offset-1-0;i>=offset-12288;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128],poly[i+16320],poly[i+16368],poly[i+16380],poly[i+16383]); -for(int i=offset-1-12288;i>=offset-15360;--i)xorEq(poly[i],poly[i+15360],poly[i+16128],poly[i+16320],poly[i+16368],poly[i+16380],poly[i+16383]); -for(int i=offset-1-15360;i>=offset-16128;--i)xorEq(poly[i],poly[i+16128],poly[i+16320],poly[i+16368],poly[i+16380],poly[i+16383]); -for(int i=offset-1-16128;i>=offset-16320;--i)xorEq(poly[i],poly[i+16320],poly[i+16368],poly[i+16380],poly[i+16383]); -for(int i=offset-1-16320;i>=offset-16368;--i)xorEq(poly[i],poly[i+16368],poly[i+16380],poly[i+16383]); -for(int i=offset-1-16368;i>=offset-16380;--i)xorEq(poly[i],poly[i+16380],poly[i+16383]); -for(int i=offset-1-16380;i>=offset-16383;--i)xorEq(poly[i],poly[i+16383]); - -} -for(int offset=(1<<13);offset<(1<=offset+(1<<13)-7680;--i)xorEq(poly[i],poly[i+4096]); -for(int i=offset+(1<<13)-1-7680;i>=offset+(1<<13)-7936;--i)xorEq(poly[i],poly[i+4096],poly[i+7680]); -for(int i=offset+(1<<13)-1-7936;i>=offset+(1<<13)-8160;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936]); -for(int i=offset+(1<<13)-1-8160;i>=offset+(1<<13)-8176;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936],poly[i+8160]); -for(int i=offset+(1<<13)-1-8176;i>=offset+(1<<13)-8190;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936],poly[i+8160],poly[i+8176]); -for(int i=offset+(1<<13)-1-8190;i>=offset+(1<<13)-8191;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936],poly[i+8160],poly[i+8176],poly[i+8190]); -for(int i=offset+(1<<13)-1-8191;i>=offset+(1<<13)-8192;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936],poly[i+8160],poly[i+8176],poly[i+8190],poly[i+8191]); -for(int i=offset-1-0;i>=offset-4096;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936],poly[i+8160],poly[i+8176],poly[i+8190],poly[i+8191]); -for(int i=offset-1-4096;i>=offset-7680;--i)xorEq(poly[i],poly[i+7680],poly[i+7936],poly[i+8160],poly[i+8176],poly[i+8190],poly[i+8191]); -for(int i=offset-1-7680;i>=offset-7936;--i)xorEq(poly[i],poly[i+7936],poly[i+8160],poly[i+8176],poly[i+8190],poly[i+8191]); -for(int i=offset-1-7936;i>=offset-8160;--i)xorEq(poly[i],poly[i+8160],poly[i+8176],poly[i+8190],poly[i+8191]); -for(int i=offset-1-8160;i>=offset-8176;--i)xorEq(poly[i],poly[i+8176],poly[i+8190],poly[i+8191]); -for(int i=offset-1-8176;i>=offset-8190;--i)xorEq(poly[i],poly[i+8190],poly[i+8191]); -for(int i=offset-1-8190;i>=offset-8191;--i)xorEq(poly[i],poly[i+8191]); - -} -for(int offset=(1<<12);offset<(1<=offset+(1<<12)-4080;--i)xorEq(poly[i],poly[i+3840]); -for(int i=offset+(1<<12)-1-4080;i>=offset+(1<<12)-4095;--i)xorEq(poly[i],poly[i+3840],poly[i+4080]); -for(int i=offset+(1<<12)-1-4095;i>=offset+(1<<12)-4096;--i)xorEq(poly[i],poly[i+3840],poly[i+4080],poly[i+4095]); -for(int i=offset-1-0;i>=offset-3840;--i)xorEq(poly[i],poly[i+3840],poly[i+4080],poly[i+4095]); -for(int i=offset-1-3840;i>=offset-4080;--i)xorEq(poly[i],poly[i+4080],poly[i+4095]); -for(int i=offset-1-4080;i>=offset-4095;--i)xorEq(poly[i],poly[i+4095]); - -} -for(int offset=(1<<11);offset<(1<=offset+(1<<11)-1536;--i)xorEq(poly[i],poly[i+1024]); -for(int i=offset+(1<<11)-1-1536;i>=offset+(1<<11)-1792;--i)xorEq(poly[i],poly[i+1024],poly[i+1536]); -for(int i=offset+(1<<11)-1-1792;i>=offset+(1<<11)-2040;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792]); -for(int i=offset+(1<<11)-1-2040;i>=offset+(1<<11)-2044;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792],poly[i+2040]); -for(int i=offset+(1<<11)-1-2044;i>=offset+(1<<11)-2046;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792],poly[i+2040],poly[i+2044]); -for(int i=offset+(1<<11)-1-2046;i>=offset+(1<<11)-2047;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792],poly[i+2040],poly[i+2044],poly[i+2046]); -for(int i=offset+(1<<11)-1-2047;i>=offset+(1<<11)-2048;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792],poly[i+2040],poly[i+2044],poly[i+2046],poly[i+2047]); -for(int i=offset-1-0;i>=offset-1024;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792],poly[i+2040],poly[i+2044],poly[i+2046],poly[i+2047]); -for(int i=offset-1-1024;i>=offset-1536;--i)xorEq(poly[i],poly[i+1536],poly[i+1792],poly[i+2040],poly[i+2044],poly[i+2046],poly[i+2047]); -for(int i=offset-1-1536;i>=offset-1792;--i)xorEq(poly[i],poly[i+1792],poly[i+2040],poly[i+2044],poly[i+2046],poly[i+2047]); -for(int i=offset-1-1792;i>=offset-2040;--i)xorEq(poly[i],poly[i+2040],poly[i+2044],poly[i+2046],poly[i+2047]); -for(int i=offset-1-2040;i>=offset-2044;--i)xorEq(poly[i],poly[i+2044],poly[i+2046],poly[i+2047]); -for(int i=offset-1-2044;i>=offset-2046;--i)xorEq(poly[i],poly[i+2046],poly[i+2047]); -for(int i=offset-1-2046;i>=offset-2047;--i)xorEq(poly[i],poly[i+2047]); - -} -for(int offset=(1<<10);offset<(1<=offset+(1<<10)-1020;--i)xorEq(poly[i],poly[i+768]); -for(int i=offset+(1<<10)-1-1020;i>=offset+(1<<10)-1023;--i)xorEq(poly[i],poly[i+768],poly[i+1020]); -for(int i=offset+(1<<10)-1-1023;i>=offset+(1<<10)-1024;--i)xorEq(poly[i],poly[i+768],poly[i+1020],poly[i+1023]); -for(int i=offset-1-0;i>=offset-768;--i)xorEq(poly[i],poly[i+768],poly[i+1020],poly[i+1023]); -for(int i=offset-1-768;i>=offset-1020;--i)xorEq(poly[i],poly[i+1020],poly[i+1023]); -for(int i=offset-1-1020;i>=offset-1023;--i)xorEq(poly[i],poly[i+1023]); - -} -for(int offset=(1<<9);offset<(1<=offset+(1<<9)-510;--i)xorEq(poly[i],poly[i+256]); -for(int i=offset+(1<<9)-1-510;i>=offset+(1<<9)-511;--i)xorEq(poly[i],poly[i+256],poly[i+510]); -for(int i=offset+(1<<9)-1-511;i>=offset+(1<<9)-512;--i)xorEq(poly[i],poly[i+256],poly[i+510],poly[i+511]); -for(int i=offset-1-0;i>=offset-256;--i)xorEq(poly[i],poly[i+256],poly[i+510],poly[i+511]); -for(int i=offset-1-256;i>=offset-510;--i)xorEq(poly[i],poly[i+510],poly[i+511]); -for(int i=offset-1-510;i>=offset-511;--i)xorEq(poly[i],poly[i+511]); - -} -for(int offset=(1<<8);offset<(1<=offset+(1<<8)-256;--i)xorEq(poly[i],poly[i+255]); -for(int i=offset-1-0;i>=offset-255;--i)xorEq(poly[i],poly[i+255]); - -} -for(int offset=(1<<7);offset<(1<=offset+(1<<7)-96;--i)xorEq(poly[i],poly[i+64]); -for(int i=offset+(1<<7)-1-96;i>=offset+(1<<7)-112;--i)xorEq(poly[i],poly[i+64],poly[i+96]); -for(int i=offset+(1<<7)-1-112;i>=offset+(1<<7)-120;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112]); -for(int i=offset+(1<<7)-1-120;i>=offset+(1<<7)-124;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112],poly[i+120]); -for(int i=offset+(1<<7)-1-124;i>=offset+(1<<7)-126;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112],poly[i+120],poly[i+124]); -for(int i=offset+(1<<7)-1-126;i>=offset+(1<<7)-127;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112],poly[i+120],poly[i+124],poly[i+126]); -for(int i=offset+(1<<7)-1-127;i>=offset+(1<<7)-128;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112],poly[i+120],poly[i+124],poly[i+126],poly[i+127]); -for(int i=offset-1-0;i>=offset-64;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112],poly[i+120],poly[i+124],poly[i+126],poly[i+127]); -for(int i=offset-1-64;i>=offset-96;--i)xorEq(poly[i],poly[i+96],poly[i+112],poly[i+120],poly[i+124],poly[i+126],poly[i+127]); -for(int i=offset-1-96;i>=offset-112;--i)xorEq(poly[i],poly[i+112],poly[i+120],poly[i+124],poly[i+126],poly[i+127]); -for(int i=offset-1-112;i>=offset-120;--i)xorEq(poly[i],poly[i+120],poly[i+124],poly[i+126],poly[i+127]); -for(int i=offset-1-120;i>=offset-124;--i)xorEq(poly[i],poly[i+124],poly[i+126],poly[i+127]); -for(int i=offset-1-124;i>=offset-126;--i)xorEq(poly[i],poly[i+126],poly[i+127]); -for(int i=offset-1-126;i>=offset-127;--i)xorEq(poly[i],poly[i+127]); - -} -for(int offset=(1<<6);offset<(1<=offset+(1<<6)-60;--i)xorEq(poly[i],poly[i+48]); -for(int i=offset+(1<<6)-1-60;i>=offset+(1<<6)-63;--i)xorEq(poly[i],poly[i+48],poly[i+60]); -for(int i=offset+(1<<6)-1-63;i>=offset+(1<<6)-64;--i)xorEq(poly[i],poly[i+48],poly[i+60],poly[i+63]); -for(int i=offset-1-0;i>=offset-48;--i)xorEq(poly[i],poly[i+48],poly[i+60],poly[i+63]); -for(int i=offset-1-48;i>=offset-60;--i)xorEq(poly[i],poly[i+60],poly[i+63]); -for(int i=offset-1-60;i>=offset-63;--i)xorEq(poly[i],poly[i+63]); - -} -for(int offset=(1<<5);offset<(1<=offset+(1<<5)-30;--i)xorEq(poly[i],poly[i+16]); -for(int i=offset+(1<<5)-1-30;i>=offset+(1<<5)-31;--i)xorEq(poly[i],poly[i+16],poly[i+30]); -for(int i=offset+(1<<5)-1-31;i>=offset+(1<<5)-32;--i)xorEq(poly[i],poly[i+16],poly[i+30],poly[i+31]); -for(int i=offset-1-0;i>=offset-16;--i)xorEq(poly[i],poly[i+16],poly[i+30],poly[i+31]); -for(int i=offset-1-16;i>=offset-30;--i)xorEq(poly[i],poly[i+30],poly[i+31]); -for(int i=offset-1-30;i>=offset-31;--i)xorEq(poly[i],poly[i+31]); - -} -for(int offset=(1<<4);offset<(1<=offset+(1<<4)-16;--i)xorEq(poly[i],poly[i+15]); -for(int i=offset-1-0;i>=offset-15;--i)xorEq(poly[i],poly[i+15]); - -} -for(int offset=(1<<3);offset<(1<=offset+(1<<3)-6;--i)xorEq(poly[i],poly[i+4]); -for(int i=offset+(1<<3)-1-6;i>=offset+(1<<3)-7;--i)xorEq(poly[i],poly[i+4],poly[i+6]); -for(int i=offset+(1<<3)-1-7;i>=offset+(1<<3)-8;--i)xorEq(poly[i],poly[i+4],poly[i+6],poly[i+7]); -for(int i=offset-1-0;i>=offset-4;--i)xorEq(poly[i],poly[i+4],poly[i+6],poly[i+7]); -for(int i=offset-1-4;i>=offset-6;--i)xorEq(poly[i],poly[i+6],poly[i+7]); -for(int i=offset-1-6;i>=offset-7;--i)xorEq(poly[i],poly[i+7]); - -} -for(int offset=(1<<2);offset<(1<=offset+(1<<2)-4;--i)xorEq(poly[i],poly[i+3]); -for(int i=offset-1-0;i>=offset-3;--i)xorEq(poly[i],poly[i+3]); - -} -for(int offset=(1<<1);offset<(1<=offset+(1<<1)-2;--i)xorEq(poly[i],poly[i+1]); -for(int i=offset-1-0;i>=offset-1;--i)xorEq(poly[i],poly[i+1]); - -} -} -} -#endif \ No newline at end of file diff --git a/libOTe/Tools/bitpolymul/bc_to_mono_gen_code.cpp b/libOTe/Tools/bitpolymul/bc_to_mono_gen_code.cpp deleted file mode 100644 index 7e7960b1..00000000 --- a/libOTe/Tools/bitpolymul/bc_to_mono_gen_code.cpp +++ /dev/null @@ -1,484 +0,0 @@ -/* -Copyright (C) 2018 Wen-Ding Li - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - -//#pragma message("here ------------------------------"); - -#include "bc_to_gen_code.h" -namespace bpm{ -void bc_to_mono_256_16(__m256i* poly, int logn){ -for(int offset=(1<<1);offset<(1<. -*/ - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - -#include -#include -#include - -#include "transpose.h" - -namespace bpm { - - - inline - __m128i bitmat_prod_accu_64x128_M8R_sse(__m128i r0, const uint64_t* mat4R, uint64_t a) - { - const __m128i* mat128 = (const __m128i*)mat4R; - while (a) { - r0 = _mm_xor_si128(r0, _mm_load_si128(mat128 + (a & 0xff))); - mat128 += 256; - a >>= 8; - } - return r0; - } - - inline - void bitmatrix_prod_64x128_8R_sse(uint8_t* r, const uint64_t* mat4R, uint64_t a) - { - __m128i r0 = _mm_setzero_si128(); - r0 = bitmat_prod_accu_64x128_M8R_sse(r0, mat4R, a); - _mm_store_si128((__m128i*) r, r0); - } - - - //USED; - inline - void bitmatrix_prod_128x128_4R_b32_opt_avx2(uint8_t* r32, const uint64_t* matB4R, const uint8_t* a32) - { - alignas(32) uint8_t t32[32 * 16]; - tr_16x16_b2_avx2(t32, a32); - - __m256i* r = (__m256i*) r32; - const __m256i* tab = (const __m256i*) & matB4R[0]; - __m256i _0xf = _mm256_set1_epi8(0xf); - - for (unsigned i = 0; i < 8; i++) r[i] = _mm256_setzero_si256(); - for (unsigned i = 0; i < 16; i++) { - __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32)); - __m256i low1_low0 = _mm256_and_si256(temp, _0xf); - __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4); - - for (unsigned j = 0; j < 8; j++) { - __m256i tab_0 = tab[i * 16 + (j << 1)]; - __m256i tab_1 = tab[i * 16 + (j << 1) + 1]; - r[j] = _mm256_xor_si256(_mm256_xor_si256(r[j], _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - } - } - tab += 16 * 16; - r += 8; - for (unsigned i = 0; i < 8; i++) r[i] = _mm256_setzero_si256(); - for (unsigned i = 0; i < 16; i++) { - __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32)); - __m256i low1_low0 = _mm256_and_si256(temp, _0xf); - __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4); - - for (unsigned j = 0; j < 8; j++) { - __m256i tab_0 = tab[i * 16 + (j << 1)]; - __m256i tab_1 = tab[i * 16 + (j << 1) + 1]; - r[j] = _mm256_xor_si256(_mm256_xor_si256(r[j], _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - } - } - - tr_16x16_b2_avx2(r32, r32); - } - - - //USED; - inline - void bitmatrix_prod_64x128_4R_b32_opt_avx2(uint8_t* r128_32, const uint64_t* matB4R, const uint8_t* a64_32) - { - alignas(32) uint8_t t32[32 * 8]; - /// 0x10,0x11,0x12,.....0x2f - transpose_8x8_b4_avx2(t32, a64_32); - /// bitsliced: 0x10,0x14,0x18,0x1c, 0x20,0x24,0x28,0x2c, 0x11,0x15,0x19,0x1d, 0x21,0x25,0x29,0x2d, | - /// 0x12,0x16,0x1a,0x1e, 0x22,0x26,0x2a,0x2e, 0x13,0x17,0x1b,0x1f, 0x23,0x27,0x2b,0x2f, - - __m256i* r = (__m256i*) r128_32; - const __m256i* tab = (const __m256i*) & matB4R[0]; - __m256i _0xf = _mm256_set1_epi8(0xf); - - for (unsigned i = 0; i < 8; i++) r[i] = _mm256_setzero_si256(); - for (unsigned i = 0; i < 8; i++) { /// - __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32)); - __m256i low1_low0 = _mm256_and_si256(temp, _0xf); - __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4); - - for (unsigned j = 0; j < 8; j++) { - __m256i tab_0 = tab[i * 16 + (j << 1)]; - __m256i tab_1 = tab[i * 16 + (j << 1) + 1]; - r[j] = _mm256_xor_si256(_mm256_xor_si256(r[j], _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - } - } - tab += 16 * 16; - r += 8; - for (unsigned i = 0; i < 8; i++) r[i] = _mm256_setzero_si256(); - for (unsigned i = 0; i < 8; i++) { /// - __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32)); - __m256i low1_low0 = _mm256_and_si256(temp, _0xf); - __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4); - - for (unsigned j = 0; j < 8; j++) { - __m256i tab_0 = tab[i * 16 + (j << 1)]; - __m256i tab_1 = tab[i * 16 + (j << 1) + 1]; - r[j] = _mm256_xor_si256(_mm256_xor_si256(r[j], _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - } - } - - /// bitsliced: 0x10,0x14,0x18,0x1c, 0x20,0x24,0x28,0x2c, 0x11,0x15,0x19,0x1d, 0x21,0x25,0x29,0x2d, | - /// 0x12,0x16,0x1a,0x1e, 0x22,0x26,0x2a,0x2e, 0x13,0x17,0x1b,0x1f, 0x23,0x27,0x2b,0x2f, - tr_16x16_b2_avx2(r128_32, r128_32); - /// 0x10,0x12,0x14,....,0x2e,0x11,0x13,0x15,....,0x2d,0x2f - } - - - - inline - void bitmatrix_prod_64x64_4R_b64_avx2(uint8_t* r128_32, const uint64_t* matB4R, const uint8_t* a64_32) - { -#if 0 - bitmatrix_prod_64x64_4R_b32_avx2(r128_32, matB4R, a64_32); - bitmatrix_prod_64x64_4R_b32_avx2(r128_32 + 8 * 32, matB4R, a64_32 + 8 * 32); -#else - alignas(32) uint8_t t32[32 * 8]; - alignas(32) uint8_t u32[32 * 8]; - - /// 0x10,0x11,0x12,.....0x2f - transpose_8x8_b4_avx2(t32, a64_32); - transpose_8x8_b4_avx2(u32, a64_32 + 8 * 32); - /// bitsliced: 0x10,0x14,0x18,0x1c, 0x20,0x24,0x28,0x2c, 0x11,0x15,0x19,0x1d, 0x21,0x25,0x29,0x2d, | - /// 0x12,0x16,0x1a,0x1e, 0x22,0x26,0x2a,0x2e, 0x13,0x17,0x1b,0x1f, 0x23,0x27,0x2b,0x2f, - - const __m256i* tab = (const __m256i*) & matB4R[0]; - __m256i _0xf = _mm256_set1_epi8(0xf); - - __m256i r0 = _mm256_setzero_si256(); - __m256i r1 = _mm256_setzero_si256(); - __m256i r2 = _mm256_setzero_si256(); - __m256i r3 = _mm256_setzero_si256(); - __m256i r4 = _mm256_setzero_si256(); - __m256i r5 = _mm256_setzero_si256(); - __m256i r6 = _mm256_setzero_si256(); - __m256i r7 = _mm256_setzero_si256(); - for (unsigned i = 0; i < 8; i++) { /// - __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32)); - __m256i _0_low1_low0 = _mm256_and_si256(temp, _0xf); - __m256i _0_high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4); - - __m256i temp1 = _mm256_load_si256((__m256i*)(u32 + i * 32)); - __m256i _1_low1_low0 = _mm256_and_si256(temp1, _0xf); - __m256i _1_high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp1), 4); - - __m256i tab_0 = tab[i * 16]; - __m256i tab_1 = tab[i * 16 + 1]; - r0 = _mm256_xor_si256(_mm256_xor_si256(r0, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0)); - r4 = _mm256_xor_si256(_mm256_xor_si256(r4, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0)); - tab_0 = tab[i * 16 + 2]; - tab_1 = tab[i * 16 + 3]; - r1 = _mm256_xor_si256(_mm256_xor_si256(r1, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0)); - r5 = _mm256_xor_si256(_mm256_xor_si256(r5, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0)); - tab_0 = tab[i * 16 + 4]; - tab_1 = tab[i * 16 + 5]; - r2 = _mm256_xor_si256(_mm256_xor_si256(r2, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0)); - r6 = _mm256_xor_si256(_mm256_xor_si256(r6, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0)); - tab_0 = tab[i * 16 + 6]; - tab_1 = tab[i * 16 + 7]; - r3 = _mm256_xor_si256(_mm256_xor_si256(r3, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0)); - r7 = _mm256_xor_si256(_mm256_xor_si256(r7, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0)); - } - _mm256_store_si256((__m256i*)(r128_32 + 0), r0); - _mm256_store_si256((__m256i*)(r128_32 + 1 * 32), r1); - _mm256_store_si256((__m256i*)(r128_32 + 2 * 32), r2); - _mm256_store_si256((__m256i*)(r128_32 + 3 * 32), r3); - _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 0 * 32), r4); - _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 1 * 32), r5); - _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 2 * 32), r6); - _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 3 * 32), r7); - - r0 = _mm256_setzero_si256(); - r1 = _mm256_setzero_si256(); - r2 = _mm256_setzero_si256(); - r3 = _mm256_setzero_si256(); - r4 = _mm256_setzero_si256(); - r5 = _mm256_setzero_si256(); - r6 = _mm256_setzero_si256(); - r7 = _mm256_setzero_si256(); - for (unsigned i = 0; i < 8; i++) { /// - __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32)); - __m256i _0_low1_low0 = _mm256_and_si256(temp, _0xf); - __m256i _0_high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4); - - __m256i temp1 = _mm256_load_si256((__m256i*)(u32 + i * 32)); - __m256i _1_low1_low0 = _mm256_and_si256(temp1, _0xf); - __m256i _1_high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp1), 4); - - __m256i tab_0 = tab[i * 16 + 8]; - __m256i tab_1 = tab[i * 16 + 8 + 1]; - r0 = _mm256_xor_si256(_mm256_xor_si256(r0, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0)); - r4 = _mm256_xor_si256(_mm256_xor_si256(r4, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0)); - tab_0 = tab[i * 16 + 8 + 2]; - tab_1 = tab[i * 16 + 8 + 3]; - r1 = _mm256_xor_si256(_mm256_xor_si256(r1, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0)); - r5 = _mm256_xor_si256(_mm256_xor_si256(r5, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0)); - tab_0 = tab[i * 16 + 8 + 4]; - tab_1 = tab[i * 16 + 8 + 5]; - r2 = _mm256_xor_si256(_mm256_xor_si256(r2, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0)); - r6 = _mm256_xor_si256(_mm256_xor_si256(r6, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0)); - tab_0 = tab[i * 16 + 8 + 6]; - tab_1 = tab[i * 16 + 8 + 7]; - r3 = _mm256_xor_si256(_mm256_xor_si256(r3, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0)); - r7 = _mm256_xor_si256(_mm256_xor_si256(r7, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0)); - } - _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 0), r0); - _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 1 * 32), r1); - _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 2 * 32), r2); - _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 3 * 32), r3); - _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 0 * 32), r4); - _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 1 * 32), r5); - _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 2 * 32), r6); - _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 3 * 32), r7); - - transpose_8x8_b4_avx2(r128_32, r128_32); - transpose_8x8_b4_avx2(r128_32 + 8 * 32, r128_32 + 8 * 32); -#endif - } - - - inline - void bitmatrix_prod_64x64_h32zero_4R_b64_avx2(uint8_t* r128_32, const uint64_t* matB4R, const uint8_t* a64_32) - { - alignas(32) uint8_t t32[32 * 8]; - transpose_8x8_h4zero_b4_avx2(t32, a64_32); - transpose_8x8_h4zero_b4_avx2(t32 + 32 * 4, a64_32 + 32 * 8); - - const __m256i* tab = (const __m256i*) & matB4R[0]; - __m256i _0xf = _mm256_set1_epi8(0xf); - - __m256i r0, r1, r2, r3, r4, r5, r6, r7; - r0 = _mm256_setzero_si256(); - r1 = _mm256_setzero_si256(); - r2 = _mm256_setzero_si256(); - r3 = _mm256_setzero_si256(); - r4 = _mm256_setzero_si256(); - r5 = _mm256_setzero_si256(); - r6 = _mm256_setzero_si256(); - r7 = _mm256_setzero_si256(); - for (unsigned i = 0; i < 4; i++) { /// - __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32)); - __m256i low1_low0 = _mm256_and_si256(temp, _0xf); - __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4); - - __m256i _temp = _mm256_load_si256((__m256i*)(t32 + 4 * 32 + i * 32)); - __m256i _low1_low0 = _mm256_and_si256(_temp, _0xf); - __m256i _high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, _temp), 4); - - __m256i tab_0 = tab[i * 16 + 0 * 2]; - __m256i tab_1 = tab[i * 16 + 0 * 2 + 1]; - r0 = _mm256_xor_si256(_mm256_xor_si256(r0, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - r4 = _mm256_xor_si256(_mm256_xor_si256(r4, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0)); - tab_0 = tab[i * 16 + 1 * 2]; - tab_1 = tab[i * 16 + 1 * 2 + 1]; - r1 = _mm256_xor_si256(_mm256_xor_si256(r1, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - r5 = _mm256_xor_si256(_mm256_xor_si256(r5, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0)); - tab_0 = tab[i * 16 + 2 * 2]; - tab_1 = tab[i * 16 + 2 * 2 + 1]; - r2 = _mm256_xor_si256(_mm256_xor_si256(r2, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - r6 = _mm256_xor_si256(_mm256_xor_si256(r6, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0)); - tab_0 = tab[i * 16 + 3 * 2]; - tab_1 = tab[i * 16 + 3 * 2 + 1]; - r3 = _mm256_xor_si256(_mm256_xor_si256(r3, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - r7 = _mm256_xor_si256(_mm256_xor_si256(r7, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0)); - } - _mm256_store_si256((__m256i*)(r128_32 + 0 * 32 + 0), r0); - _mm256_store_si256((__m256i*)(r128_32 + 0 * 32 + 1 * 32), r1); - _mm256_store_si256((__m256i*)(r128_32 + 0 * 32 + 2 * 32), r2); - _mm256_store_si256((__m256i*)(r128_32 + 0 * 32 + 3 * 32), r3); - _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 0 * 32), r4); - _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 1 * 32), r5); - _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 2 * 32), r6); - _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 3 * 32), r7); - - r0 = _mm256_setzero_si256(); - r1 = _mm256_setzero_si256(); - r2 = _mm256_setzero_si256(); - r3 = _mm256_setzero_si256(); - r4 = _mm256_setzero_si256(); - r5 = _mm256_setzero_si256(); - r6 = _mm256_setzero_si256(); - r7 = _mm256_setzero_si256(); - for (unsigned i = 0; i < 4; i++) { /// - __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32)); - __m256i low1_low0 = _mm256_and_si256(temp, _0xf); - __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4); - - __m256i _temp = _mm256_load_si256((__m256i*)(t32 + 4 * 32 + i * 32)); - __m256i _low1_low0 = _mm256_and_si256(_temp, _0xf); - __m256i _high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, _temp), 4); - - __m256i tab_0 = tab[i * 16 + 4 * 2]; - __m256i tab_1 = tab[i * 16 + 4 * 2 + 1]; - r0 = _mm256_xor_si256(_mm256_xor_si256(r0, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - r4 = _mm256_xor_si256(_mm256_xor_si256(r4, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0)); - tab_0 = tab[i * 16 + 5 * 2]; - tab_1 = tab[i * 16 + 5 * 2 + 1]; - r1 = _mm256_xor_si256(_mm256_xor_si256(r1, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - r5 = _mm256_xor_si256(_mm256_xor_si256(r5, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0)); - tab_0 = tab[i * 16 + 6 * 2]; - tab_1 = tab[i * 16 + 6 * 2 + 1]; - r2 = _mm256_xor_si256(_mm256_xor_si256(r2, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - r6 = _mm256_xor_si256(_mm256_xor_si256(r6, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0)); - tab_0 = tab[i * 16 + 7 * 2]; - tab_1 = tab[i * 16 + 7 * 2 + 1]; - r3 = _mm256_xor_si256(_mm256_xor_si256(r3, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0)); - r7 = _mm256_xor_si256(_mm256_xor_si256(r7, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0)); - } - _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 0), r0); - _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 1 * 32), r1); - _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 2 * 32), r2); - _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 3 * 32), r3); - _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 0 * 32), r4); - _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 1 * 32), r5); - _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 2 * 32), r6); - _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 3 * 32), r7); - - transpose_8x8_b4_avx2(r128_32, r128_32); - transpose_8x8_b4_avx2(r128_32 + 32 * 8, r128_32 + 32 * 8); - } - -} - - -#endif diff --git a/libOTe/Tools/bitpolymul/bpmDefines.h b/libOTe/Tools/bitpolymul/bpmDefines.h deleted file mode 100644 index 3a55aaf1..00000000 --- a/libOTe/Tools/bitpolymul/bpmDefines.h +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace bpm -{ - - template - using aligned_vector = std::vector>; - - template - using span = oc::span; - - using u64 = oc::u64; - using u32 = oc::u32; - using u8 = oc::u8; - - - template - struct toStr_ { - const T& mV; - toStr_(const T& v) : mV(v) {} - - - }; - template - inline toStr_ toStr(const T& v) - { - return toStr_(v); - } - template - inline std::ostream& operator<<(std::ostream& o, const toStr_& t) - { - o << "[" < -#include - -//#define (x) - - inline int __builtin_ctz(uint32_t x) { - unsigned long ret; - _BitScanForward(&ret, x); - return (int)ret; -} - - inline int __builtin_ctzll(unsigned long long x) { - unsigned long ret; - _BitScanForward64(&ret, x); - return (int)ret; -} - - - - inline int __builtin_ctzl(unsigned long x) { return sizeof(x) == 8 ? __builtin_ctzll(x) : __builtin_ctz((uint32_t)x); } - inline int __builtin_clz(uint32_t x) { return (int)__lzcnt(x); } - inline int __builtin_clzll(unsigned long long x) { return (int)__lzcnt64(x); } - inline int __builtin_clzl(unsigned long x) { return sizeof(x) == 8 ? __builtin_clzll(x) : __builtin_clz((uint32_t)x); } - - inline int __builtin_ctzl(unsigned long long x) { return __builtin_ctzll(x); } - inline int __builtin_clzl(unsigned long long x) { return __builtin_clzll(x); } - -#endif - -#include -#include -#include - -#define xor128(v1,v2) _mm_xor_si128(v1,v2) -#define xor256(v1,v2) _mm256_xor_si256(v1,v2) -#define and128(v1,v2) _mm_and_si128(v1,v2) -#define and256(v1,v2) _mm256_and_si256(v1,v2) -#define or128(v1,v2) _mm_or_si128(v1,v2) -#define or256(v1,v2) _mm256_or_si256(v1,v2) - - -#define cache_prefetch(d, p) _mm_prefetch((const char*)d, p) \ No newline at end of file diff --git a/libOTe/Tools/bitpolymul/btfy.cpp b/libOTe/Tools/bitpolymul/btfy.cpp deleted file mode 100644 index efd394d2..00000000 --- a/libOTe/Tools/bitpolymul/btfy.cpp +++ /dev/null @@ -1,1049 +0,0 @@ -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - -#include - -#include "gfext_aesni.h" -#include "string.h" - -#include "bpmDefines.h" - -#include "bitmat_prod.h" - -#include "gf2128_cantor_iso.h" -#include "gf264_cantor_iso.h" - -///////////////////////////////////////////////// -/// -/// field isomorphism. Cantor --> GF(2^128). -/// -////////////////////////////////////////////////////// - - -namespace bpm { - - //USED; - inline - __m128i gf_isomorphism_single_bit(u64 ith_bit) - { - return _mm_load_si128((__m128i*) (&gfCantorto2128[ith_bit])); - } - - //USED; - inline - __m128i gf_isomorphism(uint64_t a_in_cantor) - { - alignas(32) uint8_t a_iso[16]; - bitmatrix_prod_64x128_8R_sse(a_iso, gfCantorto2128_8R, a_in_cantor); - return _mm_load_si128((__m128i*) a_iso); - } - - - - ///////////////////////////////////////////////// - /// - /// Butterfly network. pclmulqdq version. - /// - ////////////////////////////////////////////////////// - - - - /////// one layer ///////////////////// - - //USED; - inline - __m128i butterfly(__m128i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i++) { - poly[i] = xor128(poly[i], _gf2ext128_mul_sse(poly[unit_2 + i], a)); - cache_prefetch(&poly[i + 1], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0); - poly[unit_2 + i] = xor128(poly[unit_2 + i], poly[i]); - } - return a; - } - - - - //USED; - inline - __m128i butterfly_avx2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i++) { - poly[i] = xor256(poly[i], _gf2ext128_mul_2x1_avx2(poly[unit_2 + i], a)); - cache_prefetch(&poly[i + 1], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0); - poly[unit_2 + i] = xor256(poly[unit_2 + i], poly[i]); - } - return a; - } - - - //USED; - inline - __m128i butterfly_avx2_b2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i += 2) { - __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]); - __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]); - cache_prefetch(&poly[i], _MM_HINT_T0); - cache_prefetch(&poly[i + 1], _MM_HINT_T0); - __m256i ap0 = _gf2ext128_mul_2x1_avx2(p0, a); - __m256i ap1 = _gf2ext128_mul_2x1_avx2(p1, a); - - __m256i q0 = _mm256_load_si256(&poly[i]); - __m256i q1 = _mm256_load_si256(&poly[i + 1]); - - cache_prefetch(&poly[unit_2 + i + 2], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 3], _MM_HINT_T0); - - q0 = xor256(q0, ap0); - q1 = xor256(q1, ap1); - _mm256_store_si256(&poly[i], q0); - _mm256_store_si256(&poly[i + 1], q1); - p0 = xor256(p0, q0); - p1 = xor256(p1, q1); - _mm256_store_si256(&poly[unit_2 + i], p0); - _mm256_store_si256(&poly[unit_2 + i + 1], p1); - } - return a; - } - - - //USED; - inline - __m128i butterfly_avx2_b4(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i += 4) { - __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]); - __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]); - __m256i p2 = _mm256_load_si256(&poly[unit_2 + i + 2]); - __m256i p3 = _mm256_load_si256(&poly[unit_2 + i + 3]); - cache_prefetch(&poly[i], _MM_HINT_T0); - cache_prefetch(&poly[i + 1], _MM_HINT_T0); - cache_prefetch(&poly[i + 2], _MM_HINT_T0); - cache_prefetch(&poly[i + 3], _MM_HINT_T0); - __m256i ap0 = _gf2ext128_mul_2x1_avx2(p0, a); - __m256i ap1 = _gf2ext128_mul_2x1_avx2(p1, a); - __m256i ap2 = _gf2ext128_mul_2x1_avx2(p2, a); - __m256i ap3 = _gf2ext128_mul_2x1_avx2(p3, a); - - __m256i q0 = _mm256_load_si256(&poly[i]); - __m256i q1 = _mm256_load_si256(&poly[i + 1]); - __m256i q2 = _mm256_load_si256(&poly[i + 2]); - __m256i q3 = _mm256_load_si256(&poly[i + 3]); - - cache_prefetch(&poly[unit_2 + i + 4], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 5], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 6], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 7], _MM_HINT_T0); - - q0 = xor256(q0, ap0); - q1 = xor256(q1, ap1); - q2 = xor256(q2, ap2); - q3 = xor256(q3, ap3); - _mm256_store_si256(&poly[i], q0); - _mm256_store_si256(&poly[i + 1], q1); - _mm256_store_si256(&poly[i + 2], q2); - _mm256_store_si256(&poly[i + 3], q3); - p0 = xor256(p0, q0); - p1 = xor256(p1, q1); - p2 = xor256(p2, q2); - p3 = xor256(p3, q3); - _mm256_store_si256(&poly[unit_2 + i], p0); - _mm256_store_si256(&poly[unit_2 + i + 1], p1); - _mm256_store_si256(&poly[unit_2 + i + 2], p2); - _mm256_store_si256(&poly[unit_2 + i + 3], p3); - } - return a; - } - - - - - inline - __m128i i_butterfly(__m128i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i++) { - poly[unit_2 + i] = xor128(poly[unit_2 + i], poly[i]); - cache_prefetch(&poly[i + 1], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0); - poly[i] = xor128(poly[i], _gf2ext128_mul_sse(poly[unit_2 + i], a)); - } - return a; - } - - - - inline - __m128i i_butterfly_avx2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i++) { - poly[unit_2 + i] = xor256(poly[unit_2 + i], poly[i]); - cache_prefetch(&poly[i + 1], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0); - poly[i] = xor256(poly[i], _gf2ext128_mul_2x1_avx2(poly[unit_2 + i], a)); - } - return a; - } - - inline - __m128i i_butterfly_avx2_b2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i += 2) { - __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]); - __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]); - - __m256i q0 = _mm256_load_si256(&poly[i]); - __m256i q1 = _mm256_load_si256(&poly[i + 1]); - - p0 = xor256(p0, q0); - p1 = xor256(p1, q1); - _mm256_store_si256(&poly[unit_2 + i], p0); - _mm256_store_si256(&poly[unit_2 + i + 1], p1); - cache_prefetch((const char*)& poly[i + 2], _MM_HINT_T0); - cache_prefetch((const char*)& poly[i + 3], _MM_HINT_T0); - cache_prefetch((const char*)& poly[unit_2 + i + 2], _MM_HINT_T0); - cache_prefetch((const char*)& poly[unit_2 + i + 3], _MM_HINT_T0); - - __m256i ap0 = _gf2ext128_mul_2x1_avx2(p0, a); - __m256i ap1 = _gf2ext128_mul_2x1_avx2(p1, a); - - q0 = xor256(q0, ap0); - q1 = xor256(q1, ap1); - _mm256_store_si256(&poly[i], q0); - _mm256_store_si256(&poly[i + 1], q1); - } - return a; - } - - - - //USED; - inline - __m128i i_butterfly_avx2_b4(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i += 4) { - __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]); - __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]); - __m256i p2 = _mm256_load_si256(&poly[unit_2 + i + 2]); - __m256i p3 = _mm256_load_si256(&poly[unit_2 + i + 3]); - - __m256i q0 = _mm256_load_si256(&poly[i]); - __m256i q1 = _mm256_load_si256(&poly[i + 1]); - __m256i q2 = _mm256_load_si256(&poly[i + 2]); - __m256i q3 = _mm256_load_si256(&poly[i + 3]); - - p0 = xor256(p0, q0); - p1 = xor256(p1, q1); - p2 = xor256(p2, q2); - p3 = xor256(p3, q3); - _mm256_store_si256(&poly[unit_2 + i], p0); - _mm256_store_si256(&poly[unit_2 + i + 1], p1); - _mm256_store_si256(&poly[unit_2 + i + 2], p2); - _mm256_store_si256(&poly[unit_2 + i + 3], p3); - cache_prefetch(&poly[i + 4], _MM_HINT_T0); - cache_prefetch(&poly[i + 5], _MM_HINT_T0); - cache_prefetch(&poly[i + 6], _MM_HINT_T0); - cache_prefetch(&poly[i + 7], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 4], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 5], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 6], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 7], _MM_HINT_T0); - - __m256i ap0 = _gf2ext128_mul_2x1_avx2(p0, a); - __m256i ap1 = _gf2ext128_mul_2x1_avx2(p1, a); - __m256i ap2 = _gf2ext128_mul_2x1_avx2(p2, a); - __m256i ap3 = _gf2ext128_mul_2x1_avx2(p3, a); - - q0 = xor256(q0, ap0); - q1 = xor256(q1, ap1); - q2 = xor256(q2, ap2); - q3 = xor256(q3, ap3); - _mm256_store_si256(&poly[i], q0); - _mm256_store_si256(&poly[i + 1], q1); - _mm256_store_si256(&poly[i + 2], q2); - _mm256_store_si256(&poly[i + 3], q3); - } - return a; - } - - - ////////////////////////////////////////////////////////////// - - - //USED; - inline - void __btfy(uint64_t* fx, u64 st_unit_size, u64 offset, u64 n_terms, u64 scalar_a) - { - - u64 i = st_unit_size; - - __m256i* poly256 = (__m256i*) & fx[0]; -#if 1 - for (; i > 3; i--) { - u64 unit = (1ull << (i - 1)); - u64 num = (n_terms >> 1) / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128(); - - u64 last_j = 0; - u64 st = (offset >> 1) / unit; - for (u64 j = st; j < st + num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = butterfly_avx2_b4(poly256 + j * unit, unit, diff_j << 1, extra_a); - } - } - for (; i > 2; i--) { - u64 unit = (1ull << (i - 1)); - u64 num = (n_terms >> 1) / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128(); - - u64 last_j = 0; - u64 st = (offset >> 1) / unit; - for (u64 j = st; j < st + num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = butterfly_avx2_b2(poly256 + j * unit, unit, diff_j << 1, extra_a); - } - } -#endif - for (; i > 1; i--) { - u64 unit = (1ull << (i - 1)); - u64 num = (n_terms >> 1) / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128(); - - u64 last_j = 0; - u64 st = (offset >> 1) / unit; - for (u64 j = st; j < st + num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = butterfly_avx2(poly256 + j * unit, unit, diff_j << 1, extra_a); - } - } - __m128i* poly128 = (__m128i*) & fx[0]; - if (i > 0) { - u64 unit = (1ull << i); - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128(); - - u64 last_j = 0; - u64 st = offset / unit; - for (u64 j = st; j < st + num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = butterfly(poly128 + j * unit, unit, diff_j << 1, extra_a); - } - } - } - - - inline - void __i_btfy(uint64_t* fx, u64 end_unit_size, u64 offset, u64 n_terms, u64 scalar_a) - { - u64 i = 1; - __m128i* poly128 = (__m128i*) & fx[0]; - for (; i < 2; i++) { - u64 unit = (1ull << i); - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128(); - - u64 last_j = 0; - u64 st = offset / unit; - for (u64 j = st; j < st + num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = i_butterfly(poly128 + j * unit, unit, diff_j << 1, extra_a); - } - } - - __m256i* poly256 = (__m256i*) & fx[0]; - for (; i < 3; i++) { - u64 unit = (1ull << (i - 1)); - u64 num = (n_terms >> 1) / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128(); - - u64 last_j = 0; - u64 st = (offset >> 1) / unit; - for (u64 j = st; j < st + num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = i_butterfly_avx2(poly256 + j * unit, unit, diff_j << 1, extra_a); - } - } - for (; i < 4; i++) { - u64 unit = (1ull << (i - 1)); - u64 num = (n_terms >> 1) / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128(); - - u64 last_j = 0; - u64 st = (offset >> 1) / unit; - for (u64 j = st; j < st + num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = i_butterfly_avx2_b2(poly256 + j * unit, unit, diff_j << 1, extra_a); - } - } - - for (; i <= end_unit_size; i++) { - u64 unit = (1ull << (i - 1)); - u64 num = (n_terms >> 1) / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128(); - - u64 last_j = 0; - u64 st = (offset >> 1) / unit; - for (u64 j = st; j < st + num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = i_butterfly_avx2_b4(poly256 + j * unit, unit, diff_j << 1, extra_a); - } - } - - } - - - - - - - ///////////////////////////////////////////////////// - // - // Public functions. - // - ///////////////////////////////////////////////////// - - - - -#define _LOG_CACHE_SIZE_ 14 - - - //USED; - void btfy_128(uint64_t * fx, u64 n_fx, u64 scalar_a) - { - - if (1 >= n_fx) return; - - u64 log_n = __builtin_ctzll(n_fx); - u64 n_terms = n_fx; - - u64 i = log_n; - - __m256i* poly256 = (__m256i*) & fx[0]; - for (; i > _LOG_CACHE_SIZE_; i--) { - u64 unit = (1ull << (i - 1)); - u64 num = (n_terms >> 1) / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = butterfly_avx2_b4(poly256 + j * unit, unit, diff_j << 1, extra_a); - } - } - //// i == 15 or less - u64 unit = (1ull << i); - u64 num = n_terms / unit; - for (u64 j = 0; j < num; j++) { - __btfy(fx, i, j * unit, unit, scalar_a); - } - } - - - - //USED; - void i_btfy_128(uint64_t* fx, u64 n_fx, u64 scalar_a) - { - if (1 >= n_fx) return; - - u64 log_n = __builtin_ctzll(n_fx); - - u64 n_terms = n_fx; - - { - u64 unit = ((1ull << _LOG_CACHE_SIZE_) > n_fx) ? n_fx : (1ull << _LOG_CACHE_SIZE_); - u64 num = n_terms / unit; - for (u64 j = 0; j < num; j++) { __i_btfy(fx, _LOG_CACHE_SIZE_, j * unit, unit, scalar_a); }; - } - __m256i* poly256 = (__m256i*) & fx[0]; - for (u64 i = _LOG_CACHE_SIZE_ + 1; i <= log_n; i++) { - u64 unit = (1ull << (i - 1)); - u64 num = (n_terms >> 1) / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = i_butterfly_avx2_b4(poly256 + j * unit, unit, diff_j << 1, extra_a); - } - } - - } - - - - - - ///////////////////////////////////////////////////////////// - - - - inline - __m128i gf264_isomorphism_single_bit(u64 ith_bit) - { - return _mm_load_si128((__m128i*) (&gfCantorto264[ith_bit << 1])); - } - - inline - __m128i gf264_isomorphism(uint64_t a_in_cantor) - { - alignas(32) uint8_t a_iso[16]; - bitmatrix_prod_64x128_8R_sse(a_iso, gfCantorto264_8R, a_in_cantor); - return _mm_load_si128((__m128i*) a_iso); - } - - //////////////////////////////// - - inline - __m128i butterfly_64_xmm(__m128i d, __m128i a) - { - __m128i r0 = xor128(d, _gf2ext64_mul_hi_sse(d, a)); - __m128i r1 = xor128(r0, _mm_slli_si128(r0, 8)); - return r1; - } - - inline - __m128i i_butterfly_64_xmm(__m128i d, __m128i a) - { - __m128i r0 = xor128(d, _mm_slli_si128(d, 8)); - __m128i r1 = xor128(r0, _gf2ext64_mul_hi_sse(r0, a)); - return r1; - } - - inline - __m128i butterfly_64_u2(__m128i* poly, u64 ska, __m128i extra_a) /// unit = 2>>1 - { - __m128i a = extra_a; - a = xor128(a, gf264_isomorphism(ska)); - poly[0] = butterfly_64_xmm(poly[0], a); - cache_prefetch(&poly[1], _MM_HINT_T0); - return a; - } - - inline - __m128i i_butterfly_64_u2(__m128i* poly, u64 ska, __m128i extra_a) /// unit = 2>>1 - { - __m128i a = extra_a; - a = xor128(a, gf264_isomorphism(ska)); - poly[0] = i_butterfly_64_xmm(poly[0], a); - cache_prefetch(&poly[1], _MM_HINT_T0); - return a; - } - - //////////////////////////// - - - inline - __m256i butterfly_64_ymm(__m256i d, __m128i a) - { - __m128i d0 = _mm256_castsi256_si128(d); - __m128i d1 = _mm256_extracti128_si256(d, 1); - d0 = xor128(d0, _gf2ext64_mul_2x1_sse(d1, a)); - d1 = xor128(d1, d0); - __m256i r0 = _mm256_castsi128_si256(d0); - __m256i r1 = _mm256_inserti128_si256(r0, d1, 1); - return r1; - } - - inline - __m256i i_butterfly_64_ymm(__m256i d, __m128i a) - { - __m128i d0 = _mm256_castsi256_si128(d); - __m128i d1 = _mm256_extracti128_si256(d, 1); - d1 = xor128(d1, d0); - d0 = xor128(d0, _gf2ext64_mul_2x1_sse(d1, a)); - __m256i r0 = _mm256_castsi128_si256(d0); - __m256i r1 = _mm256_inserti128_si256(r0, d1, 1); - return r1; - } - - inline - __m128i butterfly_64_u4(__m256i* poly, u64 ska, __m128i extra_a) /// unit = 4>>2 - { - __m128i a = extra_a; - a = xor128(a, gf264_isomorphism(ska)); - poly[0] = butterfly_64_ymm(poly[0], a); - cache_prefetch(&poly[1], _MM_HINT_T0); - return a; - } - - inline - __m128i i_butterfly_64_u4(__m256i* poly, u64 ska, __m128i extra_a) /// unit = 4>>2 - { - __m128i a = extra_a; - a = xor128(a, gf264_isomorphism(ska)); - poly[0] = i_butterfly_64_ymm(poly[0], a); - cache_prefetch(&poly[1], _MM_HINT_T0); - return a; - } - - - ////////////////////////////////////////////////// - - - inline - __m128i butterfly_64_avx2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) /// unit >= 8>>2 - { - __m128i a = extra_a; - a = xor128(a, gf264_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i++) { - poly[i] = xor256(poly[i], _gf2ext64_mul_4x1_avx2(poly[unit_2 + i], a)); - cache_prefetch(&poly[i + 1], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0); - poly[unit_2 + i] = xor256(poly[unit_2 + i], poly[i]); - } - return a; - } - - - inline - __m128i butterfly_64_avx2_b2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf264_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i += 2) { - __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]); - __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]); - cache_prefetch(&poly[i], _MM_HINT_T0); - cache_prefetch(&poly[i + 1], _MM_HINT_T0); - __m256i ap0 = _gf2ext64_mul_4x1_avx2(p0, a); - __m256i ap1 = _gf2ext64_mul_4x1_avx2(p1, a); - - __m256i q0 = _mm256_load_si256(&poly[i]); - __m256i q1 = _mm256_load_si256(&poly[i + 1]); - - cache_prefetch(&poly[unit_2 + i + 2], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 3], _MM_HINT_T0); - - q0 = xor256(q0, ap0); - q1 = xor256(q1, ap1); - _mm256_store_si256(&poly[i], q0); - _mm256_store_si256(&poly[i + 1], q1); - p0 = xor256(p0, q0); - p1 = xor256(p1, q1); - _mm256_store_si256(&poly[unit_2 + i], p0); - _mm256_store_si256(&poly[unit_2 + i + 1], p1); - } - return a; - } - - - inline - __m128i butterfly_64_avx2_b4(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf264_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i += 4) { - __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]); - __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]); - __m256i p2 = _mm256_load_si256(&poly[unit_2 + i + 2]); - __m256i p3 = _mm256_load_si256(&poly[unit_2 + i + 3]); - cache_prefetch(&poly[i], _MM_HINT_T0); - cache_prefetch(&poly[i + 1], _MM_HINT_T0); - cache_prefetch(&poly[i + 2], _MM_HINT_T0); - cache_prefetch(&poly[i + 3], _MM_HINT_T0); - __m256i ap0 = _gf2ext64_mul_4x1_avx2(p0, a); - __m256i ap1 = _gf2ext64_mul_4x1_avx2(p1, a); - __m256i ap2 = _gf2ext64_mul_4x1_avx2(p2, a); - __m256i ap3 = _gf2ext64_mul_4x1_avx2(p3, a); - - __m256i q0 = _mm256_load_si256(&poly[i]); - __m256i q1 = _mm256_load_si256(&poly[i + 1]); - __m256i q2 = _mm256_load_si256(&poly[i + 2]); - __m256i q3 = _mm256_load_si256(&poly[i + 3]); - - cache_prefetch(&poly[unit_2 + i + 4], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 5], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 6], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 7], _MM_HINT_T0); - - q0 = xor256(q0, ap0); - q1 = xor256(q1, ap1); - q2 = xor256(q2, ap2); - q3 = xor256(q3, ap3); - _mm256_store_si256(&poly[i], q0); - _mm256_store_si256(&poly[i + 1], q1); - _mm256_store_si256(&poly[i + 2], q2); - _mm256_store_si256(&poly[i + 3], q3); - p0 = xor256(p0, q0); - p1 = xor256(p1, q1); - p2 = xor256(p2, q2); - p3 = xor256(p3, q3); - _mm256_store_si256(&poly[unit_2 + i], p0); - _mm256_store_si256(&poly[unit_2 + i + 1], p1); - _mm256_store_si256(&poly[unit_2 + i + 2], p2); - _mm256_store_si256(&poly[unit_2 + i + 3], p3); - } - return a; - } - - - - - - inline - __m128i i_butterfly_64_avx2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf264_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i++) { - poly[unit_2 + i] = xor256(poly[unit_2 + i], poly[i]); - cache_prefetch(&poly[i + 1], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0); - poly[i] = xor256(poly[i], _gf2ext64_mul_4x1_avx2(poly[unit_2 + i], a)); - } - return a; - } - - - inline - __m128i i_butterfly_64_avx2_b2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf264_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i += 2) { - __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]); - __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]); - - __m256i q0 = _mm256_load_si256(&poly[i]); - __m256i q1 = _mm256_load_si256(&poly[i + 1]); - - p0 = xor256(p0, q0); - p1 = xor256(p1, q1); - _mm256_store_si256(&poly[unit_2 + i], p0); - _mm256_store_si256(&poly[unit_2 + i + 1], p1); - cache_prefetch(&poly[i + 2], _MM_HINT_T0); - cache_prefetch(&poly[i + 3], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 2], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 3], _MM_HINT_T0); - - __m256i ap0 = _gf2ext64_mul_4x1_avx2(p0, a); - __m256i ap1 = _gf2ext64_mul_4x1_avx2(p1, a); - - q0 = xor256(q0, ap0); - q1 = xor256(q1, ap1); - _mm256_store_si256(&poly[i], q0); - _mm256_store_si256(&poly[i + 1], q1); - } - return a; - } - - - - inline - __m128i i_butterfly_64_avx2_b4(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) - { - __m128i a = extra_a; - a = xor128(a, gf264_isomorphism(ska)); - - u64 unit_2 = unit / 2; - for (u64 i = 0; i < unit_2; i += 4) { - __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]); - __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]); - __m256i p2 = _mm256_load_si256(&poly[unit_2 + i + 2]); - __m256i p3 = _mm256_load_si256(&poly[unit_2 + i + 3]); - - __m256i q0 = _mm256_load_si256(&poly[i]); - __m256i q1 = _mm256_load_si256(&poly[i + 1]); - __m256i q2 = _mm256_load_si256(&poly[i + 2]); - __m256i q3 = _mm256_load_si256(&poly[i + 3]); - - p0 = xor256(p0, q0); - p1 = xor256(p1, q1); - p2 = xor256(p2, q2); - p3 = xor256(p3, q3); - _mm256_store_si256(&poly[unit_2 + i], p0); - _mm256_store_si256(&poly[unit_2 + i + 1], p1); - _mm256_store_si256(&poly[unit_2 + i + 2], p2); - _mm256_store_si256(&poly[unit_2 + i + 3], p3); - cache_prefetch(&poly[i + 4], _MM_HINT_T0); - cache_prefetch(&poly[i + 5], _MM_HINT_T0); - cache_prefetch(&poly[i + 6], _MM_HINT_T0); - cache_prefetch(&poly[i + 7], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 4], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 5], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 6], _MM_HINT_T0); - cache_prefetch(&poly[unit_2 + i + 7], _MM_HINT_T0); - - __m256i ap0 = _gf2ext64_mul_4x1_avx2(p0, a); - __m256i ap1 = _gf2ext64_mul_4x1_avx2(p1, a); - __m256i ap2 = _gf2ext64_mul_4x1_avx2(p2, a); - __m256i ap3 = _gf2ext64_mul_4x1_avx2(p3, a); - - q0 = xor256(q0, ap0); - q1 = xor256(q1, ap1); - q2 = xor256(q2, ap2); - q3 = xor256(q3, ap3); - _mm256_store_si256(&poly[i], q0); - _mm256_store_si256(&poly[i + 1], q1); - _mm256_store_si256(&poly[i + 2], q2); - _mm256_store_si256(&poly[i + 3], q3); - } - return a; - } - - - - ///////////////////////////////////////////// - - - - void btfy_64(uint64_t* fx, u64 n_fx, u64 scalar_a) - { - - if (1 >= n_fx) return; - - u64 log_n = __builtin_ctzll(n_fx); - u64 n_terms = n_fx; - - u64 i = log_n; - - uint64_t* poly = fx; - for (; i > 4; i--) { - u64 unit = (1ull << i); /// u >= 8 - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = butterfly_64_avx2_b4((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a); - } - } - for (; i > 3; i--) { - u64 unit = (1ull << i); /// u >= 8 - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = butterfly_64_avx2_b2((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a); - } - } - for (; i > 2; i--) { - u64 unit = (1ull << i); /// u >= 8 - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = butterfly_64_avx2((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a); - } - } - for (; i > 1; i--) { - u64 unit = (1ull << i); /// u = 4 - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = butterfly_64_u4((__m256i*)(poly + j * unit), diff_j << 1, extra_a); - } - } - for (; i > 0; i--) { - u64 unit = (1ull << i); /// u = 2 - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = butterfly_64_u2((__m128i*)(poly + j * unit), diff_j << 1, extra_a); - } - } - } - - void i_btfy_64(uint64_t* fx, u64 n_fx, u64 scalar_a) - { - if (1 >= n_fx) return; - - u64 log_n = __builtin_ctzll(n_fx); - u64 n_terms = n_fx; - - uint64_t* poly = fx; - u64 i = 1; - for (; i < 2; i++) { - u64 unit = (1ull << i); /// u = 2 - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = i_butterfly_64_u2((__m128i*)(poly + j * unit), diff_j << 1, extra_a); - } - } - for (; i < 3; i++) { - u64 unit = (1ull << i); /// u = 4 - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = i_butterfly_64_u4((__m256i*)(poly + j * unit), diff_j << 1, extra_a); - } - } - for (; i < 4; i++) { - u64 unit = (1ull << i); /// u >= 8 - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = i_butterfly_64_avx2((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a); - } - } - for (; i < 5; i++) { - u64 unit = (1ull << i); /// u >= 8 - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = i_butterfly_64_avx2_b2((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a); - } - } - for (; i <= log_n; i++) { - u64 unit = (1ull << i); /// u >= 8 - u64 num = n_terms / unit; - - u64 k = i - 1; - __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128(); - - u64 last_j = 0; - for (u64 j = 0; j < num; j++) { - u64 diff_j = j ^ last_j; - last_j = j; - extra_a = i_butterfly_64_avx2_b4((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a); - } - } - } -} -#endif \ No newline at end of file diff --git a/libOTe/Tools/bitpolymul/btfy.h b/libOTe/Tools/bitpolymul/btfy.h deleted file mode 100644 index 16829f21..00000000 --- a/libOTe/Tools/bitpolymul/btfy.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - -#include - -#include "bpmDefines.h" - -namespace bpm { - - void btfy_128(uint64_t* fx, u64 n_fx, u64 scalar_a); - - void i_btfy_128(uint64_t* fx, u64 n_fx, u64 scalar_a); - - - void btfy_64(uint64_t* fx, u64 n_fx, u64 scalar_a); - - void i_btfy_64(uint64_t* fx, u64 n_fx, u64 scalar_a); -} - - - - -#endif diff --git a/libOTe/Tools/bitpolymul/encode.cpp b/libOTe/Tools/bitpolymul/encode.cpp deleted file mode 100644 index 61784919..00000000 --- a/libOTe/Tools/bitpolymul/encode.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - - -#include - -#include "gfext_aesni.h" - -#include "bitmat_prod.h" - -#include "string.h" - - - - - -///////////////////////////////////////////////// -/// -/// truncated FFT, 7 layers -/// -////////////////////////////////////////////////////// - -#include "trunc_btfy_tab.h" -#include "trunc_btfy_tab_64.h" - -#include "transpose.h" - -namespace bpm { - - //USED; - inline - void bit_bc_64x2_div(__m256i* x) - { - for (u64 i = 0; i < 64; i++) x[64 + i] = _mm256_srli_si256(x[i], 8); - for (int i = 64 - 1; i >= 0; i--) { - x[1 + i] = xor256(x[1 + i], x[64 + i]); - x[4 + i] = xor256(x[4 + i], x[64 + i]); - x[16 + i] = xor256(x[16 + i], x[64 + i]); - } - for (u64 i = 0; i < 64; i++) x[i] = _mm256_unpacklo_epi64(x[i], x[64 + i]); - - for (u64 i = 0; i < 64; i += 64) { - __m256i* pi = x + i; - for (int j = 32 - 1; j >= 0; j--) { - pi[1 + j] = xor256(pi[1 + j], pi[32 + j]); - pi[2 + j] = xor256(pi[2 + j], pi[32 + j]); - pi[16 + j] = xor256(pi[16 + j], pi[32 + j]); - } - } - for (u64 i = 0; i < 64; i += 32) { - __m256i* pi = x + i; - for (int j = 16 - 1; j >= 0; j--) { - pi[1 + j] = xor256(pi[1 + j], pi[16 + j]); - } - } - for (u64 i = 0; i < 64; i += 16) { - __m256i* pi = x + i; - for (int j = 8 - 1; j >= 0; j--) { - pi[1 + j] = xor256(pi[1 + j], pi[8 + j]); - pi[2 + j] = xor256(pi[2 + j], pi[8 + j]); - pi[4 + j] = xor256(pi[4 + j], pi[8 + j]); - } - } - for (u64 i = 0; i < 64; i += 8) { - __m256i* pi = x + i; - pi[4] = xor256(pi[4], pi[7]); - pi[3] = xor256(pi[3], pi[6]); - pi[2] = xor256(pi[2], pi[5]); - pi[1] = xor256(pi[1], pi[4]); - } - - for (u64 i = 0; i < 64; i += 4) { - __m256i* pi = x + i; - pi[2] = xor256(pi[2], pi[3]); - pi[1] = xor256(pi[1], pi[2]); - } - - } - - - - //USED; - void encode_128_half_input_zero(uint64_t* rfx, const uint64_t* fx, u64 n_fx_128b) - { - if (128 * 2 > n_fx_128b) { printf("unsupported number of terms.\n"); exit(-1); } - - __m256i temp[128]; - __m128i* temp128 = (__m128i*) temp; - uint64_t* temp64 = (uint64_t*)temp; - const __m256i* fx_256 = (const __m256i*) fx; - __m128i* rfx_128 = (__m128i*) rfx; - u64 n_fx_256b = n_fx_128b / 2; - u64 num = n_fx_256b / 128; - __m256i t2[128]; - __m128i* t2_128 = (__m128i*) t2; - - for (u64 i = 0; i < num; i++) { - for (u64 j = 0; j < 64; j++) { - temp[j] = fx_256[i + j * num]; - temp[j] = div_s7(temp[j]); - } - - tr_bit_64x64_b4_avx2((uint8_t*)(temp128), (const uint8_t*)temp); - bit_bc_64x2_div(temp); - // truncated FFT - for (u64 j = 0; j < 8; j++) { - bitmatrix_prod_64x128_4R_b32_opt_avx2((uint8_t*)(&t2_128[32 * j]), beta_mul_64_bm4r_ext_8, (const uint8_t*)(&temp64[32 * j])); - } - for (u64 k = 0; k < 8; k++) for (u64 j = 0; j < 8; j++) rfx_128[i * 256 + k * 8 + j] = t2_128[k * 32 + j * 2]; - for (u64 k = 0; k < 8; k++) for (u64 j = 0; j < 8; j++) rfx_128[i * 256 + 64 + k * 8 + j] = t2_128[k * 32 + 16 + j * 2]; - for (u64 k = 0; k < 8; k++) for (u64 j = 0; j < 8; j++) rfx_128[i * 256 + 128 + k * 8 + j] = t2_128[k * 32 + j * 2 + 1]; - for (u64 k = 0; k < 8; k++) for (u64 j = 0; j < 8; j++) rfx_128[i * 256 + 128 + 64 + k * 8 + j] = t2_128[k * 32 + 16 + j * 2 + 1]; - } - } - - //USED; - inline - void bit_bc_exp(__m256i* x) - { - for (u64 i = 0; i < 128; i += 4) { - __m256i* pi = x + i; - pi[1] = xor256(pi[1], pi[2]); - pi[2] = xor256(pi[2], pi[3]); - } - for (u64 i = 0; i < 128; i += 8) { - __m256i* pi = x + i; - pi[1] = xor256(pi[1], pi[4]); - pi[2] = xor256(pi[2], pi[5]); - pi[3] = xor256(pi[3], pi[6]); - pi[4] = xor256(pi[4], pi[7]); - } - for (u64 i = 0; i < 128; i += 16) { - __m256i* pi = x + i; - for (u64 j = 0; j < 8; j++) { - pi[1 + j] = xor256(pi[1 + j], pi[8 + j]); - pi[2 + j] = xor256(pi[2 + j], pi[8 + j]); - pi[4 + j] = xor256(pi[4 + j], pi[8 + j]); - } - } - for (u64 i = 0; i < 128; i += 32) { - __m256i* pi = x + i; - for (u64 j = 0; j < 16; j++) { - pi[1 + j] = xor256(pi[1 + j], pi[16 + j]); - } - } - for (u64 i = 0; i < 128; i += 64) { - __m256i* pi = x + i; - for (u64 j = 0; j < 32; j++) { - pi[1 + j] = xor256(pi[1 + j], pi[32 + j]); - pi[2 + j] = xor256(pi[2 + j], pi[32 + j]); - pi[16 + j] = xor256(pi[16 + j], pi[32 + j]); - } - } - for (u64 i = 0; i < 64; i++) { - x[1 + i] = xor256(x[1 + i], x[64 + i]); - x[4 + i] = xor256(x[4 + i], x[64 + i]); - x[16 + i] = xor256(x[16 + i], x[64 + i]); - } - } - - - void decode_128(uint64_t* rfx, const uint64_t* fx, u64 n_fx_128b) - { - if (128 * 2 > n_fx_128b) { printf("unsupported number of terms.\n"); exit(-1); } - - const __m128i* fx_128 = (__m128i*) fx; - __m256i* rfx_256 = (__m256i*) rfx; - if (uint64_t(rfx_256) % 32) - { - std::cout << "Error (Bitpolymul) pointer need to be 32 bit aligned. " LOCATION << std::endl; - throw RTE_LOC; - } - - u64 n_fx_256b = n_fx_128b / 2; - u64 num = n_fx_256b / 128; - __m256i temp[128]; - __m128i* temp128 = (__m128i*) temp; - - for (u64 i = 0; i < num; i++) { - /// truncated iFFT here. - for (u64 j = 0; j < 128; j++) { - temp128[j * 2] = fx_128[i * 256 + j]; - temp128[j * 2 + 1] = fx_128[i * 256 + 128 + j]; - } - - for (u64 j = 0; j < 8; j++) { - bitmatrix_prod_128x128_4R_b32_opt_avx2((uint8_t*)(temp + 16 * j), i_beta_mul_64_bm4r_ext_8, (const uint8_t*)(temp + 16 * j)); - } - - bit_bc_exp(temp); - - tr_bit_128x128_b2_avx2((uint8_t*)temp, (const uint8_t*)temp128); - - for (u64 j = 0; j < 128; j++) { - temp[j] = exp_s7(temp[j]); - rfx_256[i + j * num] = temp[j]; - } - } - } - -// -// -// /////////////////////////////////////// -// -// - - - inline - void bit_bc_64x2_exp(__m256i* x) - { - for (u64 i = 0; i < 64; i += 4) { - __m256i* pi = x + i; - pi[1] = xor256(pi[1], pi[2]); - pi[2] = xor256(pi[2], pi[3]); - } - for (u64 i = 0; i < 64; i += 8) { - __m256i* pi = x + i; - pi[1] = xor256(pi[1], pi[4]); - pi[2] = xor256(pi[2], pi[5]); - pi[3] = xor256(pi[3], pi[6]); - pi[4] = xor256(pi[4], pi[7]); - } - for (u64 i = 0; i < 64; i += 16) { - __m256i* pi = x + i; - for (u64 j = 0; j < 8; j++) { - pi[1 + j] = xor256(pi[1 + j], pi[8 + j]); - pi[2 + j] = xor256(pi[2 + j], pi[8 + j]); - pi[4 + j] = xor256(pi[4 + j], pi[8 + j]); - } - } - for (u64 i = 0; i < 64; i += 32) { - __m256i* pi = x + i; - for (u64 j = 0; j < 16; j++) { - pi[1 + j] = xor256(pi[1 + j], pi[16 + j]); - } - } - for (u64 i = 0; i < 64; i += 64) { - __m256i* pi = x + i; - for (u64 j = 0; j < 32; j++) { - pi[1 + j] = xor256(pi[1 + j], pi[32 + j]); - pi[2 + j] = xor256(pi[2 + j], pi[32 + j]); - pi[16 + j] = xor256(pi[16 + j], pi[32 + j]); - } - } - - for (u64 i = 0; i < 64; i++) x[64 + i] = _mm256_srli_si256(x[i], 8); - for (u64 i = 0; i < 64; i++) { - x[1 + i] = xor256(x[1 + i], x[64 + i]); - x[4 + i] = xor256(x[4 + i], x[64 + i]); - x[16 + i] = xor256(x[16 + i], x[64 + i]); - } - for (u64 i = 0; i < 64; i++) x[i] = _mm256_unpacklo_epi64(x[i], x[64 + i]); - - } - - - - - - - void encode_64_half_input_zero(uint64_t* rfx, const uint64_t* fx, u64 n_fx) /// XXX: further optimization. - { - if (64 * 4 > n_fx) { printf("unsupported number of terms.\n"); exit(-1); } - - __m256i temp[128]; - uint64_t* temp64 = (uint64_t*)temp; - const __m256i* fx_256 = (const __m256i*) fx; - u64 n_fx_256b = n_fx >> 2; - u64 num = n_fx_256b / 64; - - for (u64 i = 0; i < num; i++) { - for (u64 j = 0; j < 32; j++) { - temp[j] = fx_256[i + j * num]; - temp[j] = div_s7(temp[j]); - } - for (u64 j = 32; j < 64; j++) temp[j] = _mm256_setzero_si256(); - - tr_bit_64x64_b4_avx2((uint8_t*)(temp), (const uint8_t*)temp); - - bit_bc_64x2_div(temp); - - // truncated FFT - //for(u64 j=0;j<256;j++) temp64[j] = bitmatrix_prod_64x64_M4R( beta_mul_32_m4r , temp64[j] ); -#if 0 - for (u64 j = 0; j < (64 * 4 / 32); j++) bitmatrix_prod_64x64_h32zero_4R_b32_avx2((uint8_t*)(&temp64[32 * j]), beta_mul_32_bm4r, (uint8_t*)(&temp64[32 * j])); -#else - for (u64 j = 0; j < (64 * 4 / 64); j++) bitmatrix_prod_64x64_h32zero_4R_b64_avx2((uint8_t*)(&temp64[64 * j]), beta_mul_32_bm4r, (uint8_t*)(&temp64[64 * j])); -#endif - - for (u64 j = 0; j < 64; j++) rfx[i * 256 + j] = temp64[j * 4]; - for (u64 j = 0; j < 64; j++) rfx[i * 256 + 64 + j] = temp64[j * 4 + 1]; - for (u64 j = 0; j < 64; j++) rfx[i * 256 + 128 + j] = temp64[j * 4 + 2]; - for (u64 j = 0; j < 64; j++) rfx[i * 256 + 192 + j] = temp64[j * 4 + 3]; - - } - } - - - void decode_64(uint64_t* rfx, const uint64_t* fx, u64 n_fx) - { - if (64 * 4 > n_fx) { printf("unsupported number of terms.\n"); exit(-1); } - - __m256i temp[128]; - uint64_t* temp64 = (uint64_t*)temp; - - __m256i* rfx_256 = (__m256i*) rfx; - u64 n_fx_256b = n_fx >> 2; - u64 num = n_fx_256b / 64; - - for (u64 i = 0; i < num; i++) { - /// truncated iFFT here. - for (u64 j = 0; j < 64; j++) { - temp64[j * 4] = fx[i * 256 + j]; - temp64[j * 4 + 1] = fx[i * 256 + 64 + j]; - temp64[j * 4 + 2] = fx[i * 256 + 128 + j]; - temp64[j * 4 + 3] = fx[i * 256 + 192 + j]; - } - // truncated iFFT - for (u64 j = 0; j < (64 * 4 / 64); j++) bitmatrix_prod_64x64_4R_b64_avx2((uint8_t*)(&temp64[64 * j]), i_beta_mul_32_bm4r, (uint8_t*)(&temp64[64 * j])); - bit_bc_64x2_exp(temp); - - tr_bit_64x64_b4_avx2((uint8_t*)(temp), (const uint8_t*)temp); - - for (u64 j = 0; j < 64; j++) { - temp[j] = exp_s7(temp[j]); - - _mm256_store_si256(&rfx_256[i + j * num], temp[j]); - } - } - } -} -#endif - diff --git a/libOTe/Tools/bitpolymul/encode.h b/libOTe/Tools/bitpolymul/encode.h deleted file mode 100644 index 2872daa8..00000000 --- a/libOTe/Tools/bitpolymul/encode.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - - -#include - -#include "bpmDefines.h" - - -namespace bpm { - - - void encode_128_half_input_zero(uint64_t* rfx, const uint64_t* fx, u64 n_fx_128b); - - void decode_128(uint64_t* rfx, const uint64_t* fx, u64 n_fx_128b); - - void encode_64_half_input_zero(uint64_t* rfx, const uint64_t* fx, u64 n_fx); - - void decode_64(uint64_t* rfx, const uint64_t* fx, u64 n_fx); - - -} - - - -#endif diff --git a/libOTe/Tools/bitpolymul/gf2128_cantor_iso.h b/libOTe/Tools/bitpolymul/gf2128_cantor_iso.h deleted file mode 100644 index 4ec780fc..00000000 --- a/libOTe/Tools/bitpolymul/gf2128_cantor_iso.h +++ /dev/null @@ -1,2351 +0,0 @@ -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - -#include "stdint.h" -#include "bpmDefines.h" -namespace bpm{ -alignas(32) const uint64_t gf2128toCantor[2*128] = { - 0x1, 0x0, - 0xF62DA500563A6180, 0x4E8FB76FADDE40EA, - 0x8D3B77807D275140, 0x69C86CD87B31609F, - 0x49EA0BE5A4B1D580, 0x45EA054D27F72703, - 0x4BA6CC4043B4F9E0, 0x5D2C5AB446A9D0D0, - 0xF4C6A222652D980, 0x6DFCF2E44CA64DDD, - 0xED1F0E1776E93F40, 0x671F07EBB40CB482, - 0x938422464F555D80, 0x53C60B27554DCB46, - 0x6E75AA60626E8510, 0x73BA77EE65FD38B8, - 0x5176A0B45A20DD80, 0x79AB26E5F2005EB2, - 0x88EA5F33357BB540, 0x5B028B966AF56B33, - 0xEBAA5B08988BAB80, 0xFBB35DBFEACA77C, - 0x9B90891CCD9DA0E0, 0x5490841E6E0AEEC3, - 0x71E8F62AD6538480, 0x10FF7AE9FD162518, - 0xDA46336568FFF340, 0x7A250EB4FFEB2EE5, - 0x73070BB8FBFBAE80, 0x51F6B50B77FB18D, - 0x594F7F505359C798, 0x4A674C195703A4E4, - 0xAC5CBADDD0A35780, 0x7993D46D3C8420E0, - 0x79CDF0EE7730B340, 0x457EB5970B0071EB, - 0x2F29A7F7044EF00, 0x1CA1EA3434B30DF4, - 0x4C9F70AAAFC66FE0, 0x7683CE5D5F8FDEAA, - 0xF7FF15EC6E75A480, 0x68383CB9786AF78A, - 0x9E7F768CD4CE7E40, 0x866AF3601FAF4C2, - 0xF8BFFFDCEB48F300, 0x8BBB968CDA7AEB6, - 0x5658CD92AB537090, 0x7ED8C611590F99A2, - 0x97F31AC8BFCF79C0, 0x41A564EF69F0061B, - 0x491C8D3FBD7A46C0, 0x1880C79D039D3794, - 0x5320998DC8436EE0, 0x2AD36EC06C212493, - 0x37652AD7DC800AE0, 0x473789EE801EB997, - 0xCDE57AFDED182E80, 0x599CBAF635479BBF, - 0xCA848E64860679C0, 0x790DEF8ECC0694B, - 0xBDE78F553997130, 0x31B03D86963281E0, - 0x75E8C0F87AF52454, 0x6F54EA15FC827696, - 0x57B33C64A3509080, 0x4AC5E2D5008CA73C, - 0xFA72E7B338F2FC40, 0x455A3E5BA2C63090, - 0xC25A47DAA93BCA80, 0x28DC1D391FAF20F7, - 0xC52B08994CA8EAE0, 0x67C1EF5C8E80491E, - 0x38335D064E98E300, 0x300D6942F7CD9EC1, - 0x38BD740C8669880, 0x12F11F2E2EEA8B0E, - 0x684DE1EFE77B4680, 0x3E7995B45292DCBA, - 0x6AD0C8FFF8255810, 0x4DC22973F04831FF, - 0x588C3C0E52306980, 0x229EF6C52FB0F783, - 0x8C009F1A594F76C0, 0x5C2422E5C45F8C4F, - 0x703CB1D20CEAE280, 0x6F04D24433FB96B2, - 0xD140CDCABEA94160, 0xC55F8AD01078EA3, - 0x3CD36E9A93B35C40, 0x6192262CAD674B9A, - 0x84E000329EEC8A80, 0xCE665DCAB7479ED, - 0xD15CD3373C46EC20, 0x7855D70FAEEF256F, - 0x7D74AB5BFEFAC8D8, 0x41B4A519F5885573, - 0xEED73249B9735400, 0x3F530821D3B2A371, - 0x5C0A97ACE028C520, 0x6177D698DD080516, - 0x85403EC43C26CD80, 0x15E45D883811CFCA, - 0x6D92CBA063C765A0, 0x14C0A4538253AC5E, - 0xBE016081553C8480, 0x705D0E8E57E8B405, - 0xFAB0D54B2C62D990, 0x3FBAD9A05A31B6DA, - 0xEAB9F006B6A248C0, 0x10D0FD26BA749E1F, - 0xACD7BFBC32C00F90, 0x64AC4D19C011E55C, - 0x22E05BA415139BC0, 0x1BEC30C48396C0BC, - 0x2B17C7831B9439C0, 0x7552E78D2FE45660, - 0x9AC4CB562DC6B3E0, 0x22D1DCDA09B437FD, - 0x2FC6C956C5054520, 0x458B1849AA05DEE, - 0x4507CA313AF999C0, 0x2E67CE80AC133372, - 0xE31448FFA55C9A8, 0x29682345DD2BC110, - 0x40F823A5051005B0, 0x5CD66FBEDCA1416, - 0x4F1CA084478FB67E, 0x58FE9F1F02C34DDD, - 0x9401E0E17FFCC0C0, 0xF39E6874FB57154, - 0x7C6AA256F2F8D8C0, 0x6FA713BF80CAF4A2, - 0x41FBA012F6FE4260, 0x6517FE8DAECC43B8, - 0x874B946AA48B8260, 0x67F7217673A528D8, - 0x67082553208B4EC0, 0x512CB42B7B65FC48, - 0x23776437FDA62FC0, 0x3CB213A59078B08C, - 0x55E63BECBCFD490, 0x69B9E67845568804, - 0xA7BE8CD5EAFC9F90, 0x542118F2C9C06D91, - 0x3F9DFF5DE5A98C40, 0x4B5159E1F17738CB, - 0xA42AF38569D49280, 0x280BDDE38C2B51A1, - 0x56562BD5AE896260, 0x3AEE4CD13FE66FB1, - 0x24E3CE0AC55D4C0, 0x1B8990B9399FCE89, - 0x534C03FE0CB12380, 0x2AC17C44B5CBF6C8, - 0x5C6B111814C6E5C0, 0x21455F6E7BDBB2E7, - 0xF701B24ABEA37538, 0x4E51BFCE5ED600A8, - 0xDFB8AC800437F418, 0x6B233DCA086C2900, - 0xC6F518AB0A6126C0, 0x3091D352179134AC, - 0xF4CA22097B285D40, 0x33D18DA7B8688C42, - 0x29791F73870D6C60, 0x90F979C19A369E, - 0x4A00D09775E8CDA0, 0x7236339726704A68, - 0x82CD618D9C5501C0, 0x3BFFC9C61E25CA, - 0x4822E93B0A9F93C0, 0x5886BB662A065DEB, - 0x1B71EF6A0E483350, 0x7993EE78C552D6A7, - 0x39E0AB2FE1FDE1D0, 0xA7F04FB818449F2, - 0xE42FD1B7336CA480, 0x52D5EAFAB8973BD4, - 0x22BAD9D7DA6AF260, 0x515B353AFBD4EE57, - 0x516E6080E351FA00, 0x46C13A15087AAB4D, - 0x4690002BD19ACFC0, 0xA955732FECE451B, - 0xC1839BCF7320A80, 0x68BC48675D86763A, - 0x39F2BAACA2659A30, 0x447F3C887998B7D8, - 0xBB694356EF81D8C4, 0x39A5B4F38E7A471D, - 0xC3CEFEF60187ACB4, 0x616EF7950F4C7FCA, - 0x67A4E5D8638E700, 0x3BE4E6C6C898C5F1, - 0x19BCAB6D65CAFE00, 0x20FA8C313A6BF2C9, - 0x636D0F3C9FC78580, 0x32B2E1B2CE393D61, - 0x720FDC7A903CA7B0, 0x51CC3DD4B38C079D, - 0x248557EDBE4E0340, 0x2EA9636EE97D7826, - 0xC7E021A62235AB40, 0x1F16734C2419282F, - 0x5BEA4B95DC05B9C0, 0x7F7C33D4DAAD4F9, - 0x5B5BAE705224D770, 0x1EA0F67A437A7A71, - 0x5D17D7932CC19000, 0x1D3CC922BA197240, - 0x6101D0C1FFA2C6C0, 0x487389C97C1CEE07, - 0xBB32E77C1C107280, 0x7D641103DD9B2707, - 0x87E8BFEEBA53B558, 0x2067B57077296DB7, - 0x222B5A3E4B11C0C0, 0x3B4D2B6D795086A0, - 0x1FE50805EDF36CA0, 0x18B883B5E74ED110, - 0x469F9F415C36B600, 0x23E9E8FFE162A5CE, - 0xFABC60622BA00858, 0x56FA6B95201917F2, - 0x668ECAD07B5F8820, 0x6B2F11A6A97AD3A6, - 0x339076761F9A5620, 0x161A28A6C25DA0E2, - 0x46531456BA060620, 0x29F7B64462EE0005, - 0x3E9C2442965E2520, 0x4FFB944BB8167D50, - 0x2D9983023CD4F1D0, 0x546A2817AA985A1E, - 0x57A6AEFD3B25EA10, 0x33B932B70D6E2C03, - 0xB95A7C73B21C230, 0x2E81CF70F7362E23, - 0x3825ADFDA787E7B0, 0x674E946D7F07319, - 0x96BE8CC46784EA40, 0xE02C1552314BBB6E, - 0x67842F29A7855520, 0x395429C0FA1AAACB, - 0x90E53100E5E8C150, 0xDD6B3CB98F7F4E3, - 0x929E6C8077F2D7C, 0x3DDC32E733BE2198, - 0x3C810D47309F6E68, 0x1071FEAF79247FAB, - 0x6084327787980768, 0x72BD5861B2F1E1D, - 0xC4A21BBC6346E312, 0xFC3EFE40B6C053E8 -}; - - -alignas(32) const uint64_t gfCantorto2128[2*128] = { - 0x1, 0x0, - 0x676AAC9FA4B20B08, 0x295AC0B1F4731AF9, - 0xFF1099C31BBE8F22, 0xA2134422CD4054C9, - 0x53B85B6402B1E848, 0x7959D70CE1EE6942, - 0xCABCD8E4694E5644, 0x8F6B313E935B8E2, - 0x4D48B16661E860EC, 0x49C9321635282198, - 0xA13FE8AC5560CE0C, 0x53D8555A9979A1C, - 0x5CB10FBABCF00118, 0x4D52354A3A3D8C86, - 0xE18C55B8E07D3612, 0x2CCAE6ED8D6B4CD0, - 0x588B6244C5D74470, 0x210D8FBE72672C66, - 0xD047DADA84654DA4, 0xC211182C85E148B3, - 0xFED3B473EEB39DF8, 0x104D101E47F1F112, - 0xBF199EB4F675F2AC, 0xCE955EA0DA2A682B, - 0x19C55B8D6BEF4C98, 0xDBACFB2AC336178F, - 0xF5531B28858156D0, 0x58770BC4E101AB94, - 0x8B97B65B221CC4E4, 0x497F8ADB47E0AE82, - 0xA10CFC6A1654C578, 0x5AA755DF14F64DA, - 0xBAE99A4E3FBE0C54, 0x82DB354523F40C7B, - 0x8E808EC2A80C4662, 0xBA5BA13DBF25EE6B, - 0x5C2B82C39EF7A93C, 0x300B8602354DBC70, - 0x882E2943D5EE4534, 0xC25F5E75EDAA4FA9, - 0x95D3204B1D1DD922, 0x39092E35DE04CC32, - 0xCB6E1A7035541FD6, 0x8AB363F0B1F0F211, - 0xA1318678293664F4, 0xBE1ECA746232042B, - 0xE684ECC9B397A5FE, 0xB3B2D35103F1A3ED, - 0x6DA6F30E41A8EDF0, 0x34B0CC6CCF4EE620, - 0xACD605531D728F16, 0xA6AF6A59808B2143, - 0x36771E3CA90CA14, 0x3555819A552C1192, - 0xC6C1932EEB78B72A, 0xEABEA114C8AE9A9F, - 0xFC5874DD3B9425CE, 0x1988519C2A18A57C, - 0x70EC558472062C44, 0x60ABFABC33F697DE, - 0xA9E47128863BA654, 0xDF68FE1CDF73F30, - 0x8B6F419EA9E92F64, 0x87506CBE98650EE9, - 0xAE03A86096676122, 0xBB5791719BA8F14F, - 0xBA49EF0905BED85A, 0x9AE42542DB02833B, - 0x997880BEBF7EB61C, 0xF29856CA664755B9, - 0x16CB3187D20086C, 0x9E37D35816D18239, - 0x248C663B21703ABE, 0x71815387F77F4DBC, - 0x143024F5848F1090, 0xA6D469FDBE031AB9, - 0x790935AF79870BE0, 0x1D83AB0444495694, - 0xBE2444C534740484, 0xCBAF5837829B974F, - 0x5EFC7F3AA24D39CA, 0xF36A42B3E5F1CBBB, - 0x92372DB327A9D5EE, 0x1CF5645B85D85AC4, - 0xD48CD14917A38034, 0xE374C7526E3ABF93, - 0x2490765A301E28C2, 0xB608A7B1ADE6F573, - 0xAA56DFD514863CF6, 0x9EC927E0EA730849, - 0xB493920663B35D20, 0xF2EEE16207FA6641, - 0x9B78C9542BBA3A2E, 0x79C54CDD0E226966, - 0x456895C1D95FE234, 0xEE72B1A21497E77B, - 0x4EB77B48CC5F7038, 0x9AD3C105B155FFEF, - 0x68F65FA05931208C, 0x585B4042D008C9DA, - 0x16DDE2BB2B38DCFA, 0xAECA82EE463B0B3B, - 0x3904C8D2F5C3D2D6, 0x54D2B7C147B9EAB0, - 0x8B1C8BD76F237756, 0x4D81761CE690153E, - 0x8A2133F2160FC5EC, 0x614A21C3FF3BF28A, - 0x4B053B0413B7ED2A, 0xA7CDB8C6809748D7, - 0x14E4307F9D1772B6, 0x515219CA23F9CE5C, - 0x511E34506522E6AE, 0x8247627F48FF1F7F, - 0xE3A3756C6EFACFC4, 0xF788C793E7244E9F, - 0x5A70839FC81FB4C0, 0xD35F0EB88CAE752B, - 0xDA8E23483A97853A, 0x38F065E6EC77C32C, - 0xD1700CE51721220C, 0xEE558F30070E0C3D, - 0x249484A90E31EF88, 0xD78F250953E96933, - 0x771A1494D77054AC, 0xDE34B71E0312848F, - 0x27F349141093E620, 0x97E14E9448DECAE7, - 0x8DA828E52BE94D70, 0x928DE3C8E22C0F1D, - 0xC1E9DB8AC9F1C256, 0xBA586143DFE63DEB, - 0xD9B45813424B2B38, 0xB2052CA6FB35EAA9, - 0x10F28AB6172A4EFA, 0x794A2A7C84A76D2C, - 0x213491AF2F858C38, 0xA3FB2735D34FBAA7, - 0xDD93CC151A20DCDA, 0xFA7CA4A3574C6525, - 0x3190A2225AB65E2C, 0xFF5E390DA90F4835, - 0x71389B2A8246F5E4, 0xD79573B001F21771, - 0x6AE0532AE2BBFB90, 0xDFD3122B95E92C4F, - 0xCD6B22D4C21C7758, 0x59EE81E35141D3CC, - 0x85E338536EB1BBC, 0xCA785A7F809253D7, - 0xA602F3FD08BBCA2A, 0x3CF77B9A1DED625A, - 0x9CFB59155F2C296A, 0xC74456A7F1E3B58B, - 0xBC92DE7F7EBFD6C4, 0x38FF17882D7D411C, - 0x49DD31700DF81D26, 0x6DAAB92652394278, - 0x3B8F902C0A858E4E, 0x8B95B6A7427690CB, - 0xD525A8185F8AF324, 0xF31F1E9DAABBFF9F, - 0x17F87F09BC736F26, 0xFAFD49E2EE8251E9, - 0xAE5FB3551C95931E, 0x1863362E3AE97756, - 0x9B8F8F876479058E, 0xCAD343E8080CBA83, - 0x51BBCC440C472768, 0xF2E5A279864A60F5, - 0x6340402C3F7FFEBE, 0xB70B9103D1CD6617, - 0xDEB9EF235F15FF90, 0xB7959B94E1E22D49, - 0x5A9D3675A3531196, 0x3524CE9C7F7B56E2, - 0xCE10620E568164C2, 0x8EF7EE5CECDB882D, - 0x854D0FEA22C345B2, 0xDA3844C594D764BF, - 0x16C016C2D631AE74, 0xF2328DF87CDF3E71, - 0x3A9122C15F3AB78, 0x9EB8B35A2448EEFF, - 0x4AC1AB2D94AA463E, 0x3C449B0A0456C972, - 0x70D846AE38FFB938, 0x6CDDD4542B3A7254, - 0x3F1AB33BDD022656, 0xEE26C355DCAC88CF, - 0xA2DEF1742F3B5916, 0x55FE928CCC907446, - 0xC0536B0BE526EB6, 0xCE0290A08EA7ED67, - 0x63118F8310AFBD9C, 0xF3BFE1A1625671EF, - 0x5C5AD70DD7F32AE, 0xFBDCAF23D12E7A5D, - 0x2CD73C266F68DA36, 0x9BFCFCADD6ED8B57, - 0x6D8E1FE42B061D44, 0x3DB9C6976DF592A6, - 0x80CA05549A4DC27C, 0xC75A42071FF8895D, - 0xD1FBFF53B9E5B9A0, 0x11F736ABDBE2672A, - 0xC1CA004429D1C70C, 0x83670004DBE27F63, - 0x7ADE7BA41DA719E2, 0x75FF5173392AD2EA, - 0x2DA0B1432202BAE2, 0xC33784B9B478B88B, - 0x88CC8045CDFF4040, 0x39324DFDAD64AA8E, - 0xD1537109B42CC8A0, 0x8B6232E621520CA1, - 0xC5585EC70C29B8F0, 0x961F8FACDB0EA92D, - 0x641E0BBE37274246, 0x38E42A8AE4B60F8E, - 0xB1F69A8517D41456, 0xC70E543A5A80F74B, - 0xBCCF8CA839BFE3A8, 0x38BD7652FBB4463C, - 0xC4FAB69066E3433A, 0xEFA5F7CA9F6294C1, - 0xB54AFAD4CD1155A8, 0x31317C030896C74A, - 0x7D4BBA2CBAE355D4, 0xD5FB04E16DA98B6, - 0xFD2B185552FCCA1E, 0xAF27A2C3C9AF3B15, - 0xA74E3032C1C70940, 0xB22C87060644347D, - 0x96784C18FA9A222C, 0x9F1317DD9BD62B2B, - 0xA055412A1255732C, 0x9675E5102F20A86D, - 0xBD9E54181B305F0, 0x1196F9167176350A, - 0x2DE9C7568EC18048, 0x4C7D6F6A66426BC8, - 0xF69478D0555733BE, 0x2CF2076679E35CAE, - 0xA0DEA3EAEE857928, 0xEFF27F24FDCF1CB1, - 0x22DE535186312472, 0xB2C39CCA82539E4D, - 0x1C881E66C80D1A94, 0x79FFDC889D966BB8, - 0x34209CFCCF813712, 0xA2DACC7D457CFCD7, - 0xDBFA17232FFAA1AA, 0x9D8978748EA31B83 -}; - - -alignas(32) const uint64_t gf2128toCantor_4R[2*(16*2*16)] = { - -0x0,0x0, -0x1,0x0, -0xf62da500563a6180,0x4e8fb76fadde40ea, -0xf62da500563a6181,0x4e8fb76fadde40ea, -0x8d3b77807d275140,0x69c86cd87b31609f, -0x8d3b77807d275141,0x69c86cd87b31609f, -0x7b16d2802b1d30c0,0x2747dbb7d6ef2075, -0x7b16d2802b1d30c1,0x2747dbb7d6ef2075, -0x49ea0be5a4b1d580,0x45ea054d27f72703, -0x49ea0be5a4b1d581,0x45ea054d27f72703, -0xbfc7aee5f28bb400,0xb65b2228a2967e9, -0xbfc7aee5f28bb401,0xb65b2228a2967e9, -0xc4d17c65d99684c0,0x2c2269955cc6479c, -0xc4d17c65d99684c1,0x2c2269955cc6479c, -0x32fcd9658face540,0x62addefaf1180776, -0x32fcd9658face541,0x62addefaf1180776, -0x0,0x0, -0x4ba6cc4043b4f9e0,0x5d2c5ab446a9d0d0, -0xf4c6a222652d980,0x6dfcf2e44ca64ddd, -0x44eaa66265e62060,0x30d0a8500a0f9d0d, -0xed1f0e1776e93f40,0x671f07ebb40cb482, -0xa6b9c257355dc6a0,0x3a335d5ff2a56452, -0xe253643550bbe6c0,0xae3f50ff8aaf95f, -0xa9f5a875130f1f20,0x57cfafbbbe03298f, -0x938422464f555d80,0x53c60b27554dcb46, -0xd822ee060ce1a460,0xeea519313e41b96, -0x9cc8486469078400,0x3e3af9c319eb869b, -0xd76e84242ab37de0,0x6316a3775f42564b, -0x7e9b2c5139bc62c0,0x34d90ccce1417fc4, -0x353de0117a089b20,0x69f55678a7e8af14, -0x71d746731feebb40,0x5925fe28ade73219, -0x3a718a335c5a42a0,0x409a49ceb4ee2c9, -0x0,0x0, -0x6e75aa60626e8510,0x73ba77ee65fd38b8, -0x5176a0b45a20dd80,0x79ab26e5f2005eb2, -0x3f030ad4384e5890,0xa11510b97fd660a, -0x88ea5f33357bb540,0x5b028b966af56b33, -0xe69ff55357153050,0x28b8fc780f08538b, -0xd99cff876f5b68c0,0x22a9ad7398f53581, -0xb7e955e70d35edd0,0x5113da9dfd080d39, -0xebaa5b08988bab80,0xfbb35dbfeaca77c, -0x85dff168fae52e90,0x7c0142359b519fc4, -0xbadcfbbcc2ab7600,0x7610133e0cacf9ce, -0xd4a951dca0c5f310,0x5aa64d06951c176, -0x6340043badf01ec0,0x54b9be4d9459cc4f, -0xd35ae5bcf9e9bd0,0x2703c9a3f1a4f4f7, -0x3236a48ff7d0c340,0x2d1298a8665992fd, -0x5c430eef95be4650,0x5ea8ef4603a4aa45, -0x0,0x0, -0x9b90891ccd9da0e0,0x5490841e6e0aeec3, -0x71e8f62ad6538480,0x10ff7ae9fd162518, -0xea787f361bce2460,0x446ffef7931ccbdb, -0xda46336568fff340,0x7a250eb4ffeb2ee5, -0x41d6ba79a56253a0,0x2eb58aaa91e1c026, -0xabaec54fbeac77c0,0x6ada745d02fd0bfd, -0x303e4c537331d720,0x3e4af0436cf7e53e, -0x73070bb8fbfbae80,0x51f6b50b77fb18d, -0xe89782a436660e60,0x518fef4ed9755f4e, -0x2effd922da82a00,0x15e011b94a699495, -0x997f748ee0358ae0,0x417095a724637a56, -0xa94138dd93045dc0,0x7f3a65e448949f68, -0x32d1b1c15e99fd20,0x2baae1fa269e71ab, -0xd8a9cef74557d940,0x6fc51f0db582ba70, -0x433947eb88ca79a0,0x3b559b13db8854b3, -0x0,0x0, -0x594f7f505359c798,0x4a674c195703a4e4, -0xac5cbaddd0a35780,0x7993d46d3c8420e0, -0xf513c58d83fa9018,0x33f498746b878404, -0x79cdf0ee7730b340,0x457eb5970b0071eb, -0x20828fbe246974d8,0xf19f98e5c03d50f, -0xd5914a33a793e4c0,0x3ced61fa3784510b, -0x8cde3563f4ca2358,0x768a2de36087f5ef, -0x2f29a7f7044ef00,0x1ca1ea3434b30df4, -0x5bbde52f231d2898,0x56c6a62d63b0a910, -0xaeae20a2a0e7b880,0x65323e5908372d14, -0xf7e15ff2f3be7f18,0x2f5572405f3489f0, -0x7b3f6a9107745c40,0x59df5fa33fb37c1f, -0x227015c1542d9bd8,0x13b813ba68b0d8fb, -0xd763d04cd7d70bc0,0x204c8bce03375cff, -0x8e2caf1c848ecc58,0x6a2bc7d75434f81b, -0x0,0x0, -0x4c9f70aaafc66fe0,0x7683ce5d5f8fdeaa, -0xf7ff15ec6e75a480,0x68383cb9786af78a, -0xbb606546c1b3cb60,0x1ebbf2e427e52920, -0x9e7f768cd4ce7e40,0x866af3601faf4c2, -0xd2e006267b0811a0,0x7ee5616b5e752a68, -0x69806360babbdac0,0x605e938f79900348, -0x251f13ca157db520,0x16dd5dd2261fdde2, -0xf8bfffdceb48f300,0x8bbb968cda7aeb6, -0xb4208f76448e9ce0,0x7e3877359228701c, -0xf40ea30853d5780,0x608385d1b5cd593c, -0x43df9a9a2afb3860,0x16004b8cea428796, -0x66c089503f868d40,0xdd165ecc5d5a74, -0x2a5ff9fa9040e2a0,0x765ed80393d284de, -0x913f9cbc51f329c0,0x68e52ae7b437adfe, -0xdda0ec16fe354620,0x1e66e4baebb87354, -0x0,0x0, -0x5658cd92ab537090,0x7ed8c611590f99a2, -0x97f31ac8bfcf79c0,0x41a564ef69f0061b, -0xc1abd75a149c0950,0x3f7da2fe30ff9fb9, -0x491c8d3fbd7a46c0,0x1880c79d039d3794, -0x1f4440ad16293650,0x6658018c5a92ae36, -0xdeef97f702b53f00,0x5925a3726a6d318f, -0x88b75a65a9e64f90,0x27fd65633362a82d, -0x5320998dc8436ee0,0x2ad36ec06c212493, -0x578541f63101e70,0x540ba8d1352ebd31, -0xc4d38345778c1720,0x6b760a2f05d12288, -0x928b4ed7dcdf67b0,0x15aecc3e5cdebb2a, -0x1a3c14b275392820,0x3253a95d6fbc1307, -0x4c64d920de6a58b0,0x4c8b6f4c36b38aa5, -0x8dcf0e7acaf651e0,0x73f6cdb2064c151c, -0xdb97c3e861a52170,0xd2e0ba35f438cbe, -0x0,0x0, -0x37652ad7dc800ae0,0x473789ee801eb997, -0xcde57afded182e80,0x599cbaf635479bbf, -0xfa80502a31982460,0x1eab3318b5592228, -0xca848e64860679c0,0x790def8ecc0694b, -0xfde1a4b35a867320,0x40a757166cded0dc, -0x761f4996b1e5740,0x5e0c640ed987f2f4, -0x3004de4eb79e5da0,0x193bede059994b63, -0xbde78f553997130,0x31b03d86963281e0, -0x3cbb52228f197bd0,0x7687b468162c3877, -0xc63b0208be815fb0,0x682c8770a3751a5f, -0xf15e28df62015550,0x2f1b0e9e236ba3c8, -0xc15af691d59f08f0,0x3620e37e7af2e8ab, -0xf63fdc46091f0210,0x71176a90faec513c, -0xcbf8c6c38872670,0x6fbc59884fb57314, -0x3bdaa6bbe4072c90,0x288bd066cfabca83, -0x0,0x0, -0x75e8c0f87af52454,0x6f54ea15fc827696, -0x57b33c64a3509080,0x4ac5e2d5008ca73c, -0x225bfc9cd9a5b4d4,0x259108c0fc0ed1aa, -0xfa72e7b338f2fc40,0x455a3e5ba2c63090, -0x8f9a274b4207d814,0x2a0ed44e5e444606, -0xadc1dbd79ba26cc0,0xf9fdc8ea24a97ac, -0xd8291b2fe1574894,0x60cb369b5ec8e13a, -0xc25a47daa93bca80,0x28dc1d391faf20f7, -0xb7b28722d3ceeed4,0x4788f72ce32d5661, -0x95e97bbe0a6b5a00,0x6219ffec1f2387cb, -0xe001bb46709e7e54,0xd4d15f9e3a1f15d, -0x3828a06991c936c0,0x6d862362bd691067, -0x4dc06091eb3c1294,0x2d2c97741eb66f1, -0x6f9b9c0d3299a640,0x2743c1b7bde5b75b, -0x1a735cf5486c8214,0x48172ba24167c1cd, -0x0,0x0, -0xc52b08994ca8eae0,0x67c1ef5c8e80491e, -0x38335d064e98e300,0x300d6942f7cd9ec1, -0xfd18559f023009e0,0x57cc861e794dd7df, -0x38bd740c8669880,0x12f11f2e2eea8b0e, -0xc6a0dfd984ce7260,0x7530f072a06ac210, -0x3bb88a4686fe7b80,0x22fc766cd92715cf, -0xfe9382dfca569160,0x453d993057a75cd1, -0x684de1efe77b4680,0x3e7995b45292dcba, -0xad66e976abd3ac60,0x59b87ae8dc1295a4, -0x507ebce9a9e3a580,0xe74fcf6a55f427b, -0x9555b470e54b4f60,0x69b513aa2bdf0b65, -0x6bc636af2f1dde00,0x2c888a9a7c7857b4, -0xaeed3e3663b534e0,0x4b4965c6f2f81eaa, -0x53f56ba961853d00,0x1c85e3d88bb5c975, -0x96de63302d2dd7e0,0x7b440c840535806b, -0x0,0x0, -0x6ad0c8fff8255810,0x4dc22973f04831ff, -0x588c3c0e52306980,0x229ef6c52fb0f783, -0x325cf4f1aa153190,0x6f5cdfb6dff8c67c, -0x8c009f1a594f76c0,0x5c2422e5c45f8c4f, -0xe6d057e5a16a2ed0,0x11e60b963417bdb0, -0xd48ca3140b7f1f40,0x7ebad420ebef7bcc, -0xbe5c6bebf35a4750,0x3378fd531ba74a33, -0x703cb1d20ceae280,0x6f04d24433fb96b2, -0x1aec792df4cfba90,0x22c6fb37c3b3a74d, -0x28b08ddc5eda8b00,0x4d9a24811c4b6131, -0x42604523a6ffd310,0x580df2ec0350ce, -0xfc3c2ec855a59440,0x3320f0a1f7a41afd, -0x96ece637ad80cc50,0x7ee2d9d207ec2b02, -0xa4b012c60795fdc0,0x11be0664d814ed7e, -0xce60da39ffb0a5d0,0x5c7c2f17285cdc81, -0x0,0x0, -0xd140cdcabea94160,0xc55f8ad01078ea3, -0x3cd36e9a93b35c40,0x6192262cad674b9a, -0xed93a3502d1a1d20,0x6dc7de81ac60c539, -0x84e000329eec8a80,0xce665dcab7479ed, -0x55a0cdf82045cbe0,0xb39d71aa73f74e, -0xb8336ea80d5fd6c0,0x6d7443f006133277, -0x6973a362b3f697a0,0x6121bb5d0714bcd4, -0xd15cd3373c46ec20,0x7855d70faeef256f, -0x1c1efd82efad40,0x74002fa2afe8abcc, -0xed8fbdadaff5b060,0x19c7f12303886ef5, -0x3ccf7067115cf100,0x1592098e028fe056, -0x55bcd305a2aa66a0,0x74b3b2d3059b5c82, -0x84fc1ecf1c0327c0,0x78e64a7e049cd221, -0x696fbd9f31193ae0,0x152194ffa8fc1718, -0xb82f70558fb07b80,0x19746c52a9fb99bb, -0x0,0x0, -0x7d74ab5bfefac8d8,0x41b4a519f5885573, -0xeed73249b9735400,0x3f530821d3b2a371, -0x93a3991247899cd8,0x7ee7ad38263af602, -0x5c0a97ace028c520,0x6177d698dd080516, -0x217e3cf71ed20df8,0x20c3738128805065, -0xb2dda5e5595b9120,0x5e24deb90ebaa667, -0xcfa90ebea7a159f8,0x1f907ba0fb32f314, -0x85403ec43c26cd80,0x15e45d883811cfca, -0xf834959fc2dc0558,0x5450f891cd999ab9, -0x6b970c8d85559980,0x2ab755a9eba36cbb, -0x16e3a7d67baf5158,0x6b03f0b01e2b39c8, -0xd94aa968dc0e08a0,0x74938b10e519cadc, -0xa43e023322f4c078,0x35272e0910919faf, -0x379d9b21657d5ca0,0x4bc0833136ab69ad, -0x4ae9307a9b879478,0xa742628c3233cde, -0x0,0x0, -0x6d92cba063c765a0,0x14c0a4538253ac5e, -0xbe016081553c8480,0x705d0e8e57e8b405, -0xd393ab2136fbe120,0x649daaddd5bb185b, -0xfab0d54b2c62d990,0x3fbad9a05a31b6da, -0x97221eeb4fa5bc30,0x2b7a7df3d8621a84, -0x44b1b5ca795e5d10,0x4fe7d72e0dd902df, -0x29237e6a1a9938b0,0x5b27737d8f8aae81, -0xeab9f006b6a248c0,0x10d0fd26ba749e1f, -0x872b3ba6d5652d60,0x410597538273241, -0x54b89087e39ecc40,0x608df3a8ed9c2a1a, -0x392a5b278059a9e0,0x744d57fb6fcf8644, -0x1009254d9ac09150,0x2f6a2486e04528c5, -0x7d9beeedf907f4f0,0x3baa80d56216849b, -0xae0845cccffc15d0,0x5f372a08b7ad9cc0, -0xc39a8e6cac3b7070,0x4bf78e5b35fe309e, -0x0,0x0, -0xacd7bfbc32c00f90,0x64ac4d19c011e55c, -0x22e05ba415139bc0,0x1bec30c48396c0bc, -0x8e37e41827d39450,0x7f407ddd438725e0, -0x2b17c7831b9439c0,0x7552e78d2fe45660, -0x87c0783f29543650,0x11feaa94eff5b33c, -0x9f79c270e87a200,0x6ebed749ac7296dc, -0xa520239b3c47ad90,0xa129a506c637380, -0x9ac4cb562dc6b3e0,0x22d1dcda09b437fd, -0x361374ea1f06bc70,0x467d91c3c9a5d2a1, -0xb82490f238d52820,0x393dec1e8a22f741, -0x14f32f4e0a1527b0,0x5d91a1074a33121d, -0xb1d30cd536528a20,0x57833b572650619d, -0x1d04b369049285b0,0x332f764ee64184c1, -0x93335771234111e0,0x4c6f0b93a5c6a121, -0x3fe4e8cd11811e70,0x28c3468a65d7447d, -0x0,0x0, -0x2fc6c956c5054520,0x458b1849aa05dee, -0x4507ca313af999c0,0x2e67ce80ac133372, -0x6ac10367fffcdce0,0x2a3f7f0436b36e9c, -0xe31448ffa55c9a8,0x29682345dd2bc110, -0x21f78dd93f508c88,0x2d3092c1478b9cfe, -0x4b368ebec0ac5068,0x70fedc57138f262, -0x64f047e805a91548,0x3575c41eb98af8c, -0x40f823a5051005b0,0x5cd66fbedca1416, -0x6f3eeaf3c0154090,0x195d77f776a49f8, -0x5ffe9943fe99c70,0x2baaa87b41d92764, -0x2a3920c2faecd950,0x2ff219ffdb797a8a, -0x4ec9672aff45cc18,0x2ca545be30e1d506, -0x610fae7c3a408938,0x28fdf43aaa4188e8, -0xbcead1bc5bc55d8,0x2c28b3e9cf2e674, -0x2408644d00b910f8,0x69a3aba0652bb9a, -0x0,0x0, -0x4f1ca084478fb67e,0x58fe9f1f02c34ddd, -0x9401e0e17ffcc0c0,0xf39e6874fb57154, -0xdb1d4065387376be,0x57c779984d763c89, -0x7c6aa256f2f8d8c0,0x6fa713bf80caf4a2, -0x337602d2b5776ebe,0x37598ca08209b97f, -0xe86b42b78d041800,0x609ef538cf7f85f6, -0xa777e233ca8bae7e,0x38606a27cdbcc82b, -0x41fba012f6fe4260,0x6517fe8daecc43b8, -0xee70096b171f41e,0x3de96192ac0f0e65, -0xd5fa40f3890282a0,0x6a2e180ae17932ec, -0x9ae6e077ce8d34de,0x32d08715e3ba7f31, -0x3d91024404069aa0,0xab0ed322e06b71a, -0x728da2c043892cde,0x524e722d2cc5fac7, -0xa990e2a57bfa5a60,0x5890bb561b3c64e, -0xe68c42213c75ec1e,0x5d7794aa63708b93, -0x0,0x0, -0x874b946aa48b8260,0x67f7217673a528d8, -0x67082553208b4ec0,0x512cb42b7b65fc48, -0xe043b1398400cca0,0x36db955d08c0d490, -0x23776437fda62fc0,0x3cb213a59078b08c, -0xa43cf05d592dada0,0x5b4532d3e3dd9854, -0x447f4164dd2d6100,0x6d9ea78eeb1d4cc4, -0xc334d50e79a6e360,0xa6986f898b8641c, -0x55e63becbcfd490,0x69b9e67845568804, -0x8215f7d46f4456f0,0xe4ec70e36f3a0dc, -0x625646edeb449a50,0x389552533e33744c, -0xe51dd2874fcf1830,0x5f6273254d965c94, -0x262907893669fb50,0x550bf5ddd52e3888, -0xa16293e392e27930,0x32fcd4aba68b1050, -0x412122da16e2b590,0x42741f6ae4bc4c0, -0xc66ab6b0b26937f0,0x63d06080ddeeec18, -0x0,0x0, -0xa7be8cd5eafc9f90,0x542118f2c9c06d91, -0x3f9dff5de5a98c40,0x4b5159e1f17738cb, -0x982373880f5513d0,0x1f70411338b7555a, -0xa42af38569d49280,0x280bdde38c2b51a1, -0x3947f5083280d10,0x7c2ac51145eb3c30, -0x9bb70cd88c7d1ec0,0x635a84027d5c696a, -0x3c09800d66818150,0x377b9cf0b49c04fb, -0x56562bd5ae896260,0x3aee4cd13fe66fb1, -0xf1e8a7004475fdf0,0x6ecf5423f6260220, -0x69cbd4884b20ee20,0x71bf1530ce91577a, -0xce75585da1dc71b0,0x259e0dc207513aeb, -0xf27cd850c75df0e0,0x12e59132b3cd3e10, -0x55c254852da16f70,0x46c489c07a0d5381, -0xcde1270d22f47ca0,0x59b4c8d342ba06db, -0x6a5fabd8c808e330,0xd95d0218b7a6b4a, -0x0,0x0, -0x24e3ce0ac55d4c0,0x1b8990b9399fce89, -0x534c03fe0cb12380,0x2ac17c44b5cbf6c8, -0x51023f1ea0e4f740,0x3148ecfd8c543841, -0x5c6b111814c6e5c0,0x21455f6e7bdbb2e7, -0x5e252df8b8933100,0x3acccfd742447c6e, -0xf2712e61877c640,0xb84232ace10442f, -0xd692e06b4221280,0x100db393f78f8aa6, -0xf701b24abea37538,0x4e51bfce5ed600a8, -0xf54f8eaa12f6a1f8,0x55d82f776749ce21, -0xa44db1b4b21256b8,0x6490c38aeb1df660, -0xa6038d541e478278,0x7f195333d28238e9, -0xab6aa352aa6590f8,0x6f14e0a0250db24f, -0xa9249fb206304438,0x749d70191c927cc6, -0xf826a0aca6d4b378,0x45d59ce490c64487, -0xfa689c4c0a8167b8,0x5e5c0c5da9598a0e, -0x0,0x0, -0xdfb8ac800437f418,0x6b233dca086c2900, -0xc6f518ab0a6126c0,0x3091d352179134ac, -0x194db42b0e56d2d8,0x5bb2ee981ffd1dac, -0xf4ca22097b285d40,0x33d18da7b8688c42, -0x2b728e897f1fa958,0x58f2b06db004a542, -0x323f3aa271497b80,0x3405ef5aff9b8ee, -0xed879622757e8f98,0x6863633fa79591ee, -0x29791f73870d6c60,0x90f979c19a369e, -0xf6c1b3f3833a9878,0x6bb3c4b3c9f61f9e, -0xef8c07d88d6c4aa0,0x30012a2bd60b0232, -0x3034ab58895bbeb8,0x5b2217e1de672b32, -0xddb33d7afc253120,0x334174de79f2badc, -0x20b91faf812c538,0x58624914719e93dc, -0x1b4625d1f64417e0,0x3d0a78c6e638e70, -0xc4fe8951f273e3f8,0x68f39a46660fa770, -0x0,0x0, -0x4a00d09775e8cda0,0x7236339726704a68, -0x82cd618d9c5501c0,0x3bffc9c61e25ca, -0xc8cdb11ae9bdcc60,0x720dcc5ee06e6fa2, -0x4822e93b0a9f93c0,0x5886bb662a065deb, -0x22239ac7f775e60,0x2ab088f10c761783, -0xcaef88b696ca9200,0x58bd44afec187821, -0x80ef5821e3225fa0,0x2a8b7738ca683249, -0x1b71ef6a0e483350,0x7993ee78c552d6a7, -0x51713ffd7ba0fef0,0xba5ddefe3229ccf, -0x99bc8ee7921d3290,0x79a811b1034cf36d, -0xd3bc5e70e7f5ff30,0xb9e2226253cb905, -0x5353065104d7a090,0x2115551eef548b4c, -0x1953d6c6713f6d30,0x53236689c924c124, -0xd19e67dc9882a150,0x212eaad7294aae86, -0x9b9eb74bed6a6cf0,0x531899400f3ae4ee, -0x0,0x0, -0x39e0ab2fe1fde1d0,0xa7f04fb818449f2, -0xe42fd1b7336ca480,0x52d5eafab8973bd4, -0xddcf7a98d2914550,0x58aaee0139137226, -0x22bad9d7da6af260,0x515b353afbd4ee57, -0x1b5a72f83b9713b0,0x5b2431c17a50a7a5, -0xc6950860e90656e0,0x38edfc04343d583, -0xff75a34f08fbb730,0x9f1db3bc2c79c71, -0x516e6080e351fa00,0x46c13a15087aab4d, -0x688ecbaf02ac1bd0,0x4cbe3eee89fee2bf, -0xb541b137d03d5e80,0x1414d0efb0ed9099, -0x8ca11a1831c0bf50,0x1e6bd4143169d96b, -0x73d4b957393b0860,0x179a0f2ff3ae451a, -0x4a341278d8c6e9b0,0x1de50bd4722a0ce8, -0x97fb68e00a57ace0,0x454fe5d54b397ece, -0xae1bc3cfebaa4d30,0x4f30e12ecabd373c, -0x0,0x0, -0x4690002bd19acfc0,0xa955732fece451b, -0xc1839bcf7320a80,0x68bc48675d86763a, -0x4a88399726a8c540,0x62291f55a3483321, -0x39f2baaca2659a30,0x447f3c887998b7d8, -0x7f62ba8773ff55f0,0x4eea6bba8756f2c3, -0x35ea8310555790b0,0x2cc374ef241ec1e2, -0x737a833b84cd5f70,0x265623dddad084f9, -0xbb694356ef81d8c4,0x39a5b4f38e7a471d, -0xfdf9437d3e1b1704,0x3330e3c170b40206, -0xb7717aea18b3d244,0x5119fc94d3fc3127, -0xf1e17ac1c9291d84,0x5b8caba62d32743c, -0x829bf9fa4de442f4,0x7dda887bf7e2f0c5, -0xc40bf9d19c7e8d34,0x774fdf49092cb5de, -0x8e83c046bad64874,0x1566c01caa6486ff, -0xc813c06d6b4c87b4,0x1ff3972e54aac3e4, -0x0,0x0, -0xc3cefef60187acb4,0x616ef7950f4c7fca, -0x67a4e5d8638e700,0x3be4e6c6c898c5f1, -0xc5b4b0ab87bf4bb4,0x5a8a1153c7d4ba3b, -0x19bcab6d65cafe00,0x20fa8c313a6bf2c9, -0xda72559b644d52b4,0x41947ba435278d03, -0x1fc6e530e3f21900,0x1b1e6af7f2f33738, -0xdc081bc6e275b5b4,0x7a709d62fdbf48f2, -0x636d0f3c9fc78580,0x32b2e1b2ce393d61, -0xa0a3f1ca9e402934,0x53dc1627c17542ab, -0x6517416119ff6280,0x956077406a1f890, -0xa6d9bf971878ce34,0x6838f0e109ed875a, -0x7ad1a451fa0d7b80,0x12486d83f452cfa8, -0xb91f5aa7fb8ad734,0x73269a16fb1eb062, -0x7cabea0c7c359c80,0x29ac8b453cca0a59, -0xbf6514fa7db23034,0x48c27cd033867593, -0x0,0x0, -0x720fdc7a903ca7b0,0x51cc3dd4b38c079d, -0x248557edbe4e0340,0x2ea9636ee97d7826, -0x568a8b972e72a4f0,0x7f655eba5af17fbb, -0xc7e021a62235ab40,0x1f16734c2419282f, -0xb5effddcb2090cf0,0x4eda4e9897952fb2, -0xe365764b9c7ba800,0x31bf1022cd645009, -0x916aaa310c470fb0,0x60732df67ee85794, -0x5bea4b95dc05b9c0,0x7f7c33d4daad4f9, -0x29e597ef4c391e70,0x563bfee9fe26d364, -0x7f6f1c78624bba80,0x295ea053a4d7acdf, -0xd60c002f2771d30,0x78929d87175bab42, -0x9c0a6a33fe301280,0x18e1b07169b3fcd6, -0xee05b6496e0cb530,0x492d8da5da3ffb4b, -0xb88f3dde407e11c0,0x3648d31f80ce84f0, -0xca80e1a4d042b670,0x6784eecb3342836d, -0x0,0x0, -0x5b5bae705224d770,0x1ea0f67a437a7a71, -0x5d17d7932cc19000,0x1d3cc922ba197240, -0x64c79e37ee54770,0x39c3f58f9630831, -0x6101d0c1ffa2c6c0,0x487389c97c1cee07, -0x3a5a7eb1ad8611b0,0x56d37fb33f669476, -0x3c160752d36356c0,0x554f40ebc6059c47, -0x674da922814781b0,0x4befb691857fe636, -0xbb32e77c1c107280,0x7d641103dd9b2707, -0xe069490c4e34a5f0,0x63c4e7799ee15d76, -0xe62530ef30d1e280,0x6058d82167825547, -0xbd7e9e9f62f535f0,0x7ef82e5b24f82f36, -0xda3337bde3b2b440,0x351798caa187c900, -0x816899cdb1966330,0x2bb76eb0e2fdb371, -0x8724e02ecf732440,0x282b51e81b9ebb40, -0xdc7f4e5e9d57f330,0x368ba79258e4c131, -0x0,0x0, -0x87e8bfeeba53b558,0x2067b57077296db7, -0x222b5a3e4b11c0c0,0x3b4d2b6d795086a0, -0xa5c3e5d0f1427598,0x1b2a9e1d0e79eb17, -0x1fe50805edf36ca0,0x18b883b5e74ed110, -0x980db7eb57a0d9f8,0x38df36c59067bca7, -0x3dce523ba6e2ac60,0x23f5a8d89e1e57b0, -0xba26edd51cb11938,0x3921da8e9373a07, -0x469f9f415c36b600,0x23e9e8ffe162a5ce, -0xc17720afe6650358,0x38e5d8f964bc879, -0x64b4c57f172776c0,0x18a4c3929832236e, -0xe35c7a91ad74c398,0x38c376e2ef1b4ed9, -0x597a9744b1c5daa0,0x3b516b4a062c74de, -0xde9228aa0b966ff8,0x1b36de3a71051969, -0x7b51cd7afad41a60,0x1c40277f7cf27e, -0xfcb972944087af38,0x207bf55708559fc9, -0x0,0x0, -0xfabc60622ba00858,0x56fa6b95201917f2, -0x668ecad07b5f8820,0x6b2f11a6a97ad3a6, -0x9c32aab250ff8078,0x3dd57a338963c454, -0x339076761f9a5620,0x161a28a6c25da0e2, -0xc92c1614343a5e78,0x40e04333e244b710, -0x551ebca664c5de00,0x7d3539006b277344, -0xafa2dcc44f65d658,0x2bcf52954b3e64b6, -0x46531456ba060620,0x29f7b64462ee0005, -0xbcef743491a60e78,0x7f0dddd142f717f7, -0x20ddde86c1598e00,0x42d8a7e2cb94d3a3, -0xda61bee4eaf98658,0x1422cc77eb8dc451, -0x75c36220a59c5000,0x3fed9ee2a0b3a0e7, -0x8f7f02428e3c5858,0x6917f57780aab715, -0x134da8f0dec3d820,0x54c28f4409c97341, -0xe9f1c892f563d078,0x238e4d129d064b3, -0x0,0x0, -0x3e9c2442965e2520,0x4ffb944bb8167d50, -0x2d9983023cd4f1d0,0x546a2817aa985a1e, -0x1305a740aa8ad4f0,0x1b91bc5c128e274e, -0x57a6aefd3b25ea10,0x33b932b70d6e2c03, -0x693a8abfad7bcf30,0x7c42a6fcb5785153, -0x7a3f2dff07f11bc0,0x67d31aa0a7f6761d, -0x44a309bd91af3ee0,0x28288eeb1fe00b4d, -0xb95a7c73b21c230,0x2e81cf70f7362e23, -0x35098385ad7fe710,0x617a5b3b4f205373, -0x260c24c507f533e0,0x7aebe7675dae743d, -0x1890008791ab16c0,0x3510732ce5b8096d, -0x5c33093a00042820,0x1d38fdc7fa580220, -0x62af2d78965a0d00,0x52c3698c424e7f70, -0x71aa8a383cd0d9f0,0x4952d5d050c0583e, -0x4f36ae7aaa8efcd0,0x6a9419be8d6256e, -0x0,0x0, -0x3825adfda787e7b0,0x674e946d7f07319, -0x96be8cc46784ea40,0xe02c1552314bbb6e, -0xae9b2139c0030df0,0xe658fc14e6bbc877, -0x67842f29a7855520,0x395429c0fa1aaacb, -0x5fa182d40002b290,0x3f20c0862dead9d2, -0xf13aa3edc001bf60,0xd9783c92cb5111a5, -0xc91f0e10678658d0,0xdf0cd5d41ca162bc, -0x90e53100e5e8c150,0xdd6b3cb98f7f4e3, -0xa8c09cfd426f26e0,0xba25a8d4f0787fa, -0x65bbdc4826c2b10,0xedfaa699a9bc4f8d, -0x3e7e103925ebcca0,0xeb8e4fdf7e4c3c94, -0xf7611e29426d9470,0x34829a0b62ed5e28, -0xcf44b3d4e5ea73c0,0x32f6734db51d2d31, -0x61df92ed25e97e30,0xd4ae8f5953a6e546, -0x59fa3f10826e9980,0xd2da661f8456965f, -0x0,0x0, -0x929e6c8077f2d7c,0x3ddc32e733be2198, -0x3c810d47309f6e68,0x1071feaf79247fab, -0x35a8eb8f37e04314,0x2dadcc484a9a5e33, -0x6084327787980768,0x72bd5861b2f1e1d, -0x69add4bf80e72a14,0x3af7e76128913f85, -0x5c053f30b7076900,0x175a2b29620b61b6, -0x552cd9f8b078447c,0x2a8619ce51b5402e, -0xc4a21bbc6346e312,0xfc3efe40b6c053e8, -0xcd8bfd746439ce6e,0xc1e2cca7857e7270, -0xf82316fb53d98d7a,0xec4f00efcfe42c43, -0xf10af03354a6a006,0xd1933208fc5a0ddb, -0xa42629cbe4dee47a,0xfb152bc6adef4df5, -0xad0fcf03e3a1c906,0xc6c919219e516c6d, -0x98a7248cd4418a12,0xeb64d569d4cb325e, -0x918ec244d33ea76e,0xd6b8e78ee77513c6, -}; -// -//alignas(32) const uint64_t gfCantorto2128_4R[2*(16*2*16)] = { -//0x0,0x0, -//0x1,0x0, -//0x676aac9fa4b20b08,0x295ac0b1f4731af9, -//0x676aac9fa4b20b09,0x295ac0b1f4731af9, -//0xff1099c31bbe8f22,0xa2134422cd4054c9, -//0xff1099c31bbe8f23,0xa2134422cd4054c9, -//0x987a355cbf0c842a,0x8b49849339334e30, -//0x987a355cbf0c842b,0x8b49849339334e30, -//0x53b85b6402b1e848,0x7959d70ce1ee6942, -//0x53b85b6402b1e849,0x7959d70ce1ee6942, -//0x34d2f7fba603e340,0x500317bd159d73bb, -//0x34d2f7fba603e341,0x500317bd159d73bb, -//0xaca8c2a7190f676a,0xdb4a932e2cae3d8b, -//0xaca8c2a7190f676b,0xdb4a932e2cae3d8b, -//0xcbc26e38bdbd6c62,0xf210539fd8dd2772, -//0xcbc26e38bdbd6c63,0xf210539fd8dd2772, -//0x0,0x0, -//0xcabcd8e4694e5644,0x8f6b313e935b8e2, -//0x4d48b16661e860ec,0x49c9321635282198, -//0x87f4698208a636a8,0x413f8105dc1d997a, -//0xa13fe8ac5560ce0c,0x53d8555a9979a1c, -//0x6b8330483c2e9848,0xdcb364640a222fe, -//0xec7759ca3488aee0,0x4cf4b7439cbfbb84, -//0x26cb812e5dc6f8a4,0x44020450758a0366, -//0x5cb10fbabcf00118,0x4d52354a3a3d8c86, -//0x960dd75ed5be575c,0x45a48659d3083464, -//0x11f9bedcdd1861f4,0x49b075c0f15ad1e, -//0xdb456638b45637b0,0xc6db44fe62015fc, -//0xfd8ee716e990cf14,0x486fb01f93aa169a, -//0x37323ff280de9950,0x4099030c7a9fae78, -//0xb0c656708878aff8,0x1a68209a6823702, -//0x7a7a8e94e136f9bc,0x950311a4fb78fe0, -//0x0,0x0, -//0xe18c55b8e07d3612,0x2ccae6ed8d6b4cd0, -//0x588b6244c5d74470,0x210d8fbe72672c66, -//0xb90737fc25aa7262,0xdc76953ff0c60b6, -//0xd047dada84654da4,0xc211182c85e148b3, -//0x31cb8f6264187bb6,0xeedbfec1088a0463, -//0x88ccb89e41b209d4,0xe31c9792f78664d5, -//0x6940ed26a1cf3fc6,0xcfd6717f7aed2805, -//0xfed3b473eeb39df8,0x104d101e47f1f112, -//0x1f5fe1cb0eceabea,0x3c87f6f3ca9abdc2, -//0xa658d6372b64d988,0x31409fa03596dd74, -//0x47d4838fcb19ef9a,0x1d8a794db8fd91a4, -//0x2e946ea96ad6d05c,0xd25c0832c210b9a1, -//0xcf183b118aabe64e,0xfe96eedf4f7bf571, -//0x761f0cedaf01942c,0xf351878cb07795c7, -//0x979359554f7ca23e,0xdf9b61613d1cd917, -//0x0,0x0, -//0xbf199eb4f675f2ac,0xce955ea0da2a682b, -//0x19c55b8d6bef4c98,0xdbacfb2ac336178f, -//0xa6dcc5399d9abe34,0x1539a58a191c7fa4, -//0xf5531b28858156d0,0x58770bc4e101ab94, -//0x4a4a859c73f4a47c,0x96e255643b2bc3bf, -//0xec9640a5ee6e1a48,0x83dbf0ee2237bc1b, -//0x538fde11181be8e4,0x4d4eae4ef81dd430, -//0x8b97b65b221cc4e4,0x497f8adb47e0ae82, -//0x348e28efd4693648,0x87ead47b9dcac6a9, -//0x9252edd649f3887c,0x92d371f184d6b90d, -//0x2d4b7362bf867ad0,0x5c462f515efcd126, -//0x7ec4ad73a79d9234,0x1108811fa6e10516, -//0xc1dd33c751e86098,0xdf9ddfbf7ccb6d3d, -//0x6701f6fecc72deac,0xcaa47a3565d71299, -//0xd818684a3a072c00,0x4312495bffd7ab2, -//0x0,0x0, -//0xa10cfc6a1654c578,0x5aa755df14f64da, -//0xbae99a4e3fbe0c54,0x82db354523f40c7b, -//0x1be5662429eac92c,0x87714018d2bb68a1, -//0x8e808ec2a80c4662,0xba5ba13dbf25ee6b, -//0x2f8c72a8be58831a,0xbff1d4604e6a8ab1, -//0x3469148c97b24a36,0x388094789cd1e210, -//0x9565e8e681e68f4e,0x3d2ae1256d9e86ca, -//0x5c2b82c39ef7a93c,0x300b8602354dbc70, -//0xfd277ea988a36c44,0x35a1f35fc402d8aa, -//0xe6c2188da149a568,0xb2d0b34716b9b00b, -//0x47cee4e7b71d6010,0xb77ac61ae7f6d4d1, -//0xd2ab0c0136fbef5e,0x8a50273f8a68521b, -//0x73a7f06b20af2a26,0x8ffa52627b2736c1, -//0x6842964f0945e30a,0x88b127aa99c5e60, -//0xc94e6a251f112672,0xd21672758d33aba, -//0x0,0x0, -//0x882e2943d5ee4534,0xc25f5e75edaa4fa9, -//0x95d3204b1d1dd922,0x39092e35de04cc32, -//0x1dfd0908c8f39c16,0xfb56704033ae839b, -//0xcb6e1a7035541fd6,0x8ab363f0b1f0f211, -//0x43403333e0ba5ae2,0x48ec3d855c5abdb8, -//0x5ebd3a3b2849c6f4,0xb3ba4dc56ff43e23, -//0xd6931378fda783c0,0x71e513b0825e718a, -//0xa1318678293664f4,0xbe1eca746232042b, -//0x291faf3bfcd821c0,0x7c4194018f984b82, -//0x34e2a633342bbdd6,0x8717e441bc36c819, -//0xbccc8f70e1c5f8e2,0x4548ba34519c87b0, -//0x6a5f9c081c627b22,0x34ada984d3c2f63a, -//0xe271b54bc98c3e16,0xf6f2f7f13e68b993, -//0xff8cbc43017fa200,0xda487b10dc63a08, -//0x77a29500d491e734,0xcffbd9c4e06c75a1, -//0x0,0x0, -//0xe684ecc9b397a5fe,0xb3b2d35103f1a3ed, -//0x6da6f30e41a8edf0,0x34b0cc6ccf4ee620, -//0x8b221fc7f23f480e,0x87021f3dccbf45cd, -//0xacd605531d728f16,0xa6af6a59808b2143, -//0x4a52e99aaee52ae8,0x151db908837a82ae, -//0xc170f65d5cda62e6,0x921fa6354fc5c763, -//0x27f41a94ef4dc718,0x21ad75644c34648e, -//0x36771e3ca90ca14,0x3555819a552c1192, -//0xe5e39d2a79076fea,0x86e752cb56ddb27f, -//0x6ec182ed8b3827e4,0x1e54df69a62f7b2, -//0x88456e2438af821a,0xb2579ea79993545f, -//0xafb174b0d7e24502,0x93faebc3d5a730d1, -//0x493598796475e0fc,0x20483892d656933c, -//0xc21787be964aa8f2,0xa74a27af1ae9d6f1, -//0x24936b7725dd0d0c,0x14f8f4fe1918751c, -//0x0,0x0, -//0xc6c1932eeb78b72a,0xeabea114c8ae9a9f, -//0xfc5874dd3b9425ce,0x1988519c2a18a57c, -//0x3a99e7f3d0ec92e4,0xf336f088e2b63fe3, -//0x70ec558472062c44,0x60abfabc33f697de, -//0xb62dc6aa997e9b6e,0x8a155ba8fb580d41, -//0x8cb421594992098a,0x7923ab2019ee32a2, -//0x4a75b277a2eabea0,0x939d0a34d140a83d, -//0xa9e47128863ba654,0xdf68fe1cdf73f30, -//0x6f25e2066d43117e,0xe7482ef50559a5af, -//0x55bc05f5bdaf839a,0x147ede7de7ef9a4c, -//0x937d96db56d734b0,0xfec07f692f4100d3, -//0xd90824acf43d8a10,0x6d5d755dfe01a8ee, -//0x1fc9b7821f453d3a,0x87e3d44936af3271, -//0x25505071cfa9afde,0x74d524c1d4190d92, -//0xe391c35f24d118f4,0x9e6b85d51cb7970d, -//0x0,0x0, -//0x8b6f419ea9e92f64,0x87506cbe98650ee9, -//0xae03a86096676122,0xbb5791719ba8f14f, -//0x256ce9fe3f8e4e46,0x3c07fdcf03cdffa6, -//0xba49ef0905bed85a,0x9ae42542db02833b, -//0x3126ae97ac57f73e,0x1db449fc43678dd2, -//0x144a476993d9b978,0x21b3b43340aa7274, -//0x9f2506f73a30961c,0xa6e3d88dd8cf7c9d, -//0x997880bebf7eb61c,0xf29856ca664755b9, -//0x1217c12016979978,0x75c83a74fe225b50, -//0x377b28de2919d73e,0x49cfc7bbfdefa4f6, -//0xbc14694080f0f85a,0xce9fab05658aaa1f, -//0x23316fb7bac06e46,0x687c7388bd45d682, -//0xa85e2e2913294122,0xef2c1f362520d86b, -//0x8d32c7d72ca70f64,0xd32be2f926ed27cd, -//0x65d8649854e2000,0x547b8e47be882924, -//0x0,0x0, -//0x16cb3187d20086c,0x9e37d35816d18239, -//0x248c663b21703abe,0x71815387f77f4dbc, -//0x25e0d5235c5032d2,0xefb680dfe1aecf85, -//0x143024f5848f1090,0xa6d469fdbe031ab9, -//0x155c97edf9af18fc,0x38e3baa5a8d29880, -//0x30bc42cea5ff2a2e,0xd7553a7a497c5705, -//0x31d0f1d6d8df2242,0x4962e9225fadd53c, -//0x790935af79870be0,0x1d83ab0444495694, -//0x786586b704a7038c,0x83b4785c5298d4ad, -//0x5d85539458f7315e,0x6c02f883b3361b28, -//0x5ce9e08c25d73932,0xf2352bdba5e79911, -//0x6d39115afd081b70,0xbb57c2f9fa4a4c2d, -//0x6c55a2428028131c,0x256011a1ec9bce14, -//0x49b57761dc7821ce,0xcad6917e0d350191, -//0x48d9c479a15829a2,0x54e142261be483a8, -//0x0,0x0, -//0xbe2444c534740484,0xcbaf5837829b974f, -//0x5efc7f3aa24d39ca,0xf36a42b3e5f1cbbb, -//0xe0d83bff96393d4e,0x38c51a84676a5cf4, -//0x92372db327a9d5ee,0x1cf5645b85d85ac4, -//0x2c13697613ddd16a,0xd75a3c6c0743cd8b, -//0xcccb528985e4ec24,0xef9f26e86029917f, -//0x72ef164cb190e8a0,0x24307edfe2b20630, -//0xd48cd14917a38034,0xe374c7526e3abf93, -//0x6aa8958c23d784b0,0x28db9f65eca128dc, -//0x8a70ae73b5eeb9fe,0x101e85e18bcb7428, -//0x3454eab6819abd7a,0xdbb1ddd60950e367, -//0x46bbfcfa300a55da,0xff81a309ebe2e557, -//0xf89fb83f047e515e,0x342efb3e69797218, -//0x184783c092476c10,0xcebe1ba0e132eec, -//0xa663c705a6336894,0xc744b98d8c88b9a3, -//0x0,0x0, -//0x2490765a301e28c2,0xb608a7b1ade6f573, -//0xaa56dfd514863cf6,0x9ec927e0ea730849, -//0x8ec6a98f24981434,0x28c180514795fd3a, -//0xb493920663b35d20,0xf2eee16207fa6641, -//0x9003e45c53ad75e2,0x44e646d3aa1c9332, -//0x1ec54dd3773561d6,0x6c27c682ed896e08, -//0x3a553b89472b4914,0xda2f6133406f9b7b, -//0x9b78c9542bba3a2e,0x79c54cdd0e226966, -//0xbfe8bf0e1ba412ec,0xcfcdeb6ca3c49c15, -//0x312e16813f3c06d8,0xe70c6b3de451612f, -//0x15be60db0f222e1a,0x5104cc8c49b7945c, -//0x2feb5b524809670e,0x8b2badbf09d80f27, -//0xb7b2d0878174fcc,0x3d230a0ea43efa54, -//0x85bd84875c8f5bf8,0x15e28a5fe3ab076e, -//0xa12df2dd6c91733a,0xa3ea2dee4e4df21d, -//0x0,0x0, -//0x456895c1d95fe234,0xee72b1a21497e77b, -//0x4eb77b48cc5f7038,0x9ad3c105b155ffef, -//0xbdfee891500920c,0x74a170a7a5c21894, -//0x68f65fa05931208c,0x585b4042d008c9da, -//0x2d9eca61806ec2b8,0xb629f1e0c49f2ea1, -//0x264124e8956e50b4,0xc2888147615d3635, -//0x6329b1294c31b280,0x2cfa30e575cad14e, -//0x16dde2bb2b38dcfa,0xaeca82ee463b0b3b, -//0x53b5777af2673ece,0x40b8334c52acec40, -//0x586a99f3e767acc2,0x341943ebf76ef4d4, -//0x1d020c323e384ef6,0xda6bf249e3f913af, -//0x7e2bbd1b7209fc76,0xf691c2ac9633c2e1, -//0x3b4328daab561e42,0x18e3730e82a4259a, -//0x309cc653be568c4e,0x6c4203a927663d0e, -//0x75f4539267096e7a,0x8230b20b33f1da75, -//0x0,0x0, -//0x3904c8d2f5c3d2d6,0x54d2b7c147b9eab0, -//0x8b1c8bd76f237756,0x4d81761ce690153e, -//0xb21843059ae0a580,0x1953c1dda129ff8e, -//0x8a2133f2160fc5ec,0x614a21c3ff3bf28a, -//0xb325fb20e3cc173a,0x35989602b882183a, -//0x13db825792cb2ba,0x2ccb57df19abe7b4, -//0x383970f78cef606c,0x7819e01e5e120d04, -//0x4b053b0413b7ed2a,0xa7cdb8c6809748d7, -//0x7201f3d6e6743ffc,0xf31f0f07c72ea267, -//0xc019b0d37c949a7c,0xea4cceda66075de9, -//0xf91d7801895748aa,0xbe9e791b21beb759, -//0xc12408f605b828c6,0xc68799057facba5d, -//0xf820c024f07bfa10,0x92552ec4381550ed, -//0x4a3883216a9b5f90,0x8b06ef19993caf63, -//0x733c4bf39f588d46,0xdfd458d8de8545d3, -//0x0,0x0, -//0x14e4307f9d1772b6,0x515219ca23f9ce5c, -//0x511e34506522e6ae,0x8247627f48ff1f7f, -//0x45fa042ff8359418,0xd3157bb56b06d123, -//0xe3a3756c6efacfc4,0xf788c793e7244e9f, -//0xf7474513f3edbd72,0xa6dade59c4dd80c3, -//0xb2bd413c0bd8296a,0x75cfa5ecafdb51e0, -//0xa659714396cf5bdc,0x249dbc268c229fbc, -//0x5a70839fc81fb4c0,0xd35f0eb88cae752b, -//0x4e94b3e05508c676,0x820d1772af57bb77, -//0xb6eb7cfad3d526e,0x51186cc7c4516a54, -//0x1f8a87b0302a20d8,0x4a750de7a8a408, -//0xb9d3f6f3a6e57b04,0x24d7c92b6b8a3bb4, -//0xad37c68c3bf209b2,0x7585d0e14873f5e8, -//0xe8cdc2a3c3c79daa,0xa690ab54237524cb, -//0xfc29f2dc5ed0ef1c,0xf7c2b29e008cea97, -//0x0,0x0, -//0xda8e23483a97853a,0x38f065e6ec77c32c, -//0xd1700ce51721220c,0xee558f30070e0c3d, -//0xbfe2fad2db6a736,0xd6a5ead6eb79cf11, -//0x249484a90e31ef88,0xd78f250953e96933, -//0xfe1aa7e134a66ab2,0xef7f40efbf9eaa1f, -//0xf5e4884c1910cd84,0x39daaa3954e7650e, -//0x2f6aab04238748be,0x12acfdfb890a622, -//0x771a1494d77054ac,0xde34b71e0312848f, -//0xad9437dcede7d196,0xe6c4d2f8ef6547a3, -//0xa66a1871c05176a0,0x3061382e041c88b2, -//0x7ce43b39fac6f39a,0x8915dc8e86b4b9e, -//0x538e903dd941bb24,0x9bb921750fbedbc, -//0x8900b375e3d63e1e,0x314bf7f1bc8c2e90, -//0x82fe9cd8ce609928,0xe7ee1d2757f5e181, -//0x5870bf90f4f71c12,0xdf1e78c1bb8222ad, -//0x0,0x0, -//0x27f349141093e620,0x97e14e9448decae7, -//0x8da828e52be94d70,0x928de3c8e22c0f1d, -//0xaa5b61f13b7aab50,0x56cad5caaf2c5fa, -//0xc1e9db8ac9f1c256,0xba586143dfe63deb, -//0xe61a929ed9622476,0x2db92fd79738f70c, -//0x4c41f36fe2188f26,0x28d5828b3dca32f6, -//0x6bb2ba7bf28b6906,0xbf34cc1f7514f811, -//0xd9b45813424b2b38,0xb2052ca6fb35eaa9, -//0xfe47110752d8cd18,0x25e46232b3eb204e, -//0x541c70f669a26648,0x2088cf6e1919e5b4, -//0x73ef39e279318068,0xb76981fa51c72f53, -//0x185d83998bbae96e,0x85d4de524d3d742, -//0x3faeca8d9b290f4e,0x9fbc03716c0d1da5, -//0x95f5ab7ca053a41e,0x9ad0ae2dc6ffd85f, -//0xb206e268b0c0423e,0xd31e0b98e2112b8, -//0x0,0x0, -//0x10f28ab6172a4efa,0x794a2a7c84a76d2c, -//0x213491af2f858c38,0xa3fb2735d34fbaa7, -//0x31c61b1938afc2c2,0xdab10d4957e8d78b, -//0xdd93cc151a20dcda,0xfa7ca4a3574c6525, -//0xcd6146a30d0a9220,0x83368edfd3eb0809, -//0xfca75dba35a550e2,0x598783968403df82, -//0xec55d70c228f1e18,0x20cda9ea00a4b2ae, -//0x3190a2225ab65e2c,0xff5e390da90f4835, -//0x216228944d9c10d6,0x861413712da82519, -//0x10a4338d7533d214,0x5ca51e387a40f292, -//0x56b93b62199cee,0x25ef3444fee79fbe, -//0xec036e37409682f6,0x5229daefe432d10, -//0xfcf1e48157bccc0c,0x7c68b7d27ae4403c, -//0xcd37ff986f130ece,0xa6d9ba9b2d0c97b7, -//0xddc5752e78394034,0xdf9390e7a9abfa9b, -//0x0,0x0, -//0x71389b2a8246f5e4,0xd79573b001f21771, -//0x6ae0532ae2bbfb90,0xdfd3122b95e92c4f, -//0x1bd8c80060fd0e74,0x846619b941b3b3e, -//0xcd6b22d4c21c7758,0x59ee81e35141d3cc, -//0xbc53b9fe405a82bc,0x8e7bf25350b3c4bd, -//0xa78b71fe20a78cc8,0x863d93c8c4a8ff83, -//0xd6b3ead4a2e1792c,0x51a8e078c55ae8f2, -//0x85e338536eb1bbc,0xca785a7f809253d7, -//0x7966a8afb4adee58,0x1ded29cf816044a6, -//0x62be60afd450e02c,0x15ab4854157b7f98, -//0x1386fb85561615c8,0xc23e3be4148968e9, -//0xc5351151f4f76ce4,0x9396db9cd1d3801b, -//0xb40d8a7b76b19900,0x4403a82cd021976a, -//0xafd5427b164c9774,0x4c45c9b7443aac54, -//0xdeedd951940a6290,0x9bd0ba0745c8bb25, -//0x0,0x0, -//0xa602f3fd08bbca2a,0x3cf77b9a1ded625a, -//0x9cfb59155f2c296a,0xc74456a7f1e3b58b, -//0x3af9aae85797e340,0xfbb32d3dec0ed7d1, -//0xbc92de7f7ebfd6c4,0x38ff17882d7d411c, -//0x1a902d8276041cee,0x4086c1230902346, -//0x2069876a2193ffae,0xffbb412fdc9ef497, -//0x866b749729283584,0xc34c3ab5c17396cd, -//0x49dd31700df81d26,0x6daab92652394278, -//0xefdfc28d0543d70c,0x515dc2bc4fd42022, -//0xd526686552d4344c,0xaaeeef81a3daf7f3, -//0x73249b985a6ffe66,0x9619941bbe3795a9, -//0xf54fef0f7347cbe2,0x5555aeae7f440364, -//0x534d1cf27bfc01c8,0x69a2d53462a9613e, -//0x69b4b61a2c6be288,0x9211f8098ea7b6ef, -//0xcfb645e724d028a2,0xaee68393934ad4b5, -//0x0,0x0, -//0x3b8f902c0a858e4e,0x8b95b6a7427690cb, -//0xd525a8185f8af324,0xf31f1e9daabbff9f, -//0xeeaa3834550f7d6a,0x788aa83ae8cd6f54, -//0x17f87f09bc736f26,0xfafd49e2ee8251e9, -//0x2c77ef25b6f6e168,0x7168ff45acf4c122, -//0xc2ddd711e3f99c02,0x9e2577f4439ae76, -//0xf952473de97c124c,0x8277e1d8064f3ebd, -//0xae5fb3551c95931e,0x1863362e3ae97756, -//0x95d0237916101d50,0x93f68089789fe79d, -//0x7b7a1b4d431f603a,0xeb7c28b3905288c9, -//0x40f58b61499aee74,0x60e99e14d2241802, -//0xb9a7cc5ca0e6fc38,0xe29e7fccd46b26bf, -//0x82285c70aa637276,0x690bc96b961db674, -//0x6c826444ff6c0f1c,0x118161517ed0d920, -//0x570df468f5e98152,0x9a14d7f63ca649eb, -//0x0,0x0, -//0x9b8f8f876479058e,0xcad343e8080cba83, -//0x51bbcc440c472768,0xf2e5a279864a60f5, -//0xca3443c3683e22e6,0x3836e1918e46da76, -//0x6340402c3f7ffebe,0xb70b9103d1cd6617, -//0xf8cfcfab5b06fb30,0x7dd8d2ebd9c1dc94, -//0x32fb8c683338d9d6,0x45ee337a578706e2, -//0xa97403ef5741dc58,0x8f3d70925f8bbc61, -//0xdeb9ef235f15ff90,0xb7959b94e1e22d49, -//0x453660a43b6cfa1e,0x7d46d87ce9ee97ca, -//0x8f0223675352d8f8,0x457039ed67a84dbc, -//0x148dace0372bdd76,0x8fa37a056fa4f73f, -//0xbdf9af0f606a012e,0x9e0a97302f4b5e, -//0x26762088041304a0,0xca4d497f3823f1dd, -//0xec42634b6c2d2646,0xf27ba8eeb6652bab, -//0x77cdeccc085423c8,0x38a8eb06be699128, -//0x0,0x0, -//0x5a9d3675a3531196,0x3524ce9c7f7b56e2, -//0xce10620e568164c2,0x8ef7ee5cecdb882d, -//0x948d547bf5d27554,0xbbd320c093a0decf, -//0x854d0fea22c345b2,0xda3844c594d764bf, -//0xdfd0399f81905424,0xef1c8a59ebac325d, -//0x4b5d6de474422170,0x54cfaa99780cec92, -//0x11c05b91d71130e6,0x61eb64050777ba70, -//0x16c016c2d631ae74,0xf2328df87cdf3e71, -//0x4c5d20b77562bfe2,0xc716436403a46893, -//0xd8d074cc80b0cab6,0x7cc563a49004b65c, -//0x824d42b923e3db20,0x49e1ad38ef7fe0be, -//0x938d1928f4f2ebc6,0x280ac93de8085ace, -//0xc9102f5d57a1fa50,0x1d2e07a197730c2c, -//0x5d9d7b26a2738f04,0xa6fd276104d3d2e3, -//0x7004d5301209e92,0x93d9e9fd7ba88401, -//0x0,0x0, -//0x3a9122c15f3ab78,0x9eb8b35a2448eeff, -//0x4ac1ab2d94aa463e,0x3c449b0a0456c972, -//0x4968b9018159ed46,0xa2fc2850201e278d, -//0x70d846ae38ffb938,0x6cddd4542b3a7254, -//0x737154822d0c1240,0xf265670e0f729cab, -//0x3a19ed83ac55ff06,0x50994f5e2f6cbb26, -//0x39b0ffafb9a6547e,0xce21fc040b2455d9, -//0x3f1ab33bdd022656,0xee26c355dcac88cf, -//0x3cb3a117c8f18d2e,0x709e700ff8e46630, -//0x75db181649a86068,0xd262585fd8fa41bd, -//0x76720a3a5c5bcb10,0x4cdaeb05fcb2af42, -//0x4fc2f595e5fd9f6e,0x82fb1701f796fa9b, -//0x4c6be7b9f00e3416,0x1c43a45bd3de1464, -//0x5035eb87157d950,0xbebf8c0bf3c033e9, -//0x6aa4c9464a47228,0x20073f51d788dd16, -//0x0,0x0, -//0xa2def1742f3b5916,0x55fe928ccc907446, -//0xc0536b0be526eb6,0xce0290a08ea7ed67, -//0xaedbc7c4916937a0,0x9bfc022c42379921, -//0x63118f8310afbd9c,0xf3bfe1a1625671ef, -//0xc1cf7ef73f94e48a,0xa641732daec605a9, -//0x6f14b933aefdd32a,0x3dbd7101ecf19c88, -//0xcdca484781c68a3c,0x6843e38d2061e8ce, -//0x5c5ad70dd7f32ae,0xfbdcaf23d12e7a5d, -//0xa71b5c04f2446bb8,0xae223daf1dbe0e1b, -//0x9c09bc0632d5c18,0x35de3f835f89973a, -//0xab1e6ab44c16050e,0x6020ad0f9319e37c, -//0x66d422f3cdd08f32,0x8634e82b3780bb2, -//0xc40ad387e2ebd624,0x5d9ddc0e7fe87ff4, -//0x6ad114437382e184,0xc661de223ddfe6d5, -//0xc80fe5375cb9b892,0x939f4caef14f9293, -//0x0,0x0, -//0x2cd73c266f68da36,0x9bfcfcadd6ed8b57, -//0x6d8e1fe42b061d44,0x3db9c6976df592a6, -//0x415923c2446ec772,0xa6453a3abb1819f1, -//0x80ca05549a4dc27c,0xc75a42071ff8895d, -//0xac1d3972f525184a,0x5ca6beaac915020a, -//0xed441ab0b14bdf38,0xfae38490720d1bfb, -//0xc1932696de23050e,0x611f783da4e090ac, -//0xd1fbff53b9e5b9a0,0x11f736abdbe2672a, -//0xfd2cc375d68d6396,0x8a0bca060d0fec7d, -//0xbc75e0b792e3a4e4,0x2c4ef03cb617f58c, -//0x90a2dc91fd8b7ed2,0xb7b20c9160fa7edb, -//0x5131fa0723a87bdc,0xd6ad74acc41aee77, -//0x7de6c6214cc0a1ea,0x4d51880112f76520, -//0x3cbfe5e308ae6698,0xeb14b23ba9ef7cd1, -//0x1068d9c567c6bcae,0x70e84e967f02f786, -//0x0,0x0, -//0xc1ca004429d1c70c,0x83670004dbe27f63, -//0x7ade7ba41da719e2,0x75ff5173392ad2ea, -//0xbb147be03476deee,0xf6985177e2c8ad89, -//0x2da0b1432202bae2,0xc33784b9b478b88b, -//0xec6ab1070bd37dee,0x405084bd6f9ac7e8, -//0x577ecae73fa5a300,0xb6c8d5ca8d526a61, -//0x96b4caa31674640c,0x35afd5ce56b01502, -//0x88cc8045cdff4040,0x39324dfdad64aa8e, -//0x49068001e42e874c,0xba554df97686d5ed, -//0xf212fbe1d05859a2,0x4ccd1c8e944e7864, -//0x33d8fba5f9899eae,0xcfaa1c8a4fac0707, -//0xa56c3106effdfaa2,0xfa05c944191c1205, -//0x64a63142c62c3dae,0x7962c940c2fe6d66, -//0xdfb24aa2f25ae340,0x8ffa98372036c0ef, -//0x1e784ae6db8b244c,0xc9d9833fbd4bf8c, -//0x0,0x0, -//0xd1537109b42cc8a0,0x8b6232e621520ca1, -//0xc5585ec70c29b8f0,0x961f8facdb0ea92d, -//0x140b2fceb8057050,0x1d7dbd4afa5ca58c, -//0x641e0bbe37274246,0x38e42a8ae4b60f8e, -//0xb54d7ab7830b8ae6,0xb386186cc5e4032f, -//0xa14655793b0efab6,0xaefba5263fb8a6a3, -//0x701524708f223216,0x259997c01eeaaa02, -//0xb1f69a8517d41456,0xc70e543a5a80f74b, -//0x60a5eb8ca3f8dcf6,0x4c6c66dc7bd2fbea, -//0x74aec4421bfdaca6,0x5111db96818e5e66, -//0xa5fdb54bafd16406,0xda73e970a0dc52c7, -//0xd5e8913b20f35610,0xffea7eb0be36f8c5, -//0x4bbe03294df9eb0,0x74884c569f64f464, -//0x10b0cffc2cdaeee0,0x69f5f11c653851e8, -//0xc1e3bef598f62640,0xe297c3fa446a5d49, -//0x0,0x0, -//0xbccf8ca839bfe3a8,0x38bd7652fbb4463c, -//0xc4fab69066e3433a,0xefa5f7ca9f6294c1, -//0x78353a385f5ca092,0xd718819864d6d2fd, -//0xb54afad4cd1155a8,0x31317c030896c74a, -//0x985767cf4aeb600,0x98c0a51f3228176, -//0x71b04c44abf21692,0xde948bc997f4538b, -//0xcd7fc0ec924df53a,0xe629fd9b6c4015b7, -//0x7d4bba2cbae355d4,0xd5fb04e16da98b6, -//0xc1843684835cb67c,0x35e2c61ced6ede8a, -//0xb9b10cbcdc0016ee,0xe2fa478489b80c77, -//0x57e8014e5bff546,0xda4731d6720c4a4b, -//0xc80140f877f2007c,0x3c6ecc4d1e4c5ffc, -//0x74cecc504e4de3d4,0x4d3ba1fe5f819c0, -//0xcfbf66811114346,0xd3cb3b87812ecb3d, -//0xb0347ac028aea0ee,0xeb764dd57a9a8d01, -//0x0,0x0, -//0xfd2b185552fcca1e,0xaf27a2c3c9af3b15, -//0xa74e3032c1c70940,0xb22c87060644347d, -//0x5a652867933bc35e,0x1d0b25c5cfeb0f68, -//0x96784c18fa9a222c,0x9f1317dd9bd62b2b, -//0x6b53544da866e832,0x3034b51e5279103e, -//0x31367c2a3b5d2b6c,0x2d3f90db9d921f56, -//0xcc1d647f69a1e172,0x82183218543d2443, -//0xa055412a1255732c,0x9675e5102f20a86d, -//0x5d7e597f40a9b932,0x395247d3e68f9378, -//0x71b7118d3927a6c,0x2459621629649c10, -//0xfa30694d816eb072,0x8b7ec0d5e0cba705, -//0x362d0d32e8cf5100,0x966f2cdb4f68346, -//0xcb061567ba339b1e,0xa641500e7d59b853, -//0x91633d0029085840,0xbb4a75cbb2b2b73b, -//0x6c4825557bf4925e,0x146dd7087b1d8c2e, -//0x0,0x0, -//0xbd9e54181b305f0,0x1196f9167176350a, -//0x2de9c7568ec18048,0x4c7d6f6a66426bc8, -//0x263022170f7285b8,0x5deb967c17345ec2, -//0xf69478d0555733be,0x2cf2076679e35cae, -//0xfd4d9d91d4e4364e,0x3d64fe70089569a4, -//0xdb7dbf86db96b3f6,0x608f680c1fa13766, -//0xd0a45ac75a25b606,0x7119911a6ed7026c, -//0xa0dea3eaee857928,0xeff27f24fdcf1cb1, -//0xab0746ab6f367cd8,0xfe6486328cb929bb, -//0x8d3764bc6044f960,0xa38f104e9b8d7779, -//0x86ee81fde1f7fc90,0xb219e958eafb4273, -//0x564adb3abbd24a96,0xc3007842842c401f, -//0x5d933e7b3a614f66,0xd2968154f55a7515, -//0x7ba31c6c3513cade,0x8f7d1728e26e2bd7, -//0x707af92db4a0cf2e,0x9eebee3e93181edd, -//0x0,0x0, -//0x22de535186312472,0xb2c39cca82539e4d, -//0x1c881e66c80d1a94,0x79ffdc889d966bb8, -//0x3e564d374e3c3ee6,0xcb3c40421fc5f5f5, -//0x34209cfccf813712,0xa2dacc7d457cfcd7, -//0x16fecfad49b01360,0x101950b7c72f629a, -//0x28a8829a078c2d86,0xdb2510f5d8ea976f, -//0xa76d1cb81bd09f4,0x69e68c3f5ab90922, -//0xdbfa17232ffaa1aa,0x9d8978748ea31b83, -//0xf9244472a9cb85d8,0x2f4ae4be0cf085ce, -//0xc7720945e7f7bb3e,0xe476a4fc1335703b, -//0xe5ac5a1461c69f4c,0x56b538369166ee76, -//0xefda8bdfe07b96b8,0x3f53b409cbdfe754, -//0xcd04d88e664ab2ca,0x8d9028c3498c7919, -//0xf35295b928768c2c,0x46ac688156498cec, -//0xd18cc6e8ae47a85e,0xf46ff44bd41a12a1, -//}; -// -// - - -alignas(32) const uint64_t gfCantorto2128_8R[2*(8*256)] = { -0x0,0x0, -0x1,0x0, -0x676aac9fa4b20b08,0x295ac0b1f4731af9, -0x676aac9fa4b20b09,0x295ac0b1f4731af9, -0xff1099c31bbe8f22,0xa2134422cd4054c9, -0xff1099c31bbe8f23,0xa2134422cd4054c9, -0x987a355cbf0c842a,0x8b49849339334e30, -0x987a355cbf0c842b,0x8b49849339334e30, -0x53b85b6402b1e848,0x7959d70ce1ee6942, -0x53b85b6402b1e849,0x7959d70ce1ee6942, -0x34d2f7fba603e340,0x500317bd159d73bb, -0x34d2f7fba603e341,0x500317bd159d73bb, -0xaca8c2a7190f676a,0xdb4a932e2cae3d8b, -0xaca8c2a7190f676b,0xdb4a932e2cae3d8b, -0xcbc26e38bdbd6c62,0xf210539fd8dd2772, -0xcbc26e38bdbd6c63,0xf210539fd8dd2772, -0xcabcd8e4694e5644,0x8f6b313e935b8e2, -0xcabcd8e4694e5645,0x8f6b313e935b8e2, -0xadd6747bcdfc5d4c,0x21ac73a21d46a21b, -0xadd6747bcdfc5d4d,0x21ac73a21d46a21b, -0x35ac412772f0d966,0xaae5f7312475ec2b, -0x35ac412772f0d967,0xaae5f7312475ec2b, -0x52c6edb8d642d26e,0x83bf3780d006f6d2, -0x52c6edb8d642d26f,0x83bf3780d006f6d2, -0x990483806bffbe0c,0x71af641f08dbd1a0, -0x990483806bffbe0d,0x71af641f08dbd1a0, -0xfe6e2f1fcf4db504,0x58f5a4aefca8cb59, -0xfe6e2f1fcf4db505,0x58f5a4aefca8cb59, -0x66141a437041312e,0xd3bc203dc59b8569, -0x66141a437041312f,0xd3bc203dc59b8569, -0x17eb6dcd4f33a26,0xfae6e08c31e89f90, -0x17eb6dcd4f33a27,0xfae6e08c31e89f90, -0x4d48b16661e860ec,0x49c9321635282198, -0x4d48b16661e860ed,0x49c9321635282198, -0x2a221df9c55a6be4,0x6093f2a7c15b3b61, -0x2a221df9c55a6be5,0x6093f2a7c15b3b61, -0xb25828a57a56efce,0xebda7634f8687551, -0xb25828a57a56efcf,0xebda7634f8687551, -0xd532843adee4e4c6,0xc280b6850c1b6fa8, -0xd532843adee4e4c7,0xc280b6850c1b6fa8, -0x1ef0ea02635988a4,0x3090e51ad4c648da, -0x1ef0ea02635988a5,0x3090e51ad4c648da, -0x799a469dc7eb83ac,0x19ca25ab20b55223, -0x799a469dc7eb83ad,0x19ca25ab20b55223, -0xe1e073c178e70786,0x9283a13819861c13, -0xe1e073c178e70787,0x9283a13819861c13, -0x868adf5edc550c8e,0xbbd96189edf506ea, -0x868adf5edc550c8f,0xbbd96189edf506ea, -0x87f4698208a636a8,0x413f8105dc1d997a, -0x87f4698208a636a9,0x413f8105dc1d997a, -0xe09ec51dac143da0,0x686541b4286e8383, -0xe09ec51dac143da1,0x686541b4286e8383, -0x78e4f0411318b98a,0xe32cc527115dcdb3, -0x78e4f0411318b98b,0xe32cc527115dcdb3, -0x1f8e5cdeb7aab282,0xca760596e52ed74a, -0x1f8e5cdeb7aab283,0xca760596e52ed74a, -0xd44c32e60a17dee0,0x386656093df3f038, -0xd44c32e60a17dee1,0x386656093df3f038, -0xb3269e79aea5d5e8,0x113c96b8c980eac1, -0xb3269e79aea5d5e9,0x113c96b8c980eac1, -0x2b5cab2511a951c2,0x9a75122bf0b3a4f1, -0x2b5cab2511a951c3,0x9a75122bf0b3a4f1, -0x4c3607bab51b5aca,0xb32fd29a04c0be08, -0x4c3607bab51b5acb,0xb32fd29a04c0be08, -0xa13fe8ac5560ce0c,0x53d8555a9979a1c, -0xa13fe8ac5560ce0d,0x53d8555a9979a1c, -0xc6554433f1d2c504,0x2c6745e45de480e5, -0xc6554433f1d2c505,0x2c6745e45de480e5, -0x5e2f716f4ede412e,0xa72ec17764d7ced5, -0x5e2f716f4ede412f,0xa72ec17764d7ced5, -0x3945ddf0ea6c4a26,0x8e7401c690a4d42c, -0x3945ddf0ea6c4a27,0x8e7401c690a4d42c, -0xf287b3c857d12644,0x7c6452594879f35e, -0xf287b3c857d12645,0x7c6452594879f35e, -0x95ed1f57f3632d4c,0x553e92e8bc0ae9a7, -0x95ed1f57f3632d4d,0x553e92e8bc0ae9a7, -0xd972a0b4c6fa966,0xde77167b8539a797, -0xd972a0b4c6fa967,0xde77167b8539a797, -0x6afd8694e8dda26e,0xf72dd6ca714abd6e, -0x6afd8694e8dda26f,0xf72dd6ca714abd6e, -0x6b8330483c2e9848,0xdcb364640a222fe, -0x6b8330483c2e9849,0xdcb364640a222fe, -0xce99cd7989c9340,0x2491f6f7b4d13807, -0xce99cd7989c9341,0x2491f6f7b4d13807, -0x9493a98b2790176a,0xafd872648de27637, -0x9493a98b2790176b,0xafd872648de27637, -0xf3f9051483221c62,0x8682b2d579916cce, -0xf3f9051483221c63,0x8682b2d579916cce, -0x383b6b2c3e9f7000,0x7492e14aa14c4bbc, -0x383b6b2c3e9f7001,0x7492e14aa14c4bbc, -0x5f51c7b39a2d7b08,0x5dc821fb553f5145, -0x5f51c7b39a2d7b09,0x5dc821fb553f5145, -0xc72bf2ef2521ff22,0xd681a5686c0c1f75, -0xc72bf2ef2521ff23,0xd681a5686c0c1f75, -0xa0415e708193f42a,0xffdb65d9987f058c, -0xa0415e708193f42b,0xffdb65d9987f058c, -0xec7759ca3488aee0,0x4cf4b7439cbfbb84, -0xec7759ca3488aee1,0x4cf4b7439cbfbb84, -0x8b1df555903aa5e8,0x65ae77f268cca17d, -0x8b1df555903aa5e9,0x65ae77f268cca17d, -0x1367c0092f3621c2,0xeee7f36151ffef4d, -0x1367c0092f3621c3,0xeee7f36151ffef4d, -0x740d6c968b842aca,0xc7bd33d0a58cf5b4, -0x740d6c968b842acb,0xc7bd33d0a58cf5b4, -0xbfcf02ae363946a8,0x35ad604f7d51d2c6, -0xbfcf02ae363946a9,0x35ad604f7d51d2c6, -0xd8a5ae31928b4da0,0x1cf7a0fe8922c83f, -0xd8a5ae31928b4da1,0x1cf7a0fe8922c83f, -0x40df9b6d2d87c98a,0x97be246db011860f, -0x40df9b6d2d87c98b,0x97be246db011860f, -0x27b537f28935c282,0xbee4e4dc44629cf6, -0x27b537f28935c283,0xbee4e4dc44629cf6, -0x26cb812e5dc6f8a4,0x44020450758a0366, -0x26cb812e5dc6f8a5,0x44020450758a0366, -0x41a12db1f974f3ac,0x6d58c4e181f9199f, -0x41a12db1f974f3ad,0x6d58c4e181f9199f, -0xd9db18ed46787786,0xe6114072b8ca57af, -0xd9db18ed46787787,0xe6114072b8ca57af, -0xbeb1b472e2ca7c8e,0xcf4b80c34cb94d56, -0xbeb1b472e2ca7c8f,0xcf4b80c34cb94d56, -0x7573da4a5f7710ec,0x3d5bd35c94646a24, -0x7573da4a5f7710ed,0x3d5bd35c94646a24, -0x121976d5fbc51be4,0x140113ed601770dd, -0x121976d5fbc51be5,0x140113ed601770dd, -0x8a63438944c99fce,0x9f48977e59243eed, -0x8a63438944c99fcf,0x9f48977e59243eed, -0xed09ef16e07b94c6,0xb61257cfad572414, -0xed09ef16e07b94c7,0xb61257cfad572414, -0x5cb10fbabcf00118,0x4d52354a3a3d8c86, -0x5cb10fbabcf00119,0x4d52354a3a3d8c86, -0x3bdba32518420a10,0x6408f5fbce4e967f, -0x3bdba32518420a11,0x6408f5fbce4e967f, -0xa3a19679a74e8e3a,0xef417168f77dd84f, -0xa3a19679a74e8e3b,0xef417168f77dd84f, -0xc4cb3ae603fc8532,0xc61bb1d9030ec2b6, -0xc4cb3ae603fc8533,0xc61bb1d9030ec2b6, -0xf0954debe41e950,0x340be246dbd3e5c4, -0xf0954debe41e951,0x340be246dbd3e5c4, -0x6863f8411af3e258,0x1d5122f72fa0ff3d, -0x6863f8411af3e259,0x1d5122f72fa0ff3d, -0xf019cd1da5ff6672,0x9618a6641693b10d, -0xf019cd1da5ff6673,0x9618a6641693b10d, -0x97736182014d6d7a,0xbf4266d5e2e0abf4, -0x97736182014d6d7b,0xbf4266d5e2e0abf4, -0x960dd75ed5be575c,0x45a48659d3083464, -0x960dd75ed5be575d,0x45a48659d3083464, -0xf1677bc1710c5c54,0x6cfe46e8277b2e9d, -0xf1677bc1710c5c55,0x6cfe46e8277b2e9d, -0x691d4e9dce00d87e,0xe7b7c27b1e4860ad, -0x691d4e9dce00d87f,0xe7b7c27b1e4860ad, -0xe77e2026ab2d376,0xceed02caea3b7a54, -0xe77e2026ab2d377,0xceed02caea3b7a54, -0xc5b58c3ad70fbf14,0x3cfd515532e65d26, -0xc5b58c3ad70fbf15,0x3cfd515532e65d26, -0xa2df20a573bdb41c,0x15a791e4c69547df, -0xa2df20a573bdb41d,0x15a791e4c69547df, -0x3aa515f9ccb13036,0x9eee1577ffa609ef, -0x3aa515f9ccb13037,0x9eee1577ffa609ef, -0x5dcfb96668033b3e,0xb7b4d5c60bd51316, -0x5dcfb96668033b3f,0xb7b4d5c60bd51316, -0x11f9bedcdd1861f4,0x49b075c0f15ad1e, -0x11f9bedcdd1861f5,0x49b075c0f15ad1e, -0x7693124379aa6afc,0x2dc1c7edfb66b7e7, -0x7693124379aa6afd,0x2dc1c7edfb66b7e7, -0xeee9271fc6a6eed6,0xa688437ec255f9d7, -0xeee9271fc6a6eed7,0xa688437ec255f9d7, -0x89838b806214e5de,0x8fd283cf3626e32e, -0x89838b806214e5df,0x8fd283cf3626e32e, -0x4241e5b8dfa989bc,0x7dc2d050eefbc45c, -0x4241e5b8dfa989bd,0x7dc2d050eefbc45c, -0x252b49277b1b82b4,0x549810e11a88dea5, -0x252b49277b1b82b5,0x549810e11a88dea5, -0xbd517c7bc417069e,0xdfd1947223bb9095, -0xbd517c7bc417069f,0xdfd1947223bb9095, -0xda3bd0e460a50d96,0xf68b54c3d7c88a6c, -0xda3bd0e460a50d97,0xf68b54c3d7c88a6c, -0xdb456638b45637b0,0xc6db44fe62015fc, -0xdb456638b45637b1,0xc6db44fe62015fc, -0xbc2fcaa710e43cb8,0x253774fe12530f05, -0xbc2fcaa710e43cb9,0x253774fe12530f05, -0x2455fffbafe8b892,0xae7ef06d2b604135, -0x2455fffbafe8b893,0xae7ef06d2b604135, -0x433f53640b5ab39a,0x872430dcdf135bcc, -0x433f53640b5ab39b,0x872430dcdf135bcc, -0x88fd3d5cb6e7dff8,0x7534634307ce7cbe, -0x88fd3d5cb6e7dff9,0x7534634307ce7cbe, -0xef9791c31255d4f0,0x5c6ea3f2f3bd6647, -0xef9791c31255d4f1,0x5c6ea3f2f3bd6647, -0x77eda49fad5950da,0xd7272761ca8e2877, -0x77eda49fad5950db,0xd7272761ca8e2877, -0x1087080009eb5bd2,0xfe7de7d03efd328e, -0x1087080009eb5bd3,0xfe7de7d03efd328e, -0xfd8ee716e990cf14,0x486fb01f93aa169a, -0xfd8ee716e990cf15,0x486fb01f93aa169a, -0x9ae44b894d22c41c,0x613570ae67d90c63, -0x9ae44b894d22c41d,0x613570ae67d90c63, -0x29e7ed5f22e4036,0xea7cf43d5eea4253, -0x29e7ed5f22e4037,0xea7cf43d5eea4253, -0x65f4d24a569c4b3e,0xc326348caa9958aa, -0x65f4d24a569c4b3f,0xc326348caa9958aa, -0xae36bc72eb21275c,0x3136671372447fd8, -0xae36bc72eb21275d,0x3136671372447fd8, -0xc95c10ed4f932c54,0x186ca7a286376521, -0xc95c10ed4f932c55,0x186ca7a286376521, -0x512625b1f09fa87e,0x93252331bf042b11, -0x512625b1f09fa87f,0x93252331bf042b11, -0x364c892e542da376,0xba7fe3804b7731e8, -0x364c892e542da377,0xba7fe3804b7731e8, -0x37323ff280de9950,0x4099030c7a9fae78, -0x37323ff280de9951,0x4099030c7a9fae78, -0x5058936d246c9258,0x69c3c3bd8eecb481, -0x5058936d246c9259,0x69c3c3bd8eecb481, -0xc822a6319b601672,0xe28a472eb7dffab1, -0xc822a6319b601673,0xe28a472eb7dffab1, -0xaf480aae3fd21d7a,0xcbd0879f43ace048, -0xaf480aae3fd21d7b,0xcbd0879f43ace048, -0x648a6496826f7118,0x39c0d4009b71c73a, -0x648a6496826f7119,0x39c0d4009b71c73a, -0x3e0c80926dd7a10,0x109a14b16f02ddc3, -0x3e0c80926dd7a11,0x109a14b16f02ddc3, -0x9b9afd5599d1fe3a,0x9bd39022563193f3, -0x9b9afd5599d1fe3b,0x9bd39022563193f3, -0xfcf051ca3d63f532,0xb2895093a242890a, -0xfcf051ca3d63f533,0xb2895093a242890a, -0xb0c656708878aff8,0x1a68209a6823702, -0xb0c656708878aff9,0x1a68209a6823702, -0xd7acfaef2ccaa4f0,0x28fc42b852f12dfb, -0xd7acfaef2ccaa4f1,0x28fc42b852f12dfb, -0x4fd6cfb393c620da,0xa3b5c62b6bc263cb, -0x4fd6cfb393c620db,0xa3b5c62b6bc263cb, -0x28bc632c37742bd2,0x8aef069a9fb17932, -0x28bc632c37742bd3,0x8aef069a9fb17932, -0xe37e0d148ac947b0,0x78ff5505476c5e40, -0xe37e0d148ac947b1,0x78ff5505476c5e40, -0x8414a18b2e7b4cb8,0x51a595b4b31f44b9, -0x8414a18b2e7b4cb9,0x51a595b4b31f44b9, -0x1c6e94d79177c892,0xdaec11278a2c0a89, -0x1c6e94d79177c893,0xdaec11278a2c0a89, -0x7b04384835c5c39a,0xf3b6d1967e5f1070, -0x7b04384835c5c39b,0xf3b6d1967e5f1070, -0x7a7a8e94e136f9bc,0x950311a4fb78fe0, -0x7a7a8e94e136f9bd,0x950311a4fb78fe0, -0x1d10220b4584f2b4,0x200af1abbbc49519, -0x1d10220b4584f2b5,0x200af1abbbc49519, -0x856a1757fa88769e,0xab43753882f7db29, -0x856a1757fa88769f,0xab43753882f7db29, -0xe200bbc85e3a7d96,0x8219b5897684c1d0, -0xe200bbc85e3a7d97,0x8219b5897684c1d0, -0x29c2d5f0e38711f4,0x7009e616ae59e6a2, -0x29c2d5f0e38711f5,0x7009e616ae59e6a2, -0x4ea8796f47351afc,0x595326a75a2afc5b, -0x4ea8796f47351afd,0x595326a75a2afc5b, -0xd6d24c33f8399ed6,0xd21aa2346319b26b, -0xd6d24c33f8399ed7,0xd21aa2346319b26b, -0xb1b8e0ac5c8b95de,0xfb406285976aa892, -0xb1b8e0ac5c8b95df,0xfb406285976aa892, -0x0,0x0, -0xe18c55b8e07d3612,0x2ccae6ed8d6b4cd0, -0x588b6244c5d74470,0x210d8fbe72672c66, -0xb90737fc25aa7262,0xdc76953ff0c60b6, -0xd047dada84654da4,0xc211182c85e148b3, -0x31cb8f6264187bb6,0xeedbfec1088a0463, -0x88ccb89e41b209d4,0xe31c9792f78664d5, -0x6940ed26a1cf3fc6,0xcfd6717f7aed2805, -0xfed3b473eeb39df8,0x104d101e47f1f112, -0x1f5fe1cb0eceabea,0x3c87f6f3ca9abdc2, -0xa658d6372b64d988,0x31409fa03596dd74, -0x47d4838fcb19ef9a,0x1d8a794db8fd91a4, -0x2e946ea96ad6d05c,0xd25c0832c210b9a1, -0xcf183b118aabe64e,0xfe96eedf4f7bf571, -0x761f0cedaf01942c,0xf351878cb07795c7, -0x979359554f7ca23e,0xdf9b61613d1cd917, -0xbf199eb4f675f2ac,0xce955ea0da2a682b, -0x5e95cb0c1608c4be,0xe25fb84d574124fb, -0xe792fcf033a2b6dc,0xef98d11ea84d444d, -0x61ea948d3df80ce,0xc35237f32526089d, -0x6f5e446e7210bf08,0xc84468c5fcb2098, -0x8ed211d6926d891a,0x204ea061d2a06c48, -0x37d5262ab7c7fb78,0x2d89c9322dac0cfe, -0xd659739257bacd6a,0x1432fdfa0c7402e, -0x41ca2ac718c66f54,0xded84ebe9ddb9939, -0xa0467f7ff8bb5946,0xf212a85310b0d5e9, -0x19414883dd112b24,0xffd5c100efbcb55f, -0xf8cd1d3b3d6c1d36,0xd31f27ed62d7f98f, -0x918df01d9ca322f0,0x1cc95692183ad18a, -0x7001a5a57cde14e2,0x3003b07f95519d5a, -0xc906925959746680,0x3dc4d92c6a5dfdec, -0x288ac7e1b9095092,0x110e3fc1e736b13c, -0x19c55b8d6bef4c98,0xdbacfb2ac336178f, -0xf8490e358b927a8a,0xf7661dc74e5d5b5f, -0x414e39c9ae3808e8,0xfaa17494b1513be9, -0xa0c26c714e453efa,0xd66b92793c3a7739, -0xc9828157ef8a013c,0x19bde30646d75f3c, -0x280ed4ef0ff7372e,0x357705ebcbbc13ec, -0x9109e3132a5d454c,0x38b06cb834b0735a, -0x7085b6abca20735e,0x147a8a55b9db3f8a, -0xe716effe855cd160,0xcbe1eb3484c7e69d, -0x69aba466521e772,0xe72b0dd909acaa4d, -0xbf9d8dba408b9510,0xeaec648af6a0cafb, -0x5e11d802a0f6a302,0xc62682677bcb862b, -0x3751352401399cc4,0x9f0f3180126ae2e, -0xd6dd609ce144aad6,0x253a15f58c4de2fe, -0x6fda5760c4eed8b4,0x28fd7ca673418248, -0x8e5602d82493eea6,0x4379a4bfe2ace98, -0xa6dcc5399d9abe34,0x1539a58a191c7fa4, -0x475090817de78826,0x39f3436794773374, -0xfe57a77d584dfa44,0x34342a346b7b53c2, -0x1fdbf2c5b830cc56,0x18feccd9e6101f12, -0x769b1fe319fff390,0xd728bda69cfd3717, -0x97174a5bf982c582,0xfbe25b4b11967bc7, -0x2e107da7dc28b7e0,0xf6253218ee9a1b71, -0xcf9c281f3c5581f2,0xdaefd4f563f157a1, -0x580f714a732923cc,0x574b5945eed8eb6, -0xb98324f2935415de,0x29be5379d386c266, -0x84130eb6fe67bc,0x24793a2a2c8aa2d0, -0xe10846b6568351ae,0x8b3dcc7a1e1ee00, -0x8848ab90f74c6e68,0xc765adb8db0cc605, -0x69c4fe281731587a,0xebaf4b5556678ad5, -0xd0c3c9d4329b2a18,0xe6682206a96bea63, -0x314f9c6cd2e61c0a,0xcaa2c4eb2400a6b3, -0xf5531b28858156d0,0x58770bc4e101ab94, -0x14df4e9065fc60c2,0x74bded296c6ae744, -0xadd8796c405612a0,0x797a847a936687f2, -0x4c542cd4a02b24b2,0x55b062971e0dcb22, -0x2514c1f201e41b74,0x9a6613e864e0e327, -0xc498944ae1992d66,0xb6acf505e98baff7, -0x7d9fa3b6c4335f04,0xbb6b9c561687cf41, -0x9c13f60e244e6916,0x97a17abb9bec8391, -0xb80af5b6b32cb28,0x483a1bdaa6f05a86, -0xea0cfae38b4ffd3a,0x64f0fd372b9b1656, -0x530bcd1faee58f58,0x69379464d49776e0, -0xb28798a74e98b94a,0x45fd728959fc3a30, -0xdbc77581ef57868c,0x8a2b03f623111235, -0x3a4b20390f2ab09e,0xa6e1e51bae7a5ee5, -0x834c17c52a80c2fc,0xab268c4851763e53, -0x62c0427dcafdf4ee,0x87ec6aa5dc1d7283, -0x4a4a859c73f4a47c,0x96e255643b2bc3bf, -0xabc6d0249389926e,0xba28b389b6408f6f, -0x12c1e7d8b623e00c,0xb7efdada494cefd9, -0xf34db260565ed61e,0x9b253c37c427a309, -0x9a0d5f46f791e9d8,0x54f34d48beca8b0c, -0x7b810afe17ecdfca,0x7839aba533a1c7dc, -0xc2863d023246ada8,0x75fec2f6ccada76a, -0x230a68bad23b9bba,0x5934241b41c6ebba, -0xb49931ef9d473984,0x86af457a7cda32ad, -0x551564577d3a0f96,0xaa65a397f1b17e7d, -0xec1253ab58907df4,0xa7a2cac40ebd1ecb, -0xd9e0613b8ed4be6,0x8b682c2983d6521b, -0x64deeb3519227420,0x44be5d56f93b7a1e, -0x8552be8df95f4232,0x6874bbbb745036ce, -0x3c558971dcf53050,0x65b3d2e88b5c5678, -0xddd9dcc93c880642,0x4979340506371aa8, -0xec9640a5ee6e1a48,0x83dbf0ee2237bc1b, -0xd1a151d0e132c5a,0xaf111603af5cf0cb, -0xb41d22e12bb95e38,0xa2d67f505050907d, -0x55917759cbc4682a,0x8e1c99bddd3bdcad, -0x3cd19a7f6a0b57ec,0x41cae8c2a7d6f4a8, -0xdd5dcfc78a7661fe,0x6d000e2f2abdb878, -0x645af83bafdc139c,0x60c7677cd5b1d8ce, -0x85d6ad834fa1258e,0x4c0d819158da941e, -0x1245f4d600dd87b0,0x9396e0f065c64d09, -0xf3c9a16ee0a0b1a2,0xbf5c061de8ad01d9, -0x4ace9692c50ac3c0,0xb29b6f4e17a1616f, -0xab42c32a2577f5d2,0x9e5189a39aca2dbf, -0xc2022e0c84b8ca14,0x5187f8dce02705ba, -0x238e7bb464c5fc06,0x7d4d1e316d4c496a, -0x9a894c48416f8e64,0x708a7762924029dc, -0x7b0519f0a112b876,0x5c40918f1f2b650c, -0x538fde11181be8e4,0x4d4eae4ef81dd430, -0xb2038ba9f866def6,0x618448a3757698e0, -0xb04bc55ddccac94,0x6c4321f08a7af856, -0xea88e9ed3db19a86,0x4089c71d0711b486, -0x83c804cb9c7ea540,0x8f5fb6627dfc9c83, -0x624451737c039352,0xa395508ff097d053, -0xdb43668f59a9e130,0xae5239dc0f9bb0e5, -0x3acf3337b9d4d722,0x8298df3182f0fc35, -0xad5c6a62f6a8751c,0x5d03be50bfec2522, -0x4cd03fda16d5430e,0x71c958bd328769f2, -0xf5d70826337f316c,0x7c0e31eecd8b0944, -0x145b5d9ed302077e,0x50c4d70340e04594, -0x7d1bb0b872cd38b8,0x9f12a67c3a0d6d91, -0x9c97e50092b00eaa,0xb3d84091b7662141, -0x2590d2fcb71a7cc8,0xbe1f29c2486a41f7, -0xc41c874457674ada,0x92d5cf2fc5010d27, -0x8b97b65b221cc4e4,0x497f8adb47e0ae82, -0x6a1be3e3c261f2f6,0x65b56c36ca8be252, -0xd31cd41fe7cb8094,0x68720565358782e4, -0x329081a707b6b686,0x44b8e388b8ecce34, -0x5bd06c81a6798940,0x8b6e92f7c201e631, -0xba5c39394604bf52,0xa7a4741a4f6aaae1, -0x35b0ec563aecd30,0xaa631d49b066ca57, -0xe2d75b7d83d3fb22,0x86a9fba43d0d8687, -0x75440228ccaf591c,0x59329ac500115f90, -0x94c857902cd26f0e,0x75f87c288d7a1340, -0x2dcf606c09781d6c,0x783f157b727673f6, -0xcc4335d4e9052b7e,0x54f5f396ff1d3f26, -0xa503d8f248ca14b8,0x9b2382e985f01723, -0x448f8d4aa8b722aa,0xb7e96404089b5bf3, -0xfd88bab68d1d50c8,0xba2e0d57f7973b45, -0x1c04ef0e6d6066da,0x96e4ebba7afc7795, -0x348e28efd4693648,0x87ead47b9dcac6a9, -0xd5027d573414005a,0xab20329610a18a79, -0x6c054aab11be7238,0xa6e75bc5efadeacf, -0x8d891f13f1c3442a,0x8a2dbd2862c6a61f, -0xe4c9f235500c7bec,0x45fbcc57182b8e1a, -0x545a78db0714dfe,0x69312aba9540c2ca, -0xbc42907195db3f9c,0x64f643e96a4ca27c, -0x5dcec5c975a6098e,0x483ca504e727eeac, -0xca5d9c9c3adaabb0,0x97a7c465da3b37bb, -0x2bd1c924daa79da2,0xbb6d228857507b6b, -0x92d6fed8ff0defc0,0xb6aa4bdba85c1bdd, -0x735aab601f70d9d2,0x9a60ad362537570d, -0x1a1a4646bebfe614,0x55b6dc495fda7f08, -0xfb9613fe5ec2d006,0x797c3aa4d2b133d8, -0x429124027b68a264,0x74bb53f72dbd536e, -0xa31d71ba9b159476,0x5871b51aa0d61fbe, -0x9252edd649f3887c,0x92d371f184d6b90d, -0x73deb86ea98ebe6e,0xbe19971c09bdf5dd, -0xcad98f928c24cc0c,0xb3defe4ff6b1956b, -0x2b55da2a6c59fa1e,0x9f1418a27bdad9bb, -0x4215370ccd96c5d8,0x50c269dd0137f1be, -0xa39962b42debf3ca,0x7c088f308c5cbd6e, -0x1a9e5548084181a8,0x71cfe6637350ddd8, -0xfb1200f0e83cb7ba,0x5d05008efe3b9108, -0x6c8159a5a7401584,0x829e61efc327481f, -0x8d0d0c1d473d2396,0xae5487024e4c04cf, -0x340a3be1629751f4,0xa393ee51b1406479, -0xd5866e5982ea67e6,0x8f5908bc3c2b28a9, -0xbcc6837f23255820,0x408f79c346c600ac, -0x5d4ad6c7c3586e32,0x6c459f2ecbad4c7c, -0xe44de13be6f21c50,0x6182f67d34a12cca, -0x5c1b483068f2a42,0x4d481090b9ca601a, -0x2d4b7362bf867ad0,0x5c462f515efcd126, -0xccc726da5ffb4cc2,0x708cc9bcd3979df6, -0x75c011267a513ea0,0x7d4ba0ef2c9bfd40, -0x944c449e9a2c08b2,0x51814602a1f0b190, -0xfd0ca9b83be33774,0x9e57377ddb1d9995, -0x1c80fc00db9e0166,0xb29dd1905676d545, -0xa587cbfcfe347304,0xbf5ab8c3a97ab5f3, -0x440b9e441e494516,0x93905e2e2411f923, -0xd398c7115135e728,0x4c0b3f4f190d2034, -0x321492a9b148d13a,0x60c1d9a294666ce4, -0x8b13a55594e2a358,0x6d06b0f16b6a0c52, -0x6a9ff0ed749f954a,0x41cc561ce6014082, -0x3df1dcbd550aa8c,0x8e1a27639cec6887, -0xe2534873352d9c9e,0xa2d0c18e11872457, -0x5b547f8f1087eefc,0xaf17a8ddee8b44e1, -0xbad82a37f0fad8ee,0x83dd4e3063e00831, -0x7ec4ad73a79d9234,0x1108811fa6e10516, -0x9f48f8cb47e0a426,0x3dc267f22b8a49c6, -0x264fcf37624ad644,0x30050ea1d4862970, -0xc7c39a8f8237e056,0x1ccfe84c59ed65a0, -0xae8377a923f8df90,0xd319993323004da5, -0x4f0f2211c385e982,0xffd37fdeae6b0175, -0xf60815ede62f9be0,0xf214168d516761c3, -0x178440550652adf2,0xdedef060dc0c2d13, -0x80171900492e0fcc,0x1459101e110f404, -0x619b4cb8a95339de,0x2d8f77ec6c7bb8d4, -0xd89c7b448cf94bbc,0x20481ebf9377d862, -0x39102efc6c847dae,0xc82f8521e1c94b2, -0x5050c3dacd4b4268,0xc354892d64f1bcb7, -0xb1dc96622d36747a,0xef9e6fc0e99af067, -0x8dba19e089c0618,0xe2590693169690d1, -0xe957f426e8e1300a,0xce93e07e9bfddc01, -0xc1dd33c751e86098,0xdf9ddfbf7ccb6d3d, -0x2051667fb195568a,0xf3573952f1a021ed, -0x99565183943f24e8,0xfe9050010eac415b, -0x78da043b744212fa,0xd25ab6ec83c70d8b, -0x119ae91dd58d2d3c,0x1d8cc793f92a258e, -0xf016bca535f01b2e,0x3146217e7441695e, -0x49118b59105a694c,0x3c81482d8b4d09e8, -0xa89ddee1f0275f5e,0x104baec006264538, -0x3f0e87b4bf5bfd60,0xcfd0cfa13b3a9c2f, -0xde82d20c5f26cb72,0xe31a294cb651d0ff, -0x6785e5f07a8cb910,0xeedd401f495db049, -0x8609b0489af18f02,0xc217a6f2c436fc99, -0xef495d6e3b3eb0c4,0xdc1d78dbedbd49c, -0xec508d6db4386d6,0x210b316033b0984c, -0xb7c23f2afee9f4b4,0x2ccc5833ccbcf8fa, -0x564e6a921e94c2a6,0x6bede41d7b42a, -0x6701f6fecc72deac,0xcaa47a3565d71299, -0x868da3462c0fe8be,0xe66e9cd8e8bc5e49, -0x3f8a94ba09a59adc,0xeba9f58b17b03eff, -0xde06c102e9d8acce,0xc76313669adb722f, -0xb7462c2448179308,0x8b56219e0365a2a, -0x56ca799ca86aa51a,0x247f84f46d5d16fa, -0xefcd4e608dc0d778,0x29b8eda79251764c, -0xe411bd86dbde16a,0x5720b4a1f3a3a9c, -0x99d2428d22c14354,0xdae96a2b2226e38b, -0x785e1735c2bc7546,0xf6238cc6af4daf5b, -0xc15920c9e7160724,0xfbe4e5955041cfed, -0x20d57571076b3136,0xd72e0378dd2a833d, -0x49959857a6a40ef0,0x18f87207a7c7ab38, -0xa819cdef46d938e2,0x343294ea2aace7e8, -0x111efa1363734a80,0x39f5fdb9d5a0875e, -0xf092afab830e7c92,0x153f1b5458cbcb8e, -0xd818684a3a072c00,0x4312495bffd7ab2, -0x39943df2da7a1a12,0x28fbc27832963662, -0x80930a0effd06870,0x253cab2bcd9a56d4, -0x611f5fb61fad5e62,0x9f64dc640f11a04, -0x85fb290be6261a4,0xc6203cb93a1c3201, -0xe9d3e7285e1f57b6,0xeaeada54b7777ed1, -0x50d4d0d47bb525d4,0xe72db307487b1e67, -0xb158856c9bc813c6,0xcbe755eac51052b7, -0x26cbdc39d4b4b1f8,0x147c348bf80c8ba0, -0xc747898134c987ea,0x38b6d2667567c770, -0x7e40be7d1163f588,0x3571bb358a6ba7c6, -0x9fccebc5f11ec39a,0x19bb5dd80700eb16, -0xf68c06e350d1fc5c,0xd66d2ca77dedc313, -0x1700535bb0acca4e,0xfaa7ca4af0868fc3, -0xae0764a79506b82c,0xf760a3190f8aef75, -0x4f8b311f757b8e3e,0xdbaa45f482e1a3a5, -0x0,0x0, -0xa10cfc6a1654c578,0x5aa755df14f64da, -0xbae99a4e3fbe0c54,0x82db354523f40c7b, -0x1be5662429eac92c,0x87714018d2bb68a1, -0x8e808ec2a80c4662,0xba5ba13dbf25ee6b, -0x2f8c72a8be58831a,0xbff1d4604e6a8ab1, -0x3469148c97b24a36,0x388094789cd1e210, -0x9565e8e681e68f4e,0x3d2ae1256d9e86ca, -0x5c2b82c39ef7a93c,0x300b8602354dbc70, -0xfd277ea988a36c44,0x35a1f35fc402d8aa, -0xe6c2188da149a568,0xb2d0b34716b9b00b, -0x47cee4e7b71d6010,0xb77ac61ae7f6d4d1, -0xd2ab0c0136fbef5e,0x8a50273f8a68521b, -0x73a7f06b20af2a26,0x8ffa52627b2736c1, -0x6842964f0945e30a,0x88b127aa99c5e60, -0xc94e6a251f112672,0xd21672758d33aba, -0x882e2943d5ee4534,0xc25f5e75edaa4fa9, -0x2922d529c3ba804c,0xc7f52b281ce52b73, -0x32c7b30dea504960,0x40846b30ce5e43d2, -0x93cb4f67fc048c18,0x452e1e6d3f112708, -0x6aea7817de20356,0x7804ff48528fa1c2, -0xa7a25beb6bb6c62e,0x7dae8a15a3c0c518, -0xbc473dcf425c0f02,0xfadfca0d717badb9, -0x1d4bc1a55408ca7a,0xff75bf508034c963, -0xd405ab804b19ec08,0xf254d877d8e7f3d9, -0x750957ea5d4d2970,0xf7fead2a29a89703, -0x6eec31ce74a7e05c,0x708fed32fb13ffa2, -0xcfe0cda462f32524,0x7525986f0a5c9b78, -0x5a852542e315aa6a,0x480f794a67c21db2, -0xfb89d928f5416f12,0x4da50c17968d7968, -0xe06cbf0cdcaba63e,0xcad44c0f443611c9, -0x41604366caff6346,0xcf7e3952b5797513, -0x95d3204b1d1dd922,0x39092e35de04cc32, -0x34dfdc210b491c5a,0x3ca35b682f4ba8e8, -0x2f3aba0522a3d576,0xbbd21b70fdf0c049, -0x8e36466f34f7100e,0xbe786e2d0cbfa493, -0x1b53ae89b5119f40,0x83528f0861212259, -0xba5f52e3a3455a38,0x86f8fa55906e4683, -0xa1ba34c78aaf9314,0x189ba4d42d52e22, -0xb6c8ad9cfb566c,0x423cf10b39a4af8, -0xc9f8a28883ea701e,0x902a837eb497042, -0x68f45ee295beb566,0xca8dd6a1a061498, -0x731138c6bc547c4a,0x8bd99d72c8bd7c39, -0xd21dc4acaa00b932,0x8e73e82f39f218e3, -0x47782c4a2be6367c,0xb359090a546c9e29, -0xe674d0203db2f304,0xb6f37c57a523faf3, -0xfd91b60414583a28,0x31823c4f77989252, -0x5c9d4a6e020cff50,0x3428491286d7f688, -0x1dfd0908c8f39c16,0xfb56704033ae839b, -0xbcf1f562dea7596e,0xfefc051dc2e1e741, -0xa7149346f74d9042,0x798d4505105a8fe0, -0x6186f2ce119553a,0x7c273058e115eb3a, -0x937d87ca60ffda74,0x410dd17d8c8b6df0, -0x32717ba076ab1f0c,0x44a7a4207dc4092a, -0x29941d845f41d620,0xc3d6e438af7f618b, -0x8898e1ee49151358,0xc67c91655e300551, -0x41d68bcb5604352a,0xcb5df64206e33feb, -0xe0da77a14050f052,0xcef7831ff7ac5b31, -0xfb3f118569ba397e,0x4986c30725173390, -0x5a33edef7feefc06,0x4c2cb65ad458574a, -0xcf560509fe087348,0x7106577fb9c6d180, -0x6e5af963e85cb630,0x74ac22224889b55a, -0x75bf9f47c1b67f1c,0xf3dd623a9a32ddfb, -0xd4b3632dd7e2ba64,0xf67717676b7db921, -0xcb6e1a7035541fd6,0x8ab363f0b1f0f211, -0x6a62e61a2300daae,0x8f1916ad40bf96cb, -0x7187803e0aea1382,0x86856b59204fe6a, -0xd08b7c541cbed6fa,0xdc223e8634b9ab0, -0x45ee94b29d5859b4,0x30e8c2cd0ed51c7a, -0xe4e268d88b0c9ccc,0x3542b790ff9a78a0, -0xff070efca2e655e0,0xb233f7882d211001, -0x5e0bf296b4b29098,0xb79982d5dc6e74db, -0x974598b3aba3b6ea,0xbab8e5f284bd4e61, -0x364964d9bdf77392,0xbf1290af75f22abb, -0x2dac02fd941dbabe,0x3863d0b7a749421a, -0x8ca0fe9782497fc6,0x3dc9a5ea560626c0, -0x19c5167103aff088,0xe344cf3b98a00a, -0xb8c9ea1b15fb35f0,0x5493192cad7c4d0, -0xa32c8c3f3c11fcdc,0x8238718a186cac71, -0x22070552a4539a4,0x879204d7e923c8ab, -0x43403333e0ba5ae2,0x48ec3d855c5abdb8, -0xe24ccf59f6ee9f9a,0x4d4648d8ad15d962, -0xf9a9a97ddf0456b6,0xca3708c07faeb1c3, -0x58a55517c95093ce,0xcf9d7d9d8ee1d519, -0xcdc0bdf148b61c80,0xf2b79cb8e37f53d3, -0x6ccc419b5ee2d9f8,0xf71de9e512303709, -0x772927bf770810d4,0x706ca9fdc08b5fa8, -0xd625dbd5615cd5ac,0x75c6dca031c43b72, -0x1f6bb1f07e4df3de,0x78e7bb87691701c8, -0xbe674d9a681936a6,0x7d4dceda98586512, -0xa5822bbe41f3ff8a,0xfa3c8ec24ae30db3, -0x48ed7d457a73af2,0xff96fb9fbbac6969, -0x91eb3f32d641b5bc,0xc2bc1abad632efa3, -0x30e7c358c01570c4,0xc7166fe7277d8b79, -0x2b02a57ce9ffb9e8,0x40672ffff5c6e3d8, -0x8a0e5916ffab7c90,0x45cd5aa204898702, -0x5ebd3a3b2849c6f4,0xb3ba4dc56ff43e23, -0xffb1c6513e1d038c,0xb61038989ebb5af9, -0xe454a07517f7caa0,0x316178804c003258, -0x45585c1f01a30fd8,0x34cb0dddbd4f5682, -0xd03db4f980458096,0x9e1ecf8d0d1d048, -0x71314893961145ee,0xc4b99a5219eb492, -0x6ad42eb7bffb8cc2,0x8b3ad9bdf325dc33, -0xcbd8d2dda9af49ba,0x8e90ace0026ab8e9, -0x296b8f8b6be6fc8,0x83b1cbc75ab98253, -0xa39a4492a0eaaab0,0x861bbe9aabf6e689, -0xb87f22b68900639c,0x16afe82794d8e28, -0x1973dedc9f54a6e4,0x4c08bdf8802eaf2, -0x8c16363a1eb229aa,0x39ea6afae59c6c38, -0x2d1aca5008e6ecd2,0x3c401fa714d308e2, -0x36ffac74210c25fe,0xbb315fbfc6686043, -0x97f3501e3758e086,0xbe9b2ae237270499, -0xd6931378fda783c0,0x71e513b0825e718a, -0x779fef12ebf346b8,0x744f66ed73111550, -0x6c7a8936c2198f94,0xf33e26f5a1aa7df1, -0xcd76755cd44d4aec,0xf69453a850e5192b, -0x58139dba55abc5a2,0xcbbeb28d3d7b9fe1, -0xf91f61d043ff00da,0xce14c7d0cc34fb3b, -0xe2fa07f46a15c9f6,0x496587c81e8f939a, -0x43f6fb9e7c410c8e,0x4ccff295efc0f740, -0x8ab891bb63502afc,0x41ee95b2b713cdfa, -0x2bb46dd17504ef84,0x4444e0ef465ca920, -0x30510bf55cee26a8,0xc335a0f794e7c181, -0x915df79f4abae3d0,0xc69fd5aa65a8a55b, -0x4381f79cb5c6c9e,0xfbb5348f08362391, -0xa534e313dd08a9e6,0xfe1f41d2f979474b, -0xbed18537f4e260ca,0x796e01ca2bc22fea, -0x1fdd795de2b6a5b2,0x7cc47497da8d4b30, -0xa1318678293664f4,0xbe1eca746232042b, -0x3d7a123f62a18c,0xbbb4bf29937d60f1, -0x1bd81c36168868a0,0x3cc5ff3141c60850, -0xbad4e05c00dcadd8,0x396f8a6cb0896c8a, -0x2fb108ba813a2296,0x4456b49dd17ea40, -0x8ebdf4d0976ee7ee,0x1ef1e142c588e9a, -0x955892f4be842ec2,0x869e5e0cfee3e63b, -0x34546e9ea8d0ebba,0x83342b510fac82e1, -0xfd1a04bbb7c1cdc8,0x8e154c76577fb85b, -0x5c16f8d1a19508b0,0x8bbf392ba630dc81, -0x47f39ef5887fc19c,0xcce7933748bb420, -0xe6ff629f9e2b04e4,0x9640c6e85c4d0fa, -0x739a8a791fcd8baa,0x344eed4be85a5630, -0xd296761309994ed2,0x31e49816191532ea, -0xc9731037207387fe,0xb695d80ecbae5a4b, -0x687fec5d36274286,0xb33fad533ae13e91, -0x291faf3bfcd821c0,0x7c4194018f984b82, -0x88135351ea8ce4b8,0x79ebe15c7ed72f58, -0x93f63575c3662d94,0xfe9aa144ac6c47f9, -0x32fac91fd532e8ec,0xfb30d4195d232323, -0xa79f21f954d467a2,0xc61a353c30bda5e9, -0x693dd934280a2da,0xc3b04061c1f2c133, -0x1d76bbb76b6a6bf6,0x44c100791349a992, -0xbc7a47dd7d3eae8e,0x416b7524e206cd48, -0x75342df8622f88fc,0x4c4a1203bad5f7f2, -0xd438d192747b4d84,0x49e0675e4b9a9328, -0xcfddb7b65d9184a8,0xce9127469921fb89, -0x6ed14bdc4bc541d0,0xcb3b521b686e9f53, -0xfbb4a33aca23ce9e,0xf611b33e05f01999, -0x5ab85f50dc770be6,0xf3bbc663f4bf7d43, -0x415d3974f59dc2ca,0x74ca867b260415e2, -0xe051c51ee3c907b2,0x7160f326d74b7138, -0x34e2a633342bbdd6,0x8717e441bc36c819, -0x95ee5a59227f78ae,0x82bd911c4d79acc3, -0x8e0b3c7d0b95b182,0x5ccd1049fc2c462, -0x2f07c0171dc174fa,0x66a4596e8da0b8, -0xba6228f19c27fbb4,0x3d4c457c03132672, -0x1b6ed49b8a733ecc,0x38e63021f25c42a8, -0x8bb2bfa399f7e0,0xbf97703920e72a09, -0xa1874ed5b5cd3298,0xba3d0564d1a84ed3, -0x68c924f0aadc14ea,0xb71c6243897b7469, -0xc9c5d89abc88d192,0xb2b6171e783410b3, -0xd220bebe956218be,0x35c75706aa8f7812, -0x732c42d48336ddc6,0x306d225b5bc01cc8, -0xe649aa3202d05288,0xd47c37e365e9a02, -0x47455658148497f0,0x8edb623c711fed8, -0x5ca0307c3d6e5edc,0x8f9cf63b15aa9679, -0xfdaccc162b3a9ba4,0x8a368366e4e5f2a3, -0xbccc8f70e1c5f8e2,0x4548ba34519c87b0, -0x1dc0731af7913d9a,0x40e2cf69a0d3e36a, -0x625153ede7bf4b6,0xc7938f7172688bcb, -0xa729e954c82f31ce,0xc239fa2c8327ef11, -0x324c01b249c9be80,0xff131b09eeb969db, -0x9340fdd85f9d7bf8,0xfab96e541ff60d01, -0x88a59bfc7677b2d4,0x7dc82e4ccd4d65a0, -0x29a96796602377ac,0x78625b113c02017a, -0xe0e70db37f3251de,0x75433c3664d13bc0, -0x41ebf1d9696694a6,0x70e9496b959e5f1a, -0x5a0e97fd408c5d8a,0xf7980973472537bb, -0xfb026b9756d898f2,0xf2327c2eb66a5361, -0x6e678371d73e17bc,0xcf189d0bdbf4d5ab, -0xcf6b7f1bc16ad2c4,0xcab2e8562abbb171, -0xd48e193fe8801be8,0x4dc3a84ef800d9d0, -0x7582e555fed4de90,0x4869dd13094fbd0a, -0x6a5f9c081c627b22,0x34ada984d3c2f63a, -0xcb5360620a36be5a,0x3107dcd9228d92e0, -0xd0b6064623dc7776,0xb6769cc1f036fa41, -0x71bafa2c3588b20e,0xb3dce99c01799e9b, -0xe4df12cab46e3d40,0x8ef608b96ce71851, -0x45d3eea0a23af838,0x8b5c7de49da87c8b, -0x5e3688848bd03114,0xc2d3dfc4f13142a, -0xff3a74ee9d84f46c,0x98748a1be5c70f0, -0x36741ecb8295d21e,0x4a62f86e68f4a4a, -0x9778e2a194c11766,0x10c5adb17c02e90, -0x8c9d8485bd2bde4a,0x867d1ac3c57b4631, -0x2d9178efab7f1b32,0x83d76f9e343422eb, -0xb8f490092a99947c,0xbefd8ebb59aaa421, -0x19f86c633ccd5104,0xbb57fbe6a8e5c0fb, -0x21d0a4715279828,0x3c26bbfe7a5ea85a, -0xa311f62d03735d50,0x398ccea38b11cc80, -0xe271b54bc98c3e16,0xf6f2f7f13e68b993, -0x437d4921dfd8fb6e,0xf35882accf27dd49, -0x58982f05f6323242,0x7429c2b41d9cb5e8, -0xf994d36fe066f73a,0x7183b7e9ecd3d132, -0x6cf13b8961807874,0x4ca956cc814d57f8, -0xcdfdc7e377d4bd0c,0x4903239170023322, -0xd618a1c75e3e7420,0xce726389a2b95b83, -0x77145dad486ab158,0xcbd816d453f63f59, -0xbe5a3788577b972a,0xc6f971f30b2505e3, -0x1f56cbe2412f5252,0xc35304aefa6a6139, -0x4b3adc668c59b7e,0x442244b628d10998, -0xa5bf51ac7e915e06,0x418831ebd99e6d42, -0x30dab94aff77d148,0x7ca2d0ceb400eb88, -0x91d64520e9231430,0x7908a593454f8f52, -0x8a332304c0c9dd1c,0xfe79e58b97f4e7f3, -0x2b3fdf6ed69d1864,0xfbd390d666bb8329, -0xff8cbc43017fa200,0xda487b10dc63a08, -0x5e804029172b6778,0x80ef2ecfc895ed2, -0x4565260d3ec1ae54,0x8f7fb2f42e323673, -0xe469da6728956b2c,0x8ad5c7a9df7d52a9, -0x710c3281a973e462,0xb7ff268cb2e3d463, -0xd000ceebbf27211a,0xb25553d143acb0b9, -0xcbe5a8cf96cde836,0x352413c99117d818, -0x6ae954a580992d4e,0x308e66946058bcc2, -0xa3a73e809f880b3c,0x3daf01b3388b8678, -0x2abc2ea89dcce44,0x380574eec9c4e2a2, -0x194ea4cea0360768,0xbf7434f61b7f8a03, -0xb84258a4b662c210,0xbade41abea30eed9, -0x2d27b04237844d5e,0x87f4a08e87ae6813, -0x8c2b4c2821d08826,0x825ed5d376e10cc9, -0x97ce2a0c083a410a,0x52f95cba45a6468, -0x36c2d6661e6e8472,0x85e096551500b2, -0x77a29500d491e734,0xcffbd9c4e06c75a1, -0xd6ae696ac2c5224c,0xca51ac991123117b, -0xcd4b0f4eeb2feb60,0x4d20ec81c39879da, -0x6c47f324fd7b2e18,0x488a99dc32d71d00, -0xf9221bc27c9da156,0x75a078f95f499bca, -0x582ee7a86ac9642e,0x700a0da4ae06ff10, -0x43cb818c4323ad02,0xf77b4dbc7cbd97b1, -0xe2c77de65577687a,0xf2d138e18df2f36b, -0x2b8917c34a664e08,0xfff05fc6d521c9d1, -0x8a85eba95c328b70,0xfa5a2a9b246ead0b, -0x91608d8d75d8425c,0x7d2b6a83f6d5c5aa, -0x306c71e7638c8724,0x78811fde079aa170, -0xa5099901e26a086a,0x45abfefb6a0427ba, -0x405656bf43ecd12,0x40018ba69b4b4360, -0x1fe0034fddd4043e,0xc770cbbe49f02bc1, -0xbeecff25cb80c146,0xc2dabee3b8bf4f1b, -0x0,0x0, -0xe684ecc9b397a5fe,0xb3b2d35103f1a3ed, -0x6da6f30e41a8edf0,0x34b0cc6ccf4ee620, -0x8b221fc7f23f480e,0x87021f3dccbf45cd, -0xacd605531d728f16,0xa6af6a59808b2143, -0x4a52e99aaee52ae8,0x151db908837a82ae, -0xc170f65d5cda62e6,0x921fa6354fc5c763, -0x27f41a94ef4dc718,0x21ad75644c34648e, -0x36771e3ca90ca14,0x3555819a552c1192, -0xe5e39d2a79076fea,0x86e752cb56ddb27f, -0x6ec182ed8b3827e4,0x1e54df69a62f7b2, -0x88456e2438af821a,0xb2579ea79993545f, -0xafb174b0d7e24502,0x93faebc3d5a730d1, -0x493598796475e0fc,0x20483892d656933c, -0xc21787be964aa8f2,0xa74a27af1ae9d6f1, -0x24936b7725dd0d0c,0x14f8f4fe1918751c, -0xc6c1932eeb78b72a,0xeabea114c8ae9a9f, -0x20457fe758ef12d4,0x590c7245cb5f3972, -0xab676020aad05ada,0xde0e6d7807e07cbf, -0x4de38ce91947ff24,0x6dbcbe290411df52, -0x6a17967df60a383c,0x4c11cb4d4825bbdc, -0x8c937ab4459d9dc2,0xffa3181c4bd41831, -0x7b16573b7a2d5cc,0x78a10721876b5dfc, -0xe13589ba04357032,0xcb13d470849afe11, -0xc5a6e2cd21e87d3e,0xdfeb208e9d828b0d, -0x23220e04927fd8c0,0x6c59f3df9e7328e0, -0xa80011c3604090ce,0xeb5bece252cc6d2d, -0x4e84fd0ad3d73530,0x58e93fb3513dcec0, -0x6970e79e3c9af228,0x79444ad71d09aa4e, -0x8ff40b578f0d57d6,0xcaf699861ef809a3, -0x4d614907d321fd8,0x4df486bbd2474c6e, -0xe252f859cea5ba26,0xfe4655ead1b6ef83, -0xfc5874dd3b9425ce,0x1988519c2a18a57c, -0x1adc981488038030,0xaa3a82cd29e90691, -0x91fe87d37a3cc83e,0x2d389df0e556435c, -0x777a6b1ac9ab6dc0,0x9e8a4ea1e6a7e0b1, -0x508e718e26e6aad8,0xbf273bc5aa93843f, -0xb60a9d4795710f26,0xc95e894a96227d2, -0x3d288280674e4728,0x8b97f7a965dd621f, -0xdbac6e49d4d9e2d6,0x382524f8662cc1f2, -0xff3f053ef104efda,0x2cddd0067f34b4ee, -0x19bbe9f742934a24,0x9f6f03577cc51703, -0x9299f630b0ac022a,0x186d1c6ab07a52ce, -0x741d1af9033ba7d4,0xabdfcf3bb38bf123, -0x53e9006dec7660cc,0x8a72ba5fffbf95ad, -0xb56deca45fe1c532,0x39c0690efc4e3640, -0x3e4ff363adde8d3c,0xbec2763330f1738d, -0xd8cb1faa1e4928c2,0xd70a5623300d060, -0x3a99e7f3d0ec92e4,0xf336f088e2b63fe3, -0xdc1d0b3a637b371a,0x408423d9e1479c0e, -0x573f14fd91447f14,0xc7863ce42df8d9c3, -0xb1bbf83422d3daea,0x7434efb52e097a2e, -0x964fe2a0cd9e1df2,0x55999ad1623d1ea0, -0x70cb0e697e09b80c,0xe62b498061ccbd4d, -0xfbe911ae8c36f002,0x612956bdad73f880, -0x1d6dfd673fa155fc,0xd29b85ecae825b6d, -0x39fe96101a7c58f0,0xc6637112b79a2e71, -0xdf7a7ad9a9ebfd0e,0x75d1a243b46b8d9c, -0x5458651e5bd4b500,0xf2d3bd7e78d4c851, -0xb2dc89d7e84310fe,0x41616e2f7b256bbc, -0x95289343070ed7e6,0x60cc1b4b37110f32, -0x73ac7f8ab4997218,0xd37ec81a34e0acdf, -0xf88e604d46a63a16,0x547cd727f85fe912, -0x1e0a8c84f5319fe8,0xe7ce0476fbae4aff, -0x70ec558472062c44,0x60abfabc33f697de, -0x9668b94dc19189ba,0xd31929ed30073433, -0x1d4aa68a33aec1b4,0x541b36d0fcb871fe, -0xfbce4a438039644a,0xe7a9e581ff49d213, -0xdc3a50d76f74a352,0xc60490e5b37db69d, -0x3abebc1edce306ac,0x75b643b4b08c1570, -0xb19ca3d92edc4ea2,0xf2b45c897c3350bd, -0x57184f109d4beb5c,0x41068fd87fc2f350, -0x738b2467b896e650,0x55fe7b2666da864c, -0x950fc8ae0b0143ae,0xe64ca877652b25a1, -0x1e2dd769f93e0ba0,0x614eb74aa994606c, -0xf8a93ba04aa9ae5e,0xd2fc641baa65c381, -0xdf5d2134a5e46946,0xf351117fe651a70f, -0x39d9cdfd1673ccb8,0x40e3c22ee5a004e2, -0xb2fbd23ae44c84b6,0xc7e1dd13291f412f, -0x547f3ef357db2148,0x74530e422aeee2c2, -0xb62dc6aa997e9b6e,0x8a155ba8fb580d41, -0x50a92a632ae93e90,0x39a788f9f8a9aeac, -0xdb8b35a4d8d6769e,0xbea597c43416eb61, -0x3d0fd96d6b41d360,0xd17449537e7488c, -0x1afbc3f9840c1478,0x2cba31f17bd32c02, -0xfc7f2f30379bb186,0x9f08e2a078228fef, -0x775d30f7c5a4f988,0x180afd9db49dca22, -0x91d9dc3e76335c76,0xabb82eccb76c69cf, -0xb54ab74953ee517a,0xbf40da32ae741cd3, -0x53ce5b80e079f484,0xcf20963ad85bf3e, -0xd8ec44471246bc8a,0x8bf0165e613afaf3, -0x3e68a88ea1d11974,0x3842c50f62cb591e, -0x199cb21a4e9cde6c,0x19efb06b2eff3d90, -0xff185ed3fd0b7b92,0xaa5d633a2d0e9e7d, -0x743a41140f34339c,0x2d5f7c07e1b1dbb0, -0x92beadddbca39662,0x9eedaf56e240785d, -0x8cb421594992098a,0x7923ab2019ee32a2, -0x6a30cd90fa05ac74,0xca9178711a1f914f, -0xe112d257083ae47a,0x4d93674cd6a0d482, -0x7963e9ebbad4184,0xfe21b41dd551776f, -0x2062240a54e0869c,0xdf8cc179996513e1, -0xc6e6c8c3e7772362,0x6c3e12289a94b00c, -0x4dc4d70415486b6c,0xeb3c0d15562bf5c1, -0xab403bcda6dfce92,0x588ede4455da562c, -0x8fd350ba8302c39e,0x4c762aba4cc22330, -0x6957bc7330956660,0xffc4f9eb4f3380dd, -0xe275a3b4c2aa2e6e,0x78c6e6d6838cc510, -0x4f14f7d713d8b90,0xcb743587807d66fd, -0x230555e99e704c88,0xead940e3cc490273, -0xc581b9202de7e976,0x596b93b2cfb8a19e, -0x4ea3a6e7dfd8a178,0xde698c8f0307e453, -0xa8274a2e6c4f0486,0x6ddb5fde00f647be, -0x4a75b277a2eabea0,0x939d0a34d140a83d, -0xacf15ebe117d1b5e,0x202fd965d2b10bd0, -0x27d34179e3425350,0xa72dc6581e0e4e1d, -0xc157adb050d5f6ae,0x149f15091dffedf0, -0xe6a3b724bf9831b6,0x3532606d51cb897e, -0x275bed0c0f9448,0x8680b33c523a2a93, -0x8b05442afe30dc46,0x182ac019e856f5e, -0x6d81a8e34da779b8,0xb2307f509d74ccb3, -0x4912c394687a74b4,0xa6c88bae846cb9af, -0xaf962f5ddbedd14a,0x157a58ff879d1a42, -0x24b4309a29d29944,0x927847c24b225f8f, -0xc230dc539a453cba,0x21ca949348d3fc62, -0xe5c4c6c77508fba2,0x67e1f704e798ec, -0x3402a0ec69f5e5c,0xb3d532a607163b01, -0x886235c934a01652,0x34d72d9bcba97ecc, -0x6ee6d9008737b3ac,0x8765fecac858dd21, -0xa9e47128863ba654,0xdf68fe1cdf73f30, -0x4f609de135ac03aa,0xbe445cb0ce069cdd, -0xc4428226c7934ba4,0x3946438d02b9d910, -0x22c66eef7404ee5a,0x8af490dc01487afd, -0x532747b9b492942,0xab59e5b84d7c1e73, -0xe3b698b228de8cbc,0x18eb36e94e8dbd9e, -0x68948775dae1c4b2,0x9fe929d48232f853, -0x8e106bbc6976614c,0x2c5bfa8581c35bbe, -0xaa8300cb4cab6c40,0x38a30e7b98db2ea2, -0x4c07ec02ff3cc9be,0x8b11dd2a9b2a8d4f, -0xc725f3c50d0381b0,0xc13c2175795c882, -0x21a11f0cbe94244e,0xbfa1114654646b6f, -0x655059851d9e356,0x9e0c642218500fe1, -0xe0d1e951e24e46a8,0x2dbeb7731ba1ac0c, -0x6bf3f69610710ea6,0xaabca84ed71ee9c1, -0x8d771a5fa3e6ab58,0x190e7b1fd4ef4a2c, -0x6f25e2066d43117e,0xe7482ef50559a5af, -0x89a10ecfded4b480,0x54fafda406a80642, -0x28311082cebfc8e,0xd3f8e299ca17438f, -0xe407fdc19f7c5970,0x604a31c8c9e6e062, -0xc3f3e75570319e68,0x41e744ac85d284ec, -0x25770b9cc3a63b96,0xf25597fd86232701, -0xae55145b31997398,0x755788c04a9c62cc, -0x48d1f892820ed666,0xc6e55b91496dc121, -0x6c4293e5a7d3db6a,0xd21daf6f5075b43d, -0x8ac67f2c14447e94,0x61af7c3e538417d0, -0x1e460ebe67b369a,0xe6ad63039f3b521d, -0xe7608c2255ec9364,0x551fb0529ccaf1f0, -0xc09496b6baa1547c,0x74b2c536d0fe957e, -0x26107a7f0936f182,0xc7001667d30f3693, -0xad3265b8fb09b98c,0x4002095a1fb0735e, -0x4bb68971489e1c72,0xf3b0da0b1c41d0b3, -0x55bc05f5bdaf839a,0x147ede7de7ef9a4c, -0xb338e93c0e382664,0xa7cc0d2ce41e39a1, -0x381af6fbfc076e6a,0x20ce121128a17c6c, -0xde9e1a324f90cb94,0x937cc1402b50df81, -0xf96a00a6a0dd0c8c,0xb2d1b4246764bb0f, -0x1feeec6f134aa972,0x1636775649518e2, -0x94ccf3a8e175e17c,0x86617848a82a5d2f, -0x72481f6152e24482,0x35d3ab19abdbfec2, -0x56db7416773f498e,0x212b5fe7b2c38bde, -0xb05f98dfc4a8ec70,0x92998cb6b1322833, -0x3b7d87183697a47e,0x159b938b7d8d6dfe, -0xddf96bd185000180,0xa62940da7e7cce13, -0xfa0d71456a4dc698,0x878435be3248aa9d, -0x1c899d8cd9da6366,0x3436e6ef31b90970, -0x97ab824b2be52b68,0xb334f9d2fd064cbd, -0x712f6e8298728e96,0x862a83fef7ef50, -0x937d96db56d734b0,0xfec07f692f4100d3, -0x75f97a12e540914e,0x4d72ac382cb0a33e, -0xfedb65d5177fd940,0xca70b305e00fe6f3, -0x185f891ca4e87cbe,0x79c26054e3fe451e, -0x3fab93884ba5bba6,0x586f1530afca2190, -0xd92f7f41f8321e58,0xebddc661ac3b827d, -0x520d60860a0d5656,0x6cdfd95c6084c7b0, -0xb4898c4fb99af3a8,0xdf6d0a0d6375645d, -0x901ae7389c47fea4,0xcb95fef37a6d1141, -0x769e0bf12fd05b5a,0x78272da2799cb2ac, -0xfdbc1436ddef1354,0xff25329fb523f761, -0x1b38f8ff6e78b6aa,0x4c97e1ceb6d2548c, -0x3ccce26b813571b2,0x6d3a94aafae63002, -0xda480ea232a2d44c,0xde8847fbf91793ef, -0x516a1165c09d9c42,0x598a58c635a8d622, -0xb7eefdac730a39bc,0xea388b97365975cf, -0xd90824acf43d8a10,0x6d5d755dfe01a8ee, -0x3f8cc86547aa2fee,0xdeefa60cfdf00b03, -0xb4aed7a2b59567e0,0x59edb931314f4ece, -0x522a3b6b0602c21e,0xea5f6a6032beed23, -0x75de21ffe94f0506,0xcbf21f047e8a89ad, -0x935acd365ad8a0f8,0x7840cc557d7b2a40, -0x1878d2f1a8e7e8f6,0xff42d368b1c46f8d, -0xfefc3e381b704d08,0x4cf00039b235cc60, -0xda6f554f3ead4004,0x5808f4c7ab2db97c, -0x3cebb9868d3ae5fa,0xebba2796a8dc1a91, -0xb7c9a6417f05adf4,0x6cb838ab64635f5c, -0x514d4a88cc92080a,0xdf0aebfa6792fcb1, -0x76b9501c23dfcf12,0xfea79e9e2ba6983f, -0x903dbcd590486aec,0x4d154dcf28573bd2, -0x1b1fa312627722e2,0xca1752f2e4e87e1f, -0xfd9b4fdbd1e0871c,0x79a581a3e719ddf2, -0x1fc9b7821f453d3a,0x87e3d44936af3271, -0xf94d5b4bacd298c4,0x34510718355e919c, -0x726f448c5eedd0ca,0xb3531825f9e1d451, -0x94eba845ed7a7534,0xe1cb74fa1077bc, -0xb31fb2d10237b22c,0x214cbe10b6241332, -0x559b5e18b1a017d2,0x92fe6d41b5d5b0df, -0xdeb941df439f5fdc,0x15fc727c796af512, -0x383dad16f008fa22,0xa64ea12d7a9b56ff, -0x1caec661d5d5f72e,0xb2b655d3638323e3, -0xfa2a2aa8664252d0,0x10486826072800e, -0x7108356f947d1ade,0x860699bfaccdc5c3, -0x978cd9a627eabf20,0x35b44aeeaf3c662e, -0xb078c332c8a77838,0x14193f8ae30802a0, -0x56fc2ffb7b30ddc6,0xa7abecdbe0f9a14d, -0xddde303c890f95c8,0x20a9f3e62c46e480, -0x3b5adcf53a983036,0x931b20b72fb7476d, -0x25505071cfa9afde,0x74d524c1d4190d92, -0xc3d4bcb87c3e0a20,0xc767f790d7e8ae7f, -0x48f6a37f8e01422e,0x4065e8ad1b57ebb2, -0xae724fb63d96e7d0,0xf3d73bfc18a6485f, -0x89865522d2db20c8,0xd27a4e9854922cd1, -0x6f02b9eb614c8536,0x61c89dc957638f3c, -0xe420a62c9373cd38,0xe6ca82f49bdccaf1, -0x2a44ae520e468c6,0x557851a5982d691c, -0x26372192053965ca,0x4180a55b81351c00, -0xc0b3cd5bb6aec034,0xf232760a82c4bfed, -0x4b91d29c4491883a,0x753069374e7bfa20, -0xad153e55f7062dc4,0xc682ba664d8a59cd, -0x8ae124c1184beadc,0xe72fcf0201be3d43, -0x6c65c808abdc4f22,0x549d1c53024f9eae, -0xe747d7cf59e3072c,0xd39f036ecef0db63, -0x1c33b06ea74a2d2,0x602dd03fcd01788e, -0xe391c35f24d118f4,0x9e6b85d51cb7970d, -0x5152f969746bd0a,0x2dd956841f4634e0, -0x8e3730516579f504,0xaadb49b9d3f9712d, -0x68b3dc98d6ee50fa,0x19699ae8d008d2c0, -0x4f47c60c39a397e2,0x38c4ef8c9c3cb64e, -0xa9c32ac58a34321c,0x8b763cdd9fcd15a3, -0x22e13502780b7a12,0xc7423e05372506e, -0xc465d9cbcb9cdfec,0xbfc6f0b15083f383, -0xe0f6b2bcee41d2e0,0xab3e044f499b869f, -0x6725e755dd6771e,0x188cd71e4a6a2572, -0x8d5041b2afe93f10,0x9f8ec82386d560bf, -0x6bd4ad7b1c7e9aee,0x2c3c1b728524c352, -0x4c20b7eff3335df6,0xd916e16c910a7dc, -0xaaa45b2640a4f808,0xbe23bd47cae10431, -0x218644e1b29bb006,0x3921a27a065e41fc, -0xc702a828010c15f8,0x8a93712b05afe211, -}; -} -#endif \ No newline at end of file diff --git a/libOTe/Tools/bitpolymul/gf264_cantor_iso.h b/libOTe/Tools/bitpolymul/gf264_cantor_iso.h deleted file mode 100644 index d5739ff8..00000000 --- a/libOTe/Tools/bitpolymul/gf264_cantor_iso.h +++ /dev/null @@ -1,2149 +0,0 @@ -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - -#include "stdint.h" -#include "bpmDefines.h" -namespace bpm{ - -alignas(32) const uint64_t gfCantorto264[64*2] = { - 0x1, 0, - 0x19C9369F278ADC02, 0, - 0xA181E7D66F5FF794, 0, - 0x5DB84357CE785D08, 0, - 0xB973D466F5C9D0CA, 0, - 0x521AC889831A075E, 0, - 0x33CE8BEDDC8A656, 0, - 0xB5846C4E07B91010, 0, - 0x4087B8CBB37A32EC, 0, - 0xD0D3888C0AE17C, 0, - 0xAFD5AC70237F2222, 0, - 0xE3F5AF99CC3AAAF8, 0, - 0x5A1DB3B16A0B58B8, 0, - 0x9947C54FE7EE248, 0, - 0xE8EAF0E0068F544, 0, - 0xA2A113500B4B4F5A, 0, - 0xE96F9805D6CE0BB0, 0, - 0x53496F8B5C9EDD4C, 0, - 0xAD325CB6F4AC2A9E, 0, - 0x4A8DCF8BD7EDE826, 0, - 0xA3E9C552B6434210, 0, - 0x5FA92AD9C9BC7ED0, 0, - 0xA389F910CD7734DE, 0, - 0xE916F3DFCA4609D8, 0, - 0xF89578714BD28F96, 0, - 0x564DDA59237A3352, 0, - 0xAD33BC6CC75AED38, 0, - 0x57A3104FCD0E5F34, 0, - 0xB0F502E4CD60039A, 0, - 0xEB42E79F91F49F8C, 0, - 0x54E5BF3774B3F850, 0, - 0xB66864E6EC14B4D2, 0, - 0xED57CE778F0D6244, 0, - 0x523AAF9D6148BA24, 0, - 0xA8FCBFAAC14940C6, 0, - 0xE503EACFCEF77780, 0, - 0xF3746C7B5183A372, 0, - 0xEC50D77D2F416218, 0, - 0xF9CDF54569FE87E6, 0, - 0xE576269915705E2C, 0, - 0xEE2A197148FA8C72, 0, - 0x49E31453575F365A, 0, - 0xB86698D88ADD0BC0, 0, - 0x4F35FB218E7F37C0, 0, - 0xA306FEEA8A242832, 0, - 0x5E5F06A9DAEAD6E6, 0, - 0xBE13089ECC784EA0, 0, - 0xFE1A10738739C892, 0, - 0xE2266CEB0C5BC774, 0, - 0xF490E6ED40D1DD1A, 0, - 0xF3F5F515077E92F0, 0, - 0x467C20312E7EB0F0, 0, - 0xB06CAA4295D350C2, 0, - 0x5C5916D98A583C16, 0, - 0xA04DE5B4C7A1CEAC, 0, - 0x41430183D6E85EC0, 0, - 0xB361D8DABE3B3632, 0, - 0x4357375D88B88B56, 0, - 0xB057DCC8A19FBC9C, 0, - 0xF26E1791BE4B37C2, 0, - 0xE9F744031BFE63E4, 0, - 0xE50803875E9AB776, 0, - 0x44EE098F4D56753E, 0, - 0x9DC338F8399031B4, 0, -}; - - - - -alignas(32) const uint64_t gfCantorto264_8R[(64/8)*256*2] = { -0x0,0, -0x1,0, -0x19c9369f278adc02,0, -0x19c9369f278adc03,0, -0xa181e7d66f5ff794,0, -0xa181e7d66f5ff795,0, -0xb848d14948d52b96,0, -0xb848d14948d52b97,0, -0x5db84357ce785d08,0, -0x5db84357ce785d09,0, -0x447175c8e9f2810a,0, -0x447175c8e9f2810b,0, -0xfc39a481a127aa9c,0, -0xfc39a481a127aa9d,0, -0xe5f0921e86ad769e,0, -0xe5f0921e86ad769f,0, -0xb973d466f5c9d0ca,0, -0xb973d466f5c9d0cb,0, -0xa0bae2f9d2430cc8,0, -0xa0bae2f9d2430cc9,0, -0x18f233b09a96275e,0, -0x18f233b09a96275f,0, -0x13b052fbd1cfb5c,0, -0x13b052fbd1cfb5d,0, -0xe4cb97313bb18dc2,0, -0xe4cb97313bb18dc3,0, -0xfd02a1ae1c3b51c0,0, -0xfd02a1ae1c3b51c1,0, -0x454a70e754ee7a56,0, -0x454a70e754ee7a57,0, -0x5c8346787364a654,0, -0x5c8346787364a655,0, -0x521ac889831a075e,0, -0x521ac889831a075f,0, -0x4bd3fe16a490db5c,0, -0x4bd3fe16a490db5d,0, -0xf39b2f5fec45f0ca,0, -0xf39b2f5fec45f0cb,0, -0xea5219c0cbcf2cc8,0, -0xea5219c0cbcf2cc9,0, -0xfa28bde4d625a56,0, -0xfa28bde4d625a57,0, -0x166bbd416ae88654,0, -0x166bbd416ae88655,0, -0xae236c08223dadc2,0, -0xae236c08223dadc3,0, -0xb7ea5a9705b771c0,0, -0xb7ea5a9705b771c1,0, -0xeb691cef76d3d794,0, -0xeb691cef76d3d795,0, -0xf2a02a7051590b96,0, -0xf2a02a7051590b97,0, -0x4ae8fb39198c2000,0, -0x4ae8fb39198c2001,0, -0x5321cda63e06fc02,0, -0x5321cda63e06fc03,0, -0xb6d15fb8b8ab8a9c,0, -0xb6d15fb8b8ab8a9d,0, -0xaf1869279f21569e,0, -0xaf1869279f21569f,0, -0x1750b86ed7f47d08,0, -0x1750b86ed7f47d09,0, -0xe998ef1f07ea10a,0, -0xe998ef1f07ea10b,0, -0x33ce8beddc8a656,0, -0x33ce8beddc8a657,0, -0x1af5de21fa427a54,0, -0x1af5de21fa427a55,0, -0xa2bd0f68b29751c2,0, -0xa2bd0f68b29751c3,0, -0xbb7439f7951d8dc0,0, -0xbb7439f7951d8dc1,0, -0x5e84abe913b0fb5e,0, -0x5e84abe913b0fb5f,0, -0x474d9d76343a275c,0, -0x474d9d76343a275d,0, -0xff054c3f7cef0cca,0, -0xff054c3f7cef0ccb,0, -0xe6cc7aa05b65d0c8,0, -0xe6cc7aa05b65d0c9,0, -0xba4f3cd82801769c,0, -0xba4f3cd82801769d,0, -0xa3860a470f8baa9e,0, -0xa3860a470f8baa9f,0, -0x1bcedb0e475e8108,0, -0x1bcedb0e475e8109,0, -0x207ed9160d45d0a,0, -0x207ed9160d45d0b,0, -0xe7f77f8fe6792b94,0, -0xe7f77f8fe6792b95,0, -0xfe3e4910c1f3f796,0, -0xfe3e4910c1f3f797,0, -0x467698598926dc00,0, -0x467698598926dc01,0, -0x5fbfaec6aeac0002,0, -0x5fbfaec6aeac0003,0, -0x512620375ed2a108,0, -0x512620375ed2a109,0, -0x48ef16a879587d0a,0, -0x48ef16a879587d0b,0, -0xf0a7c7e1318d569c,0, -0xf0a7c7e1318d569d,0, -0xe96ef17e16078a9e,0, -0xe96ef17e16078a9f,0, -0xc9e636090aafc00,0, -0xc9e636090aafc01,0, -0x155755ffb7202002,0, -0x155755ffb7202003,0, -0xad1f84b6fff50b94,0, -0xad1f84b6fff50b95,0, -0xb4d6b229d87fd796,0, -0xb4d6b229d87fd797,0, -0xe855f451ab1b71c2,0, -0xe855f451ab1b71c3,0, -0xf19cc2ce8c91adc0,0, -0xf19cc2ce8c91adc1,0, -0x49d41387c4448656,0, -0x49d41387c4448657,0, -0x501d2518e3ce5a54,0, -0x501d2518e3ce5a55,0, -0xb5edb70665632cca,0, -0xb5edb70665632ccb,0, -0xac24819942e9f0c8,0, -0xac24819942e9f0c9,0, -0x146c50d00a3cdb5e,0, -0x146c50d00a3cdb5f,0, -0xda5664f2db6075c,0, -0xda5664f2db6075d,0, -0xb5846c4e07b91010,0, -0xb5846c4e07b91011,0, -0xac4d5ad12033cc12,0, -0xac4d5ad12033cc13,0, -0x14058b9868e6e784,0, -0x14058b9868e6e785,0, -0xdccbd074f6c3b86,0, -0xdccbd074f6c3b87,0, -0xe83c2f19c9c14d18,0, -0xe83c2f19c9c14d19,0, -0xf1f51986ee4b911a,0, -0xf1f51986ee4b911b,0, -0x49bdc8cfa69eba8c,0, -0x49bdc8cfa69eba8d,0, -0x5074fe508114668e,0, -0x5074fe508114668f,0, -0xcf7b828f270c0da,0, -0xcf7b828f270c0db,0, -0x153e8eb7d5fa1cd8,0, -0x153e8eb7d5fa1cd9,0, -0xad765ffe9d2f374e,0, -0xad765ffe9d2f374f,0, -0xb4bf6961baa5eb4c,0, -0xb4bf6961baa5eb4d,0, -0x514ffb7f3c089dd2,0, -0x514ffb7f3c089dd3,0, -0x4886cde01b8241d0,0, -0x4886cde01b8241d1,0, -0xf0ce1ca953576a46,0, -0xf0ce1ca953576a47,0, -0xe9072a3674ddb644,0, -0xe9072a3674ddb645,0, -0xe79ea4c784a3174e,0, -0xe79ea4c784a3174f,0, -0xfe579258a329cb4c,0, -0xfe579258a329cb4d,0, -0x461f4311ebfce0da,0, -0x461f4311ebfce0db,0, -0x5fd6758ecc763cd8,0, -0x5fd6758ecc763cd9,0, -0xba26e7904adb4a46,0, -0xba26e7904adb4a47,0, -0xa3efd10f6d519644,0, -0xa3efd10f6d519645,0, -0x1ba700462584bdd2,0, -0x1ba700462584bdd3,0, -0x26e36d9020e61d0,0, -0x26e36d9020e61d1,0, -0x5eed70a1716ac784,0, -0x5eed70a1716ac785,0, -0x4724463e56e01b86,0, -0x4724463e56e01b87,0, -0xff6c97771e353010,0, -0xff6c97771e353011,0, -0xe6a5a1e839bfec12,0, -0xe6a5a1e839bfec13,0, -0x35533f6bf129a8c,0, -0x35533f6bf129a8d,0, -0x1a9c05699898468e,0, -0x1a9c05699898468f,0, -0xa2d4d420d04d6d18,0, -0xa2d4d420d04d6d19,0, -0xbb1de2bff7c7b11a,0, -0xbb1de2bff7c7b11b,0, -0xb6b884f0da71b646,0, -0xb6b884f0da71b647,0, -0xaf71b26ffdfb6a44,0, -0xaf71b26ffdfb6a45,0, -0x17396326b52e41d2,0, -0x17396326b52e41d3,0, -0xef055b992a49dd0,0, -0xef055b992a49dd1,0, -0xeb00c7a71409eb4e,0, -0xeb00c7a71409eb4f,0, -0xf2c9f1383383374c,0, -0xf2c9f1383383374d,0, -0x4a8120717b561cda,0, -0x4a8120717b561cdb,0, -0x534816ee5cdcc0d8,0, -0x534816ee5cdcc0d9,0, -0xfcb50962fb8668c,0, -0xfcb50962fb8668d,0, -0x160266090832ba8e,0, -0x160266090832ba8f,0, -0xae4ab74040e79118,0, -0xae4ab74040e79119,0, -0xb78381df676d4d1a,0, -0xb78381df676d4d1b,0, -0x527313c1e1c03b84,0, -0x527313c1e1c03b85,0, -0x4bba255ec64ae786,0, -0x4bba255ec64ae787,0, -0xf3f2f4178e9fcc10,0, -0xf3f2f4178e9fcc11,0, -0xea3bc288a9151012,0, -0xea3bc288a9151013,0, -0xe4a24c79596bb118,0, -0xe4a24c79596bb119,0, -0xfd6b7ae67ee16d1a,0, -0xfd6b7ae67ee16d1b,0, -0x4523abaf3634468c,0, -0x4523abaf3634468d,0, -0x5cea9d3011be9a8e,0, -0x5cea9d3011be9a8f,0, -0xb91a0f2e9713ec10,0, -0xb91a0f2e9713ec11,0, -0xa0d339b1b0993012,0, -0xa0d339b1b0993013,0, -0x189be8f8f84c1b84,0, -0x189be8f8f84c1b85,0, -0x152de67dfc6c786,0, -0x152de67dfc6c787,0, -0x5dd1981faca261d2,0, -0x5dd1981faca261d3,0, -0x4418ae808b28bdd0,0, -0x4418ae808b28bdd1,0, -0xfc507fc9c3fd9646,0, -0xfc507fc9c3fd9647,0, -0xe5994956e4774a44,0, -0xe5994956e4774a45,0, -0x69db4862da3cda,0, -0x69db4862da3cdb,0, -0x19a0edd74550e0d8,0, -0x19a0edd74550e0d9,0, -0xa1e83c9e0d85cb4e,0, -0xa1e83c9e0d85cb4f,0, -0xb8210a012a0f174c,0, -0xb8210a012a0f174d,0, -0x0,0, -0x4087b8cbb37a32ec,0, -0xd0d3888c0ae17c,0, -0x40576b433f70d390,0, -0xafd5ac70237f2222,0, -0xef5214bb900510ce,0, -0xaf057ff8af75c35e,0, -0xef82c7331c0ff1b2,0, -0xe3f5af99cc3aaaf8,0, -0xa37217527f409814,0, -0xe3257c1140304b84,0, -0xa3a2c4daf34a7968,0, -0x4c2003e9ef4588da,0, -0xca7bb225c3fba36,0, -0x4cf0d061634f69a6,0, -0xc7768aad0355b4a,0, -0x5a1db3b16a0b58b8,0, -0x1a9a0b7ad9716a54,0, -0x5acd6039e601b9c4,0, -0x1a4ad8f2557b8b28,0, -0xf5c81fc149747a9a,0, -0xb54fa70afa0e4876,0, -0xf518cc49c57e9be6,0, -0xb59f74827604a90a,0, -0xb9e81c28a631f240,0, -0xf96fa4e3154bc0ac,0, -0xb938cfa02a3b133c,0, -0xf9bf776b994121d0,0, -0x163db058854ed062,0, -0x56ba08933634e28e,0, -0x16ed63d00944311e,0, -0x566adb1bba3e03f2,0, -0x9947c54fe7ee248,0, -0x4913c49f4d04d0a4,0, -0x944afdc72740334,0, -0x49c31717c10e31d8,0, -0xa641d024dd01c06a,0, -0xe6c668ef6e7bf286,0, -0xa69103ac510b2116,0, -0xe616bb67e27113fa,0, -0xea61d3cd324448b0,0, -0xaae66b06813e7a5c,0, -0xeab10045be4ea9cc,0, -0xaa36b88e0d349b20,0, -0x45b47fbd113b6a92,0, -0x533c776a241587e,0, -0x4564ac359d318bee,0, -0x5e314fe2e4bb902,0, -0x5389cfe59475baf0,0, -0x130e772e270f881c,0, -0x53591c6d187f5b8c,0, -0x13dea4a6ab056960,0, -0xfc5c6395b70a98d2,0, -0xbcdbdb5e0470aa3e,0, -0xfc8cb01d3b0079ae,0, -0xbc0b08d6887a4b42,0, -0xb07c607c584f1008,0, -0xf0fbd8b7eb3522e4,0, -0xb0acb3f4d445f174,0, -0xf02b0b3f673fc398,0, -0x1fa9cc0c7b30322a,0, -0x5f2e74c7c84a00c6,0, -0x1f791f84f73ad356,0, -0x5ffea74f4440e1ba,0, -0xe8eaf0e0068f544,0, -0x4e0917c5b312c7a8,0, -0xe5e7c868c621438,0, -0x4ed9c44d3f1826d4,0, -0xa15b037e2317d766,0, -0xe1dcbbb5906de58a,0, -0xa18bd0f6af1d361a,0, -0xe10c683d1c6704f6,0, -0xed7b0097cc525fbc,0, -0xadfcb85c7f286d50,0, -0xedabd31f4058bec0,0, -0xad2c6bd4f3228c2c,0, -0x42aeace7ef2d7d9e,0, -0x229142c5c574f72,0, -0x427e7f6f63279ce2,0, -0x2f9c7a4d05dae0e,0, -0x54931cbf6a63adfc,0, -0x1414a474d9199f10,0, -0x5443cf37e6694c80,0, -0x14c477fc55137e6c,0, -0xfb46b0cf491c8fde,0, -0xbbc10804fa66bd32,0, -0xfb966347c5166ea2,0, -0xbb11db8c766c5c4e,0, -0xb766b326a6590704,0, -0xf7e10bed152335e8,0, -0xb7b660ae2a53e678,0, -0xf731d8659929d494,0, -0x18b31f5685262526,0, -0x5834a79d365c17ca,0, -0x1863ccde092cc45a,0, -0x58e47415ba56f6b6,0, -0x71ad35afe16170c,0, -0x479d6b914d6c25e0,0, -0x7ca00d2721cf670,0, -0x474db819c166c49c,0, -0xa8cf7f2add69352e,0, -0xe848c7e16e1307c2,0, -0xa81faca25163d452,0, -0xe8981469e219e6be,0, -0xe4ef7cc3322cbdf4,0, -0xa468c40881568f18,0, -0xe43faf4bbe265c88,0, -0xa4b817800d5c6e64,0, -0x4b3ad0b311539fd6,0, -0xbbd6878a229ad3a,0, -0x4bea033b9d597eaa,0, -0xb6dbbf02e234c46,0, -0x5d0760eb941d4fb4,0, -0x1d80d82027677d58,0, -0x5dd7b3631817aec8,0, -0x1d500ba8ab6d9c24,0, -0xf2d2cc9bb7626d96,0, -0xb255745004185f7a,0, -0xf2021f133b688cea,0, -0xb285a7d88812be06,0, -0xbef2cf725827e54c,0, -0xfe7577b9eb5dd7a0,0, -0xbe221cfad42d0430,0, -0xfea5a431675736dc,0, -0x112763027b58c76e,0, -0x51a0dbc9c822f582,0, -0x11f7b08af7522612,0, -0x51700841442814fe,0, -0xa2a113500b4b4f5a,0, -0xe226ab9bb8317db6,0, -0xa271c0d88741ae26,0, -0xe2f67813343b9cca,0, -0xd74bf2028346d78,0, -0x4df307eb9b4e5f94,0, -0xda46ca8a43e8c04,0, -0x4d23d4631744bee8,0, -0x4154bcc9c771e5a2,0, -0x1d30402740bd74e,0, -0x41846f414b7b04de,0, -0x103d78af8013632,0, -0xee8110b9e40ec780,0, -0xae06a8725774f56c,0, -0xee51c331680426fc,0, -0xaed67bfadb7e1410,0, -0xf8bca0e1614017e2,0, -0xb83b182ad23a250e,0, -0xf86c7369ed4af69e,0, -0xb8ebcba25e30c472,0, -0x57690c91423f35c0,0, -0x17eeb45af145072c,0, -0x57b9df19ce35d4bc,0, -0x173e67d27d4fe650,0, -0x1b490f78ad7abd1a,0, -0x5bceb7b31e008ff6,0, -0x1b99dcf021705c66,0, -0x5b1e643b920a6e8a,0, -0xb49ca3088e059f38,0, -0xf41b1bc33d7fadd4,0, -0xb44c7080020f7e44,0, -0xf4cbc84bb1754ca8,0, -0xab356f04f535ad12,0, -0xebb2d7cf464f9ffe,0, -0xabe5bc8c793f4c6e,0, -0xeb620447ca457e82,0, -0x4e0c374d64a8f30,0, -0x44677bbf6530bddc,0, -0x43010fc5a406e4c,0, -0x44b7a837e93a5ca0,0, -0x48c0c09d390f07ea,0, -0x84778568a753506,0, -0x48101315b505e696,0, -0x897abde067fd47a,0, -0xe7156ced1a7025c8,0, -0xa792d426a90a1724,0, -0xe7c5bf65967ac4b4,0, -0xa74207ae2500f658,0, -0xf128dcb59f3ef5aa,0, -0xb1af647e2c44c746,0, -0xf1f80f3d133414d6,0, -0xb17fb7f6a04e263a,0, -0x5efd70c5bc41d788,0, -0x1e7ac80e0f3be564,0, -0x5e2da34d304b36f4,0, -0x1eaa1b8683310418,0, -0x12dd732c53045f52,0, -0x525acbe7e07e6dbe,0, -0x120da0a4df0ebe2e,0, -0x528a186f6c748cc2,0, -0xbd08df5c707b7d70,0, -0xfd8f6797c3014f9c,0, -0xbdd80cd4fc719c0c,0, -0xfd5fb41f4f0baee0,0, -0xac2fbc5e0b23ba1e,0, -0xeca80495b85988f2,0, -0xacff6fd687295b62,0, -0xec78d71d3453698e,0, -0x3fa102e285c983c,0, -0x437da8e59b26aad0,0, -0x32ac3a6a4567940,0, -0x43ad7b6d172c4bac,0, -0x4fda13c7c71910e6,0, -0xf5dab0c7463220a,0, -0x4f0ac04f4b13f19a,0, -0xf8d7884f869c376,0, -0xe00fbfb7e46632c4,0, -0xa088077c571c0028,0, -0xe0df6c3f686cd3b8,0, -0xa058d4f4db16e154,0, -0xf6320fef6128e2a6,0, -0xb6b5b724d252d04a,0, -0xf6e2dc67ed2203da,0, -0xb66564ac5e583136,0, -0x59e7a39f4257c084,0, -0x19601b54f12df268,0, -0x59377017ce5d21f8,0, -0x19b0c8dc7d271314,0, -0x15c7a076ad12485e,0, -0x554018bd1e687ab2,0, -0x151773fe2118a922,0, -0x5590cb3592629bce,0, -0xba120c068e6d6a7c,0, -0xfa95b4cd3d175890,0, -0xbac2df8e02678b00,0, -0xfa456745b11db9ec,0, -0xa5bbc00af55d5856,0, -0xe53c78c146276aba,0, -0xa56b13827957b92a,0, -0xe5ecab49ca2d8bc6,0, -0xa6e6c7ad6227a74,0, -0x4ae9d4b165584898,0, -0xabebff25a289b08,0, -0x4a390739e952a9e4,0, -0x464e6f933967f2ae,0, -0x6c9d7588a1dc042,0, -0x469ebc1bb56d13d2,0, -0x61904d00617213e,0, -0xe99bc3e31a18d08c,0, -0xa91c7b28a962e260,0, -0xe94b106b961231f0,0, -0xa9cca8a02568031c,0, -0xffa673bb9f5600ee,0, -0xbf21cb702c2c3202,0, -0xff76a033135ce192,0, -0xbff118f8a026d37e,0, -0x5073dfcbbc2922cc,0, -0x10f467000f531020,0, -0x50a30c433023c3b0,0, -0x1024b4888359f15c,0, -0x1c53dc22536caa16,0, -0x5cd464e9e01698fa,0, -0x1c830faadf664b6a,0, -0x5c04b7616c1c7986,0, -0xb386705270138834,0, -0xf301c899c369bad8,0, -0xb356a3dafc196948,0, -0xf3d11b114f635ba4,0, -0x0,0, -0xe96f9805d6ce0bb0,0, -0x53496f8b5c9edd4c,0, -0xba26f78e8a50d6fc,0, -0xad325cb6f4ac2a9e,0, -0x445dc4b32262212e,0, -0xfe7b333da832f7d2,0, -0x1714ab387efcfc62,0, -0x4a8dcf8bd7ede826,0, -0xa3e2578e0123e396,0, -0x19c4a0008b73356a,0, -0xf0ab38055dbd3eda,0, -0xe7bf933d2341c2b8,0, -0xed00b38f58fc908,0, -0xb4f6fcb67fdf1ff4,0, -0x5d9964b3a9111444,0, -0xa3e9c552b6434210,0, -0x4a865d57608d49a0,0, -0xf0a0aad9eadd9f5c,0, -0x19cf32dc3c1394ec,0, -0xedb99e442ef688e,0, -0xe7b401e19421633e,0, -0x5d92f66f1e71b5c2,0, -0xb4fd6e6ac8bfbe72,0, -0xe9640ad961aeaa36,0, -0xb92dcb760a186,0, -0xba2d65523d30777a,0, -0x5342fd57ebfe7cca,0, -0x4456566f950280a8,0, -0xad39ce6a43cc8b18,0, -0x171f39e4c99c5de4,0, -0xfe70a1e11f525654,0, -0x5fa92ad9c9bc7ed0,0, -0xb6c6b2dc1f727560,0, -0xce045529522a39c,0, -0xe58fdd5743eca82c,0, -0xf29b766f3d10544e,0, -0x1bf4ee6aebde5ffe,0, -0xa1d219e4618e8902,0, -0x48bd81e1b74082b2,0, -0x1524e5521e5196f6,0, -0xfc4b7d57c89f9d46,0, -0x466d8ad942cf4bba,0, -0xaf0212dc9401400a,0, -0xb816b9e4eafdbc68,0, -0x517921e13c33b7d8,0, -0xeb5fd66fb6636124,0, -0x2304e6a60ad6a94,0, -0xfc40ef8b7fff3cc0,0, -0x152f778ea9313770,0, -0xaf0980002361e18c,0, -0x46661805f5afea3c,0, -0x5172b33d8b53165e,0, -0xb81d2b385d9d1dee,0, -0x23bdcb6d7cdcb12,0, -0xeb5444b30103c0a2,0, -0xb6cd2000a812d4e6,0, -0x5fa2b8057edcdf56,0, -0xe5844f8bf48c09aa,0, -0xcebd78e2242021a,0, -0x1bff7cb65cbefe78,0, -0xf290e4b38a70f5c8,0, -0x48b6133d00202334,0, -0xa1d98b38d6ee2884,0, -0xa389f910cd7734de,0, -0x4ae661151bb93f6e,0, -0xf0c0969b91e9e992,0, -0x19af0e9e4727e222,0, -0xebba5a639db1e40,0, -0xe7d43da3ef1515f0,0, -0x5df2ca2d6545c30c,0, -0xb49d5228b38bc8bc,0, -0xe904369b1a9adcf8,0, -0x6bae9ecc54d748,0, -0xba4d5910460401b4,0, -0x5322c11590ca0a04,0, -0x44366a2dee36f666,0, -0xad59f22838f8fdd6,0, -0x177f05a6b2a82b2a,0, -0xfe109da36466209a,0, -0x603c427b3476ce,0, -0xe90fa447adfa7d7e,0, -0x532953c927aaab82,0, -0xba46cbccf164a032,0, -0xad5260f48f985c50,0, -0x443df8f1595657e0,0, -0xfe1b0f7fd306811c,0, -0x1774977a05c88aac,0, -0x4aedf3c9acd99ee8,0, -0xa3826bcc7a179558,0, -0x19a49c42f04743a4,0, -0xf0cb044726894814,0, -0xe7dfaf7f5875b476,0, -0xeb0377a8ebbbfc6,0, -0xb496c0f404eb693a,0, -0x5df958f1d225628a,0, -0xfc20d3c904cb4a0e,0, -0x154f4bccd20541be,0, -0xaf69bc4258559742,0, -0x460624478e9b9cf2,0, -0x51128f7ff0676090,0, -0xb87d177a26a96b20,0, -0x25be0f4acf9bddc,0, -0xeb3478f17a37b66c,0, -0xb6ad1c42d326a228,0, -0x5fc2844705e8a998,0, -0xe5e473c98fb87f64,0, -0xc8bebcc597674d4,0, -0x1b9f40f4278a88b6,0, -0xf2f0d8f1f1448306,0, -0x48d62f7f7b1455fa,0, -0xa1b9b77aadda5e4a,0, -0x5fc9169bb288081e,0, -0xb6a68e9e644603ae,0, -0xc807910ee16d552,0, -0xe5efe11538d8dee2,0, -0xf2fb4a2d46242280,0, -0x1b94d22890ea2930,0, -0xa1b225a61abaffcc,0, -0x48ddbda3cc74f47c,0, -0x1544d9106565e038,0, -0xfc2b4115b3abeb88,0, -0x460db69b39fb3d74,0, -0xaf622e9eef3536c4,0, -0xb87685a691c9caa6,0, -0x51191da34707c116,0, -0xeb3fea2dcd5717ea,0, -0x25072281b991c5a,0, -0xe916f3dfca4609d8,0, -0x796bda1c880268,0, -0xba5f9c5496d8d494,0, -0x533004514016df24,0, -0x4424af693eea2346,0, -0xad4b376ce82428f6,0, -0x176dc0e26274fe0a,0, -0xfe0258e7b4baf5ba,0, -0xa39b3c541dabe1fe,0, -0x4af4a451cb65ea4e,0, -0xf0d253df41353cb2,0, -0x19bdcbda97fb3702,0, -0xea960e2e907cb60,0, -0xe7c6f8e73fc9c0d0,0, -0x5de00f69b599162c,0, -0xb48f976c63571d9c,0, -0x4aff368d7c054bc8,0, -0xa390ae88aacb4078,0, -0x19b65906209b9684,0, -0xf0d9c103f6559d34,0, -0xe7cd6a3b88a96156,0, -0xea2f23e5e676ae6,0, -0xb48405b0d437bc1a,0, -0x5deb9db502f9b7aa,0, -0x72f906abe8a3ee,0, -0xe91d61037d26a85e,0, -0x533b968df7767ea2,0, -0xba540e8821b87512,0, -0xad40a5b05f448970,0, -0x442f3db5898a82c0,0, -0xfe09ca3b03da543c,0, -0x1766523ed5145f8c,0, -0xb6bfd90603fa7708,0, -0x5fd04103d5347cb8,0, -0xe5f6b68d5f64aa44,0, -0xc992e8889aaa1f4,0, -0x1b8d85b0f7565d96,0, -0xf2e21db521985626,0, -0x48c4ea3babc880da,0, -0xa1ab723e7d068b6a,0, -0xfc32168dd4179f2e,0, -0x155d8e8802d9949e,0, -0xaf7b790688894262,0, -0x4614e1035e4749d2,0, -0x51004a3b20bbb5b0,0, -0xb86fd23ef675be00,0, -0x24925b07c2568fc,0, -0xeb26bdb5aaeb634c,0, -0x15561c54b5b93518,0, -0xfc39845163773ea8,0, -0x461f73dfe927e854,0, -0xaf70ebda3fe9e3e4,0, -0xb86440e241151f86,0, -0x510bd8e797db1436,0, -0xeb2d2f691d8bc2ca,0, -0x242b76ccb45c97a,0, -0x5fdbd3df6254dd3e,0, -0xb6b44bdab49ad68e,0, -0xc92bc543eca0072,0, -0xe5fd2451e8040bc2,0, -0xf2e98f6996f8f7a0,0, -0x1b86176c4036fc10,0, -0xa1a0e0e2ca662aec,0, -0x48cf78e71ca8215c,0, -0x4a9f0acf07313d06,0, -0xa3f092cad1ff36b6,0, -0x19d665445bafe04a,0, -0xf0b9fd418d61ebfa,0, -0xe7ad5679f39d1798,0, -0xec2ce7c25531c28,0, -0xb4e439f2af03cad4,0, -0x5d8ba1f779cdc164,0, -0x12c544d0dcd520,0, -0xe97d5d410612de90,0, -0x535baacf8c42086c,0, -0xba3432ca5a8c03dc,0, -0xad2099f22470ffbe,0, -0x444f01f7f2bef40e,0, -0xfe69f67978ee22f2,0, -0x17066e7cae202942,0, -0xe976cf9db1727f16,0, -0x19579867bc74a6,0, -0xba3fa016edeca25a,0, -0x535038133b22a9ea,0, -0x4444932b45de5588,0, -0xad2b0b2e93105e38,0, -0x170dfca0194088c4,0, -0xfe6264a5cf8e8374,0, -0xa3fb0016669f9730,0, -0x4a949813b0519c80,0, -0xf0b26f9d3a014a7c,0, -0x19ddf798eccf41cc,0, -0xec95ca09233bdae,0, -0xe7a6c4a544fdb61e,0, -0x5d80332bcead60e2,0, -0xb4efab2e18636b52,0, -0x15362016ce8d43d6,0, -0xfc59b81318434866,0, -0x467f4f9d92139e9a,0, -0xaf10d79844dd952a,0, -0xb8047ca03a216948,0, -0x516be4a5ecef62f8,0, -0xeb4d132b66bfb404,0, -0x2228b2eb071bfb4,0, -0x5fbbef9d1960abf0,0, -0xb6d47798cfaea040,0, -0xcf2801645fe76bc,0, -0xe59d181393307d0c,0, -0xf289b32bedcc816e,0, -0x1be62b2e3b028ade,0, -0xa1c0dca0b1525c22,0, -0x48af44a5679c5792,0, -0xb6dfe54478ce01c6,0, -0x5fb07d41ae000a76,0, -0xe5968acf2450dc8a,0, -0xcf912caf29ed73a,0, -0x1bedb9f28c622b58,0, -0xf28221f75aac20e8,0, -0x48a4d679d0fcf614,0, -0xa1cb4e7c0632fda4,0, -0xfc522acfaf23e9e0,0, -0x153db2ca79ede250,0, -0xaf1b4544f3bd34ac,0, -0x4674dd4125733f1c,0, -0x516076795b8fc37e,0, -0xb80fee7c8d41c8ce,0, -0x22919f207111e32,0, -0xeb4681f7d1df1582,0, -0x0,0, -0xf89578714bd28f96,0, -0x564dda59237a3352,0, -0xaed8a22868a8bcc4,0, -0xad33bc6cc75aed38,0, -0x55a6c41d8c8862ae,0, -0xfb7e6635e420de6a,0, -0x3eb1e44aff251fc,0, -0x57a3104fcd0e5f34,0, -0xaf36683e86dcd0a2,0, -0x1eeca16ee746c66,0, -0xf97bb267a5a6e3f0,0, -0xfa90ac230a54b20c,0, -0x205d45241863d9a,0, -0xacdd767a292e815e,0, -0x54480e0b62fc0ec8,0, -0xb0f502e4cd60039a,0, -0x48607a9586b28c0c,0, -0xe6b8d8bdee1a30c8,0, -0x1e2da0cca5c8bf5e,0, -0x1dc6be880a3aeea2,0, -0xe553c6f941e86134,0, -0x4b8b64d12940ddf0,0, -0xb31e1ca062925266,0, -0xe75612ab006e5cae,0, -0x1fc36ada4bbcd338,0, -0xb11bc8f223146ffc,0, -0x498eb08368c6e06a,0, -0x4a65aec7c734b196,0, -0xb2f0d6b68ce63e00,0, -0x1c28749ee44e82c4,0, -0xe4bd0cefaf9c0d52,0, -0xeb42e79f91f49f8c,0, -0x13d79feeda26101a,0, -0xbd0f3dc6b28eacde,0, -0x459a45b7f95c2348,0, -0x46715bf356ae72b4,0, -0xbee423821d7cfd22,0, -0x103c81aa75d441e6,0, -0xe8a9f9db3e06ce70,0, -0xbce1f7d05cfac0b8,0, -0x44748fa117284f2e,0, -0xeaac2d897f80f3ea,0, -0x123955f834527c7c,0, -0x11d24bbc9ba02d80,0, -0xe94733cdd072a216,0, -0x479f91e5b8da1ed2,0, -0xbf0ae994f3089144,0, -0x5bb7e57b5c949c16,0, -0xa3229d0a17461380,0, -0xdfa3f227feeaf44,0, -0xf56f4753343c20d2,0, -0xf68459179bce712e,0, -0xe112166d01cfeb8,0, -0xa0c9834eb8b4427c,0, -0x585cfb3ff366cdea,0, -0xc14f534919ac322,0, -0xf4818d45da484cb4,0, -0x5a592f6db2e0f070,0, -0xa2cc571cf9327fe6,0, -0xa127495856c02e1a,0, -0x59b231291d12a18c,0, -0xf76a930175ba1d48,0, -0xfffeb703e6892de,0, -0x54e5bf3774b3f850,0, -0xac70c7463f6177c6,0, -0x2a8656e57c9cb02,0, -0xfa3d1d1f1c1b4494,0, -0xf9d6035bb3e91568,0, -0x1437b2af83b9afe,0, -0xaf9bd9029093263a,0, -0x570ea173db41a9ac,0, -0x346af78b9bda764,0, -0xfbd3d709f26f28f2,0, -0x550b75219ac79436,0, -0xad9e0d50d1151ba0,0, -0xae7513147ee74a5c,0, -0x56e06b653535c5ca,0, -0xf838c94d5d9d790e,0, -0xadb13c164ff698,0, -0xe410bdd3b9d3fbca,0, -0x1c85c5a2f201745c,0, -0xb25d678a9aa9c898,0, -0x4ac81ffbd17b470e,0, -0x492301bf7e8916f2,0, -0xb1b679ce355b9964,0, -0x1f6edbe65df325a0,0, -0xe7fba3971621aa36,0, -0xb3b3ad9c74dda4fe,0, -0x4b26d5ed3f0f2b68,0, -0xe5fe77c557a797ac,0, -0x1d6b0fb41c75183a,0, -0x1e8011f0b38749c6,0, -0xe6156981f855c650,0, -0x48cdcba990fd7a94,0, -0xb058b3d8db2ff502,0, -0xbfa758a8e54767dc,0, -0x473220d9ae95e84a,0, -0xe9ea82f1c63d548e,0, -0x117ffa808defdb18,0, -0x1294e4c4221d8ae4,0, -0xea019cb569cf0572,0, -0x44d93e9d0167b9b6,0, -0xbc4c46ec4ab53620,0, -0xe80448e7284938e8,0, -0x10913096639bb77e,0, -0xbe4992be0b330bba,0, -0x46dceacf40e1842c,0, -0x4537f48bef13d5d0,0, -0xbda28cfaa4c15a46,0, -0x137a2ed2cc69e682,0, -0xebef56a387bb6914,0, -0xf525a4c28276446,0, -0xf7c7223d63f5ebd0,0, -0x591f80150b5d5714,0, -0xa18af864408fd882,0, -0xa261e620ef7d897e,0, -0x5af49e51a4af06e8,0, -0xf42c3c79cc07ba2c,0, -0xcb9440887d535ba,0, -0x58f14a03e5293b72,0, -0xa0643272aefbb4e4,0, -0xebc905ac6530820,0, -0xf629e82b8d8187b6,0, -0xf5c2f66f2273d64a,0, -0xd578e1e69a159dc,0, -0xa38f2c360109e518,0, -0x5b1a54474adb6a8e,0, -0xb66864e6ec14b4d2,0, -0x4efd1c97a7c63b44,0, -0xe025bebfcf6e8780,0, -0x18b0c6ce84bc0816,0, -0x1b5bd88a2b4e59ea,0, -0xe3cea0fb609cd67c,0, -0x4d1602d308346ab8,0, -0xb5837aa243e6e52e,0, -0xe1cb74a9211aebe6,0, -0x195e0cd86ac86470,0, -0xb786aef00260d8b4,0, -0x4f13d68149b25722,0, -0x4cf8c8c5e64006de,0, -0xb46db0b4ad928948,0, -0x1ab5129cc53a358c,0, -0xe2206aed8ee8ba1a,0, -0x69d66022174b748,0, -0xfe081e736aa638de,0, -0x50d0bc5b020e841a,0, -0xa845c42a49dc0b8c,0, -0xabaeda6ee62e5a70,0, -0x533ba21fadfcd5e6,0, -0xfde30037c5546922,0, -0x57678468e86e6b4,0, -0x513e764dec7ae87c,0, -0xa9ab0e3ca7a867ea,0, -0x773ac14cf00db2e,0, -0xffe6d46584d254b8,0, -0xfc0dca212b200544,0, -0x498b25060f28ad2,0, -0xaa401078085a3616,0, -0x52d568094388b980,0, -0x5d2a83797de02b5e,0, -0xa5bffb083632a4c8,0, -0xb6759205e9a180c,0, -0xf3f221511548979a,0, -0xf0193f15babac666,0, -0x88c4764f16849f0,0, -0xa654e54c99c0f534,0, -0x5ec19d3dd2127aa2,0, -0xa899336b0ee746a,0, -0xf21ceb47fb3cfbfc,0, -0x5cc4496f93944738,0, -0xa451311ed846c8ae,0, -0xa7ba2f5a77b49952,0, -0x5f2f572b3c6616c4,0, -0xf1f7f50354ceaa00,0, -0x9628d721f1c2596,0, -0xeddf819db08028c4,0, -0x154af9ecfb52a752,0, -0xbb925bc493fa1b96,0, -0x430723b5d8289400,0, -0x40ec3df177dac5fc,0, -0xb87945803c084a6a,0, -0x16a1e7a854a0f6ae,0, -0xee349fd91f727938,0, -0xba7c91d27d8e77f0,0, -0x42e9e9a3365cf866,0, -0xec314b8b5ef444a2,0, -0x14a433fa1526cb34,0, -0x174f2dbebad49ac8,0, -0xefda55cff106155e,0, -0x4102f7e799aea99a,0, -0xb9978f96d27c260c,0, -0xe28ddbd198a74c82,0, -0x1a18a3a0d375c314,0, -0xb4c00188bbdd7fd0,0, -0x4c5579f9f00ff046,0, -0x4fbe67bd5ffda1ba,0, -0xb72b1fcc142f2e2c,0, -0x19f3bde47c8792e8,0, -0xe166c59537551d7e,0, -0xb52ecb9e55a913b6,0, -0x4dbbb3ef1e7b9c20,0, -0xe36311c776d320e4,0, -0x1bf669b63d01af72,0, -0x181d77f292f3fe8e,0, -0xe0880f83d9217118,0, -0x4e50adabb189cddc,0, -0xb6c5d5dafa5b424a,0, -0x5278d93555c74f18,0, -0xaaeda1441e15c08e,0, -0x435036c76bd7c4a,0, -0xfca07b1d3d6ff3dc,0, -0xff4b6559929da220,0, -0x7de1d28d94f2db6,0, -0xa906bf00b1e79172,0, -0x5193c771fa351ee4,0, -0x5dbc97a98c9102c,0, -0xfd4eb10bd31b9fba,0, -0x53961323bbb3237e,0, -0xab036b52f061ace8,0, -0xa8e875165f93fd14,0, -0x507d0d6714417282,0, -0xfea5af4f7ce9ce46,0, -0x630d73e373b41d0,0, -0x9cf3c4e0953d30e,0, -0xf15a443f42815c98,0, -0x5f82e6172a29e05c,0, -0xa7179e6661fb6fca,0, -0xa4fc8022ce093e36,0, -0x5c69f85385dbb1a0,0, -0xf2b15a7bed730d64,0, -0xa24220aa6a182f2,0, -0x5e6c2c01c45d8c3a,0, -0xa6f954708f8f03ac,0, -0x821f658e727bf68,0, -0xf0b48e29acf530fe,0, -0xf35f906d03076102,0, -0xbcae81c48d5ee94,0, -0xa5124a34207d5250,0, -0x5d8732456bafddc6,0, -0xb93a3eaac433d094,0, -0x41af46db8fe15f02,0, -0xef77e4f3e749e3c6,0, -0x17e29c82ac9b6c50,0, -0x140982c603693dac,0, -0xec9cfab748bbb23a,0, -0x4244589f20130efe,0, -0xbad120ee6bc18168,0, -0xee992ee5093d8fa0,0, -0x160c569442ef0036,0, -0xb8d4f4bc2a47bcf2,0, -0x40418ccd61953364,0, -0x43aa9289ce676298,0, -0xbb3feaf885b5ed0e,0, -0x15e748d0ed1d51ca,0, -0xed7230a1a6cfde5c,0, -0x0,0, -0xed57ce778f0d6244,0, -0x523aaf9d6148ba24,0, -0xbf6d61eaee45d860,0, -0xa8fcbfaac14940c6,0, -0x45ab71dd4e442282,0, -0xfac61037a001fae2,0, -0x1791de402f0c98a6,0, -0xe503eacfcef77780,0, -0x85424b841fa15c4,0, -0xb7394552afbfcda4,0, -0x5a6e8b2520b2afe0,0, -0x4dff55650fbe3746,0, -0xa0a89b1280b35502,0, -0x1fc5faf86ef68d62,0, -0xf292348fe1fbef26,0, -0xf3746c7b5183a372,0, -0x1e23a20cde8ec136,0, -0xa14ec3e630cb1956,0, -0x4c190d91bfc67b12,0, -0x5b88d3d190cae3b4,0, -0xb6df1da61fc781f0,0, -0x9b27c4cf1825990,0, -0xe4e5b23b7e8f3bd4,0, -0x167786b49f74d4f2,0, -0xfb2048c31079b6b6,0, -0x444d2929fe3c6ed6,0, -0xa91ae75e71310c92,0, -0xbe8b391e5e3d9434,0, -0x53dcf769d130f670,0, -0xecb196833f752e10,0, -0x1e658f4b0784c54,0, -0xec50d77d2f416218,0, -0x107190aa04c005c,0, -0xbe6a78e04e09d83c,0, -0x533db697c104ba78,0, -0x44ac68d7ee0822de,0, -0xa9fba6a06105409a,0, -0x1696c74a8f4098fa,0, -0xfbc1093d004dfabe,0, -0x9533db2e1b61598,0, -0xe404f3c56ebb77dc,0, -0x5b69922f80feafbc,0, -0xb63e5c580ff3cdf8,0, -0xa1af821820ff555e,0, -0x4cf84c6faff2371a,0, -0xf3952d8541b7ef7a,0, -0x1ec2e3f2ceba8d3e,0, -0x1f24bb067ec2c16a,0, -0xf2737571f1cfa32e,0, -0x4d1e149b1f8a7b4e,0, -0xa049daec9087190a,0, -0xb7d804acbf8b81ac,0, -0x5a8fcadb3086e3e8,0, -0xe5e2ab31dec33b88,0, -0x8b5654651ce59cc,0, -0xfa2751c9b035b6ea,0, -0x17709fbe3f38d4ae,0, -0xa81dfe54d17d0cce,0, -0x454a30235e706e8a,0, -0x52dbee63717cf62c,0, -0xbf8c2014fe719468,0, -0xe141fe10344c08,0, -0xedb68f899f392e4c,0, -0xf9cdf54569fe87e6,0, -0x149a3b32e6f3e5a2,0, -0xabf75ad808b63dc2,0, -0x46a094af87bb5f86,0, -0x51314aefa8b7c720,0, -0xbc66849827baa564,0, -0x30be572c9ff7d04,0, -0xee5c2b0546f21f40,0, -0x1cce1f8aa709f066,0, -0xf199d1fd28049222,0, -0x4ef4b017c6414a42,0, -0xa3a37e60494c2806,0, -0xb432a0206640b0a0,0, -0x59656e57e94dd2e4,0, -0xe6080fbd07080a84,0, -0xb5fc1ca880568c0,0, -0xab9993e387d2494,0, -0xe7ee5749b77046d0,0, -0x588336a359359eb0,0, -0xb5d4f8d4d638fcf4,0, -0xa2452694f9346452,0, -0x4f12e8e376390616,0, -0xf07f8909987cde76,0, -0x1d28477e1771bc32,0, -0xefba73f1f68a5314,0, -0x2edbd8679873150,0, -0xbd80dc6c97c2e930,0, -0x50d7121b18cf8b74,0, -0x4746cc5b37c313d2,0, -0xaa11022cb8ce7196,0, -0x157c63c6568ba9f6,0, -0xf82badb1d986cbb2,0, -0x159d223846bfe5fe,0, -0xf8caec4fc9b287ba,0, -0x47a78da527f75fda,0, -0xaaf043d2a8fa3d9e,0, -0xbd619d9287f6a538,0, -0x503653e508fbc77c,0, -0xef5b320fe6be1f1c,0, -0x20cfc7869b37d58,0, -0xf09ec8f78848927e,0, -0x1dc906800745f03a,0, -0xa2a4676ae900285a,0, -0x4ff3a91d660d4a1e,0, -0x5862775d4901d2b8,0, -0xb535b92ac60cb0fc,0, -0xa58d8c02849689c,0, -0xe70f16b7a7440ad8,0, -0xe6e94e43173c468c,0, -0xbbe8034983124c8,0, -0xb4d3e1de7674fca8,0, -0x59842fa9f9799eec,0, -0x4e15f1e9d675064a,0, -0xa3423f9e5978640e,0, -0x1c2f5e74b73dbc6e,0, -0xf17890033830de2a,0, -0x3eaa48cd9cb310c,0, -0xeebd6afb56c65348,0, -0x51d00b11b8838b28,0, -0xbc87c566378ee96c,0, -0xab161b26188271ca,0, -0x4641d551978f138e,0, -0xf92cb4bb79cacbee,0, -0x147b7accf6c7a9aa,0, -0xe576269915705e2c,0, -0x821e8ee9a7d3c68,0, -0xb74c89047438e408,0, -0x5a1b4773fb35864c,0, -0x4d8a9933d4391eea,0, -0xa0dd57445b347cae,0, -0x1fb036aeb571a4ce,0, -0xf2e7f8d93a7cc68a,0, -0x75cc56db8729ac,0, -0xed220221548a4be8,0, -0x524f63cbbacf9388,0, -0xbf18adbc35c2f1cc,0, -0xa88973fc1ace696a,0, -0x45debd8b95c30b2e,0, -0xfab3dc617b86d34e,0, -0x17e41216f48bb10a,0, -0x16024ae244f3fd5e,0, -0xfb558495cbfe9f1a,0, -0x4438e57f25bb477a,0, -0xa96f2b08aab6253e,0, -0xbefef54885babd98,0, -0x53a93b3f0ab7dfdc,0, -0xecc45ad5e4f207bc,0, -0x19394a26bff65f8,0, -0xf301a02d8a048ade,0, -0x1e566e5a0509e89a,0, -0xa13b0fb0eb4c30fa,0, -0x4c6cc1c7644152be,0, -0x5bfd1f874b4dca18,0, -0xb6aad1f0c440a85c,0, -0x9c7b01a2a05703c,0, -0xe4907e6da5081278,0, -0x926f1e43a313c34,0, -0xe4713f93b53c5e70,0, -0x5b1c5e795b798610,0, -0xb64b900ed474e454,0, -0xa1da4e4efb787cf2,0, -0x4c8d803974751eb6,0, -0xf3e0e1d39a30c6d6,0, -0x1eb72fa4153da492,0, -0xec251b2bf4c64bb4,0, -0x172d55c7bcb29f0,0, -0xbe1fb4b6958ef190,0, -0x53487ac11a8393d4,0, -0x44d9a481358f0b72,0, -0xa98e6af6ba826936,0, -0x16e30b1c54c7b156,0, -0xfbb4c56bdbcad312,0, -0xfa529d9f6bb29f46,0, -0x170553e8e4bffd02,0, -0xa86832020afa2562,0, -0x453ffc7585f74726,0, -0x52ae2235aafbdf80,0, -0xbff9ec4225f6bdc4,0, -0x948da8cbb365a4,0, -0xedc343df44be07e0,0, -0x1f517750a545e8c6,0, -0xf206b9272a488a82,0, -0x4d6bd8cdc40d52e2,0, -0xa03c16ba4b0030a6,0, -0xb7adc8fa640ca800,0, -0x5afa068deb01ca44,0, -0xe597676705441224,0, -0x8c0a9108a497060,0, -0x1cbbd3dc7c8ed9ca,0, -0xf1ec1dabf383bb8e,0, -0x4e817c411dc663ee,0, -0xa3d6b23692cb01aa,0, -0xb4476c76bdc7990c,0, -0x5910a20132cafb48,0, -0xe67dc3ebdc8f2328,0, -0xb2a0d9c5382416c,0, -0xf9b83913b279ae4a,0, -0x14eff7643d74cc0e,0, -0xab82968ed331146e,0, -0x46d558f95c3c762a,0, -0x514486b97330ee8c,0, -0xbc1348cefc3d8cc8,0, -0x37e2924127854a8,0, -0xee29e7539d7536ec,0, -0xefcfbfa72d0d7ab8,0, -0x29871d0a20018fc,0, -0xbdf5103a4c45c09c,0, -0x50a2de4dc348a2d8,0, -0x4733000dec443a7e,0, -0xaa64ce7a6349583a,0, -0x1509af908d0c805a,0, -0xf85e61e70201e21e,0, -0xacc5568e3fa0d38,0, -0xe79b9b1f6cf76f7c,0, -0x58f6faf582b2b71c,0, -0xb5a134820dbfd558,0, -0xa230eac222b34dfe,0, -0x4f6724b5adbe2fba,0, -0xf00a455f43fbf7da,0, -0x1d5d8b28ccf6959e,0, -0xf0eb04a153cfbbd2,0, -0x1dbccad6dcc2d996,0, -0xa2d1ab3c328701f6,0, -0x4f86654bbd8a63b2,0, -0x5817bb0b9286fb14,0, -0xb540757c1d8b9950,0, -0xa2d1496f3ce4130,0, -0xe77adae17cc32374,0, -0x15e8ee6e9d38cc52,0, -0xf8bf20191235ae16,0, -0x47d241f3fc707676,0, -0xaa858f84737d1432,0, -0xbd1451c45c718c94,0, -0x50439fb3d37ceed0,0, -0xef2efe593d3936b0,0, -0x279302eb23454f4,0, -0x39f68da024c18a0,0, -0xeec8a6ad8d417ae4,0, -0x51a5c7476304a284,0, -0xbcf20930ec09c0c0,0, -0xab63d770c3055866,0, -0x463419074c083a22,0, -0xf95978eda24de242,0, -0x140eb69a2d408006,0, -0xe69c8215ccbb6f20,0, -0xbcb4c6243b60d64,0, -0xb4a62d88adf3d504,0, -0x59f1e3ff22feb740,0, -0x4e603dbf0df22fe6,0, -0xa337f3c882ff4da2,0, -0x1c5a92226cba95c2,0, -0xf10d5c55e3b7f786,0, -0x0,0, -0xee2a197148fa8c72,0, -0x49e31453575f365a,0, -0xa7c90d221fa5ba28,0, -0xb86698d88add0bc0,0, -0x564c81a9c22787b2,0, -0xf1858c8bdd823d9a,0, -0x1faf95fa9578b1e8,0, -0x4f35fb218e7f37c0,0, -0xa11fe250c685bbb2,0, -0x6d6ef72d920019a,0, -0xe8fcf60391da8de8,0, -0xf75363f904a23c00,0, -0x19797a884c58b072,0, -0xbeb077aa53fd0a5a,0, -0x509a6edb1b078628,0, -0xa306feea8a242832,0, -0x4d2ce79bc2dea440,0, -0xeae5eab9dd7b1e68,0, -0x4cff3c89581921a,0, -0x1b60663200f923f2,0, -0xf54a7f434803af80,0, -0x5283726157a615a8,0, -0xbca96b101f5c99da,0, -0xec3305cb045b1ff2,0, -0x2191cba4ca19380,0, -0xa5d01198530429a8,0, -0x4bfa08e91bfea5da,0, -0x54559d138e861432,0, -0xba7f8462c67c9840,0, -0x1db68940d9d92268,0, -0xf39c90319123ae1a,0, -0x5e5f06a9daead6e6,0, -0xb0751fd892105a94,0, -0x17bc12fa8db5e0bc,0, -0xf9960b8bc54f6cce,0, -0xe6399e715037dd26,0, -0x813870018cd5154,0, -0xafda8a220768eb7c,0, -0x41f093534f92670e,0, -0x116afd885495e126,0, -0xff40e4f91c6f6d54,0, -0x5889e9db03cad77c,0, -0xb6a3f0aa4b305b0e,0, -0xa90c6550de48eae6,0, -0x47267c2196b26694,0, -0xe0ef71038917dcbc,0, -0xec56872c1ed50ce,0, -0xfd59f84350cefed4,0, -0x1373e132183472a6,0, -0xb4baec100791c88e,0, -0x5a90f5614f6b44fc,0, -0x453f609bda13f514,0, -0xab1579ea92e97966,0, -0xcdc74c88d4cc34e,0, -0xe2f66db9c5b64f3c,0, -0xb26c0362deb1c914,0, -0x5c461a13964b4566,0, -0xfb8f173189eeff4e,0, -0x15a50e40c114733c,0, -0xa0a9bba546cc2d4,0, -0xe42082cb1c964ea6,0, -0x43e98fe90333f48e,0, -0xadc396984bc978fc,0, -0xbe13089ecc784ea0,0, -0x503911ef8482c2d2,0, -0xf7f01ccd9b2778fa,0, -0x19da05bcd3ddf488,0, -0x675904646a54560,0, -0xe85f89370e5fc912,0, -0x4f96841511fa733a,0, -0xa1bc9d645900ff48,0, -0xf126f3bf42077960,0, -0x1f0ceace0afdf512,0, -0xb8c5e7ec15584f3a,0, -0x56effe9d5da2c348,0, -0x49406b67c8da72a0,0, -0xa76a72168020fed2,0, -0xa37f349f8544fa,0, -0xee896645d77fc888,0, -0x1d15f674465c6692,0, -0xf33fef050ea6eae0,0, -0x54f6e227110350c8,0, -0xbadcfb5659f9dcba,0, -0xa5736eaccc816d52,0, -0x4b5977dd847be120,0, -0xec907aff9bde5b08,0, -0x2ba638ed324d77a,0, -0x52200d55c8235152,0, -0xbc0a142480d9dd20,0, -0x1bc319069f7c6708,0, -0xf5e90077d786eb7a,0, -0xea46958d42fe5a92,0, -0x46c8cfc0a04d6e0,0, -0xa3a581de15a16cc8,0, -0x4d8f98af5d5be0ba,0, -0xe04c0e3716929846,0, -0xe6617465e681434,0, -0xa9af1a6441cdae1c,0, -0x478503150937226e,0, -0x582a96ef9c4f9386,0, -0xb6008f9ed4b51ff4,0, -0x11c982bccb10a5dc,0, -0xffe39bcd83ea29ae,0, -0xaf79f51698edaf86,0, -0x4153ec67d01723f4,0, -0xe69ae145cfb299dc,0, -0x8b0f834874815ae,0, -0x171f6dce1230a446,0, -0xf93574bf5aca2834,0, -0x5efc799d456f921c,0, -0xb0d660ec0d951e6e,0, -0x434af0dd9cb6b074,0, -0xad60e9acd44c3c06,0, -0xaa9e48ecbe9862e,0, -0xe483fdff83130a5c,0, -0xfb2c6805166bbbb4,0, -0x150671745e9137c6,0, -0xb2cf7c5641348dee,0, -0x5ce5652709ce019c,0, -0xc7f0bfc12c987b4,0, -0xe255128d5a330bc6,0, -0x459c1faf4596b1ee,0, -0xabb606de0d6c3d9c,0, -0xb419932498148c74,0, -0x5a338a55d0ee0006,0, -0xfdfa8777cf4bba2e,0, -0x13d09e0687b1365c,0, -0xfe1a10738739c892,0, -0x10300902cfc344e0,0, -0xb7f90420d066fec8,0, -0x59d31d51989c72ba,0, -0x467c88ab0de4c352,0, -0xa85691da451e4f20,0, -0xf9f9cf85abbf508,0, -0xe1b585891241797a,0, -0xb12feb520946ff52,0, -0x5f05f22341bc7320,0, -0xf8ccff015e19c908,0, -0x16e6e67016e3457a,0, -0x949738a839bf492,0, -0xe7636afbcb6178e0,0, -0x40aa67d9d4c4c2c8,0, -0xae807ea89c3e4eba,0, -0x5d1cee990d1de0a0,0, -0xb336f7e845e76cd2,0, -0x14fffaca5a42d6fa,0, -0xfad5e3bb12b85a88,0, -0xe57a764187c0eb60,0, -0xb506f30cf3a6712,0, -0xac996212d09fdd3a,0, -0x42b37b6398655148,0, -0x122915b88362d760,0, -0xfc030cc9cb985b12,0, -0x5bca01ebd43de13a,0, -0xb5e0189a9cc76d48,0, -0xaa4f8d6009bfdca0,0, -0x44659411414550d2,0, -0xe3ac99335ee0eafa,0, -0xd868042161a6688,0, -0xa04516da5dd31e74,0, -0x4e6f0fab15299206,0, -0xe9a602890a8c282e,0, -0x78c1bf84276a45c,0, -0x18238e02d70e15b4,0, -0xf60997739ff499c6,0, -0x51c09a51805123ee,0, -0xbfea8320c8abaf9c,0, -0xef70edfbd3ac29b4,0, -0x15af48a9b56a5c6,0, -0xa693f9a884f31fee,0, -0x48b9e0d9cc09939c,0, -0x5716752359712274,0, -0xb93c6c52118bae06,0, -0x1ef561700e2e142e,0, -0xf0df780146d4985c,0, -0x343e830d7f73646,0, -0xed69f1419f0dba34,0, -0x4aa0fc6380a8001c,0, -0xa48ae512c8528c6e,0, -0xbb2570e85d2a3d86,0, -0x550f699915d0b1f4,0, -0xf2c664bb0a750bdc,0, -0x1cec7dca428f87ae,0, -0x4c76131159880186,0, -0xa25c0a6011728df4,0, -0x59507420ed737dc,0, -0xebbf1e33462dbbae,0, -0xf4108bc9d3550a46,0, -0x1a3a92b89baf8634,0, -0xbdf39f9a840a3c1c,0, -0x53d986ebccf0b06e,0, -0x400918ed4b418632,0, -0xae23019c03bb0a40,0, -0x9ea0cbe1c1eb068,0, -0xe7c015cf54e43c1a,0, -0xf86f8035c19c8df2,0, -0x1645994489660180,0, -0xb18c946696c3bba8,0, -0x5fa68d17de3937da,0, -0xf3ce3ccc53eb1f2,0, -0xe116fabd8dc43d80,0, -0x46dff79f926187a8,0, -0xa8f5eeeeda9b0bda,0, -0xb75a7b144fe3ba32,0, -0x5970626507193640,0, -0xfeb96f4718bc8c68,0, -0x109376365046001a,0, -0xe30fe607c165ae00,0, -0xd25ff76899f2272,0, -0xaaecf254963a985a,0, -0x44c6eb25dec01428,0, -0x5b697edf4bb8a5c0,0, -0xb54367ae034229b2,0, -0x128a6a8c1ce7939a,0, -0xfca073fd541d1fe8,0, -0xac3a1d264f1a99c0,0, -0x4210045707e015b2,0, -0xe5d909751845af9a,0, -0xbf3100450bf23e8,0, -0x145c85fec5c79200,0, -0xfa769c8f8d3d1e72,0, -0x5dbf91ad9298a45a,0, -0xb39588dcda622828,0, -0x1e561e4491ab50d4,0, -0xf07c0735d951dca6,0, -0x57b50a17c6f4668e,0, -0xb99f13668e0eeafc,0, -0xa630869c1b765b14,0, -0x481a9fed538cd766,0, -0xefd392cf4c296d4e,0, -0x1f98bbe04d3e13c,0, -0x5163e5651fd46714,0, -0xbf49fc14572eeb66,0, -0x1880f136488b514e,0, -0xf6aae8470071dd3c,0, -0xe9057dbd95096cd4,0, -0x72f64ccddf3e0a6,0, -0xa0e669eec2565a8e,0, -0x4ecc709f8aacd6fc,0, -0xbd50e0ae1b8f78e6,0, -0x537af9df5375f494,0, -0xf4b3f4fd4cd04ebc,0, -0x1a99ed8c042ac2ce,0, -0x536787691527326,0, -0xeb1c6107d9a8ff54,0, -0x4cd56c25c60d457c,0, -0xa2ff75548ef7c90e,0, -0xf2651b8f95f04f26,0, -0x1c4f02fedd0ac354,0, -0xbb860fdcc2af797c,0, -0x55ac16ad8a55f50e,0, -0x4a0383571f2d44e6,0, -0xa4299a2657d7c894,0, -0x3e09704487272bc,0, -0xedca8e750088fece,0, -0x0,0, -0xe2266ceb0c5bc774,0, -0xf490e6ed40d1dd1a,0, -0x16b68a064c8a1a6e,0, -0xf3f5f515077e92f0,0, -0x11d399fe0b255584,0, -0x76513f847af4fea,0, -0xe5437f134bf4889e,0, -0x467c20312e7eb0f0,0, -0xa45a4cda22257784,0, -0xb2ecc6dc6eaf6dea,0, -0x50caaa3762f4aa9e,0, -0xb589d52429002200,0, -0x57afb9cf255be574,0, -0x411933c969d1ff1a,0, -0xa33f5f22658a386e,0, -0xb06caa4295d350c2,0, -0x524ac6a9998897b6,0, -0x44fc4cafd5028dd8,0, -0xa6da2044d9594aac,0, -0x43995f5792adc232,0, -0xa1bf33bc9ef60546,0, -0xb709b9bad27c1f28,0, -0x552fd551de27d85c,0, -0xf6108a73bbade032,0, -0x1436e698b7f62746,0, -0x2806c9efb7c3d28,0, -0xe0a60075f727fa5c,0, -0x5e57f66bcd372c2,0, -0xe7c3138db088b5b6,0, -0xf175998bfc02afd8,0, -0x1353f560f05968ac,0, -0x5c5916d98a583c16,0, -0xbe7f7a328603fb62,0, -0xa8c9f034ca89e10c,0, -0x4aef9cdfc6d22678,0, -0xaface3cc8d26aee6,0, -0x4d8a8f27817d6992,0, -0x5b3c0521cdf773fc,0, -0xb91a69cac1acb488,0, -0x1a2536e8a4268ce6,0, -0xf8035a03a87d4b92,0, -0xeeb5d005e4f751fc,0, -0xc93bceee8ac9688,0, -0xe9d0c3fda3581e16,0, -0xbf6af16af03d962,0, -0x1d402510e389c30c,0, -0xff6649fbefd20478,0, -0xec35bc9b1f8b6cd4,0, -0xe13d07013d0aba0,0, -0x18a55a765f5ab1ce,0, -0xfa83369d530176ba,0, -0x1fc0498e18f5fe24,0, -0xfde6256514ae3950,0, -0xeb50af635824233e,0, -0x976c388547fe44a,0, -0xaa499caa31f5dc24,0, -0x486ff0413dae1b50,0, -0x5ed97a477124013e,0, -0xbcff16ac7d7fc64a,0, -0x59bc69bf368b4ed4,0, -0xbb9a05543ad089a0,0, -0xad2c8f52765a93ce,0, -0x4f0ae3b97a0154ba,0, -0xa04de5b4c7a1ceac,0, -0x426b895fcbfa09d8,0, -0x54dd0359877013b6,0, -0xb6fb6fb28b2bd4c2,0, -0x53b810a1c0df5c5c,0, -0xb19e7c4acc849b28,0, -0xa728f64c800e8146,0, -0x450e9aa78c554632,0, -0xe631c585e9df7e5c,0, -0x417a96ee584b928,0, -0x12a12368a90ea346,0, -0xf0874f83a5556432,0, -0x15c43090eea1ecac,0, -0xf7e25c7be2fa2bd8,0, -0xe154d67dae7031b6,0, -0x372ba96a22bf6c2,0, -0x10214ff652729e6e,0, -0xf207231d5e29591a,0, -0xe4b1a91b12a34374,0, -0x697c5f01ef88400,0, -0xe3d4bae3550c0c9e,0, -0x1f2d6085957cbea,0, -0x17445c0e15ddd184,0, -0xf56230e5198616f0,0, -0x565d6fc77c0c2e9e,0, -0xb47b032c7057e9ea,0, -0xa2cd892a3cddf384,0, -0x40ebe5c1308634f0,0, -0xa5a89ad27b72bc6e,0, -0x478ef63977297b1a,0, -0x51387c3f3ba36174,0, -0xb31e10d437f8a600,0, -0xfc14f36d4df9f2ba,0, -0x1e329f8641a235ce,0, -0x88415800d282fa0,0, -0xeaa2796b0173e8d4,0, -0xfe106784a87604a,0, -0xedc76a9346dca73e,0, -0xfb71e0950a56bd50,0, -0x19578c7e060d7a24,0, -0xba68d35c6387424a,0, -0x584ebfb76fdc853e,0, -0x4ef835b123569f50,0, -0xacde595a2f0d5824,0, -0x499d264964f9d0ba,0, -0xabbb4aa268a217ce,0, -0xbd0dc0a424280da0,0, -0x5f2bac4f2873cad4,0, -0x4c78592fd82aa278,0, -0xae5e35c4d471650c,0, -0xb8e8bfc298fb7f62,0, -0x5aced32994a0b816,0, -0xbf8dac3adf543088,0, -0x5dabc0d1d30ff7fc,0, -0x4b1d4ad79f85ed92,0, -0xa93b263c93de2ae6,0, -0xa04791ef6541288,0, -0xe82215f5fa0fd5fc,0, -0xfe949ff3b685cf92,0, -0x1cb2f318bade08e6,0, -0xf9f18c0bf12a8078,0, -0x1bd7e0e0fd71470c,0, -0xd616ae6b1fb5d62,0, -0xef47060dbda09a16,0, -0x41430183d6e85ec0,0, -0xa3656d68dab399b4,0, -0xb5d3e76e963983da,0, -0x57f58b859a6244ae,0, -0xb2b6f496d196cc30,0, -0x5090987dddcd0b44,0, -0x4626127b9147112a,0, -0xa4007e909d1cd65e,0, -0x73f21b2f896ee30,0, -0xe5194d59f4cd2944,0, -0xf3afc75fb847332a,0, -0x1189abb4b41cf45e,0, -0xf4cad4a7ffe87cc0,0, -0x16ecb84cf3b3bbb4,0, -0x5a324abf39a1da,0, -0xe27c5ea1b36266ae,0, -0xf12fabc1433b0e02,0, -0x1309c72a4f60c976,0, -0x5bf4d2c03ead318,0, -0xe79921c70fb1146c,0, -0x2da5ed444459cf2,0, -0xe0fc323f481e5b86,0, -0xf64ab839049441e8,0, -0x146cd4d208cf869c,0, -0xb7538bf06d45bef2,0, -0x5575e71b611e7986,0, -0x43c36d1d2d9463e8,0, -0xa1e501f621cfa49c,0, -0x44a67ee56a3b2c02,0, -0xa680120e6660eb76,0, -0xb03698082aeaf118,0, -0x5210f4e326b1366c,0, -0x1d1a175a5cb062d6,0, -0xff3c7bb150eba5a2,0, -0xe98af1b71c61bfcc,0, -0xbac9d5c103a78b8,0, -0xeeefe24f5bcef026,0, -0xcc98ea457953752,0, -0x1a7f04a21b1f2d3c,0, -0xf85968491744ea48,0, -0x5b66376b72ced226,0, -0xb9405b807e951552,0, -0xaff6d186321f0f3c,0, -0x4dd0bd6d3e44c848,0, -0xa893c27e75b040d6,0, -0x4ab5ae9579eb87a2,0, -0x5c03249335619dcc,0, -0xbe254878393a5ab8,0, -0xad76bd18c9633214,0, -0x4f50d1f3c538f560,0, -0x59e65bf589b2ef0e,0, -0xbbc0371e85e9287a,0, -0x5e83480dce1da0e4,0, -0xbca524e6c2466790,0, -0xaa13aee08ecc7dfe,0, -0x4835c20b8297ba8a,0, -0xeb0a9d29e71d82e4,0, -0x92cf1c2eb464590,0, -0x1f9a7bc4a7cc5ffe,0, -0xfdbc172fab97988a,0, -0x18ff683ce0631014,0, -0xfad904d7ec38d760,0, -0xec6f8ed1a0b2cd0e,0, -0xe49e23aace90a7a,0, -0xe10ee4371149906c,0, -0x32888dc1d125718,0, -0x159e02da51984d76,0, -0xf7b86e315dc38a02,0, -0x12fb11221637029c,0, -0xf0dd7dc91a6cc5e8,0, -0xe66bf7cf56e6df86,0, -0x44d9b245abd18f2,0, -0xa772c4063f37209c,0, -0x4554a8ed336ce7e8,0, -0x53e222eb7fe6fd86,0, -0xb1c44e0073bd3af2,0, -0x548731133849b26c,0, -0xb6a15df834127518,0, -0xa017d7fe78986f76,0, -0x4231bb1574c3a802,0, -0x51624e75849ac0ae,0, -0xb344229e88c107da,0, -0xa5f2a898c44b1db4,0, -0x47d4c473c810dac0,0, -0xa297bb6083e4525e,0, -0x40b1d78b8fbf952a,0, -0x56075d8dc3358f44,0, -0xb4213166cf6e4830,0, -0x171e6e44aae4705e,0, -0xf53802afa6bfb72a,0, -0xe38e88a9ea35ad44,0, -0x1a8e442e66e6a30,0, -0xe4eb9b51ad9ae2ae,0, -0x6cdf7baa1c125da,0, -0x107b7dbced4b3fb4,0, -0xf25d1157e110f8c0,0, -0xbd57f2ee9b11ac7a,0, -0x5f719e05974a6b0e,0, -0x49c71403dbc07160,0, -0xabe178e8d79bb614,0, -0x4ea207fb9c6f3e8a,0, -0xac846b109034f9fe,0, -0xba32e116dcbee390,0, -0x58148dfdd0e524e4,0, -0xfb2bd2dfb56f1c8a,0, -0x190dbe34b934dbfe,0, -0xfbb3432f5bec190,0, -0xed9d58d9f9e506e4,0, -0x8de27cab2118e7a,0, -0xeaf84b21be4a490e,0, -0xfc4ec127f2c05360,0, -0x1e68adccfe9b9414,0, -0xd3b58ac0ec2fcb8,0, -0xef1d344702993bcc,0, -0xf9abbe414e1321a2,0, -0x1b8dd2aa4248e6d6,0, -0xfeceadb909bc6e48,0, -0x1ce8c15205e7a93c,0, -0xa5e4b54496db352,0, -0xe87827bf45367426,0, -0x4b47789d20bc4c48,0, -0xa96114762ce78b3c,0, -0xbfd79e70606d9152,0, -0x5df1f29b6c365626,0, -0xb8b28d8827c2deb8,0, -0x5a94e1632b9919cc,0, -0x4c226b65671303a2,0, -0xae04078e6b48c4d6,0, -0x0,0, -0xb361d8dabe3b3632,0, -0x4357375d88b88b56,0, -0xf036ef873683bd64,0, -0xb057dcc8a19fbc9c,0, -0x33604121fa48aae,0, -0xf300eb95292737ca,0, -0x4061334f971c01f8,0, -0xf26e1791be4b37c2,0, -0x410fcf4b007001f0,0, -0xb13920cc36f3bc94,0, -0x258f81688c88aa6,0, -0x4239cb591fd48b5e,0, -0xf1581383a1efbd6c,0, -0x16efc04976c0008,0, -0xb20f24de2957363a,0, -0xe9f744031bfe63e4,0, -0x5a969cd9a5c555d6,0, -0xaaa0735e9346e8b2,0, -0x19c1ab842d7dde80,0, -0x59a098cbba61df78,0, -0xeac14011045ae94a,0, -0x1af7af9632d9542e,0, -0xa996774c8ce2621c,0, -0x1b995392a5b55426,0, -0xa8f88b481b8e6214,0, -0x58ce64cf2d0ddf70,0, -0xebafbc159336e942,0, -0xabce8f5a042ae8ba,0, -0x18af5780ba11de88,0, -0xe899b8078c9263ec,0, -0x5bf860dd32a955de,0, -0xe50803875e9ab776,0, -0x5669db5de0a18144,0, -0xa65f34dad6223c20,0, -0x153eec0068190a12,0, -0x555fdf4fff050bea,0, -0xe63e0795413e3dd8,0, -0x1608e81277bd80bc,0, -0xa56930c8c986b68e,0, -0x17661416e0d180b4,0, -0xa407cccc5eeab686,0, -0x5431234b68690be2,0, -0xe750fb91d6523dd0,0, -0xa731c8de414e3c28,0, -0x14501004ff750a1a,0, -0xe466ff83c9f6b77e,0, -0x5707275977cd814c,0, -0xcff47844564d492,0, -0xbf9e9f5efb5fe2a0,0, -0x4fa870d9cddc5fc4,0, -0xfcc9a80373e769f6,0, -0xbca89b4ce4fb680e,0, -0xfc943965ac05e3c,0, -0xffffac116c43e358,0, -0x4c9e74cbd278d56a,0, -0xfe915015fb2fe350,0, -0x4df088cf4514d562,0, -0xbdc6674873976806,0, -0xea7bf92cdac5e34,0, -0x4ec68cdd5ab05fcc,0, -0xfda75407e48b69fe,0, -0xd91bb80d208d49a,0, -0xbef0635a6c33e2a8,0, -0x44ee098f4d56753e,0, -0xf78fd155f36d430c,0, -0x7b93ed2c5eefe68,0, -0xb4d8e6087bd5c85a,0, -0xf4b9d547ecc9c9a2,0, -0x47d80d9d52f2ff90,0, -0xb7eee21a647142f4,0, -0x48f3ac0da4a74c6,0, -0xb6801e1ef31d42fc,0, -0x5e1c6c44d2674ce,0, -0xf5d729437ba5c9aa,0, -0x46b6f199c59eff98,0, -0x6d7c2d65282fe60,0, -0xb5b61a0cecb9c852,0, -0x4580f58bda3a7536,0, -0xf6e12d5164014304,0, -0xad194d8c56a816da,0, -0x1e789556e89320e8,0, -0xee4e7ad1de109d8c,0, -0x5d2fa20b602babbe,0, -0x1d4e9144f737aa46,0, -0xae2f499e490c9c74,0, -0x5e19a6197f8f2110,0, -0xed787ec3c1b41722,0, -0x5f775a1de8e32118,0, -0xec1682c756d8172a,0, -0x1c206d40605baa4e,0, -0xaf41b59ade609c7c,0, -0xef2086d5497c9d84,0, -0x5c415e0ff747abb6,0, -0xac77b188c1c416d2,0, -0x1f1669527fff20e0,0, -0xa1e60a0813ccc248,0, -0x1287d2d2adf7f47a,0, -0xe2b13d559b74491e,0, -0x51d0e58f254f7f2c,0, -0x11b1d6c0b2537ed4,0, -0xa2d00e1a0c6848e6,0, -0x52e6e19d3aebf582,0, -0xe187394784d0c3b0,0, -0x53881d99ad87f58a,0, -0xe0e9c54313bcc3b8,0, -0x10df2ac4253f7edc,0, -0xa3bef21e9b0448ee,0, -0xe3dfc1510c184916,0, -0x50be198bb2237f24,0, -0xa088f60c84a0c240,0, -0x13e92ed63a9bf472,0, -0x48114e0b0832a1ac,0, -0xfb7096d1b609979e,0, -0xb467956808a2afa,0, -0xb827a18c3eb11cc8,0, -0xf84692c3a9ad1d30,0, -0x4b274a1917962b02,0, -0xbb11a59e21159666,0, -0x8707d449f2ea054,0, -0xba7f599ab679966e,0, -0x91e81400842a05c,0, -0xf9286ec73ec11d38,0, -0x4a49b61d80fa2b0a,0, -0xa28855217e62af2,0, -0xb9495d88a9dd1cc0,0, -0x497fb20f9f5ea1a4,0, -0xfa1e6ad521659796,0, -0x9dc338f8399031b4,0, -0x2ea2e02287ab0786,0, -0xde940fa5b128bae2,0, -0x6df5d77f0f138cd0,0, -0x2d94e430980f8d28,0, -0x9ef53cea2634bb1a,0, -0x6ec3d36d10b7067e,0, -0xdda20bb7ae8c304c,0, -0x6fad2f6987db0676,0, -0xdcccf7b339e03044,0, -0x2cfa18340f638d20,0, -0x9f9bc0eeb158bb12,0, -0xdffaf3a12644baea,0, -0x6c9b2b7b987f8cd8,0, -0x9cadc4fcaefc31bc,0, -0x2fcc1c2610c7078e,0, -0x74347cfb226e5250,0, -0xc755a4219c556462,0, -0x37634ba6aad6d906,0, -0x8402937c14edef34,0, -0xc463a03383f1eecc,0, -0x770278e93dcad8fe,0, -0x8734976e0b49659a,0, -0x34554fb4b57253a8,0, -0x865a6b6a9c256592,0, -0x353bb3b0221e53a0,0, -0xc50d5c37149deec4,0, -0x766c84edaaa6d8f6,0, -0x360db7a23dbad90e,0, -0x856c6f788381ef3c,0, -0x755a80ffb5025258,0, -0xc63b58250b39646a,0, -0x78cb3b7f670a86c2,0, -0xcbaae3a5d931b0f0,0, -0x3b9c0c22efb20d94,0, -0x88fdd4f851893ba6,0, -0xc89ce7b7c6953a5e,0, -0x7bfd3f6d78ae0c6c,0, -0x8bcbd0ea4e2db108,0, -0x38aa0830f016873a,0, -0x8aa52ceed941b100,0, -0x39c4f434677a8732,0, -0xc9f21bb351f93a56,0, -0x7a93c369efc20c64,0, -0x3af2f02678de0d9c,0, -0x899328fcc6e53bae,0, -0x79a5c77bf06686ca,0, -0xcac41fa14e5db0f8,0, -0x913c7f7c7cf4e526,0, -0x225da7a6c2cfd314,0, -0xd26b4821f44c6e70,0, -0x610a90fb4a775842,0, -0x216ba3b4dd6b59ba,0, -0x920a7b6e63506f88,0, -0x623c94e955d3d2ec,0, -0xd15d4c33ebe8e4de,0, -0x635268edc2bfd2e4,0, -0xd033b0377c84e4d6,0, -0x20055fb04a0759b2,0, -0x9364876af43c6f80,0, -0xd305b42563206e78,0, -0x60646cffdd1b584a,0, -0x90528378eb98e52e,0, -0x23335ba255a3d31c,0, -0xd92d317774c6448a,0, -0x6a4ce9adcafd72b8,0, -0x9a7a062afc7ecfdc,0, -0x291bdef04245f9ee,0, -0x697aedbfd559f816,0, -0xda1b35656b62ce24,0, -0x2a2ddae25de17340,0, -0x994c0238e3da4572,0, -0x2b4326e6ca8d7348,0, -0x9822fe3c74b6457a,0, -0x681411bb4235f81e,0, -0xdb75c961fc0ece2c,0, -0x9b14fa2e6b12cfd4,0, -0x287522f4d529f9e6,0, -0xd843cd73e3aa4482,0, -0x6b2215a95d9172b0,0, -0x30da75746f38276e,0, -0x83bbadaed103115c,0, -0x738d4229e780ac38,0, -0xc0ec9af359bb9a0a,0, -0x808da9bccea79bf2,0, -0x33ec7166709cadc0,0, -0xc3da9ee1461f10a4,0, -0x70bb463bf8242696,0, -0xc2b462e5d17310ac,0, -0x71d5ba3f6f48269e,0, -0x81e355b859cb9bfa,0, -0x32828d62e7f0adc8,0, -0x72e3be2d70ecac30,0, -0xc18266f7ced79a02,0, -0x31b48970f8542766,0, -0x82d551aa466f1154,0, -0x3c2532f02a5cf3fc,0, -0x8f44ea2a9467c5ce,0, -0x7f7205ada2e478aa,0, -0xcc13dd771cdf4e98,0, -0x8c72ee388bc34f60,0, -0x3f1336e235f87952,0, -0xcf25d965037bc436,0, -0x7c4401bfbd40f204,0, -0xce4b25619417c43e,0, -0x7d2afdbb2a2cf20c,0, -0x8d1c123c1caf4f68,0, -0x3e7dcae6a294795a,0, -0x7e1cf9a9358878a2,0, -0xcd7d21738bb34e90,0, -0x3d4bcef4bd30f3f4,0, -0x8e2a162e030bc5c6,0, -0xd5d276f331a29018,0, -0x66b3ae298f99a62a,0, -0x968541aeb91a1b4e,0, -0x25e4997407212d7c,0, -0x6585aa3b903d2c84,0, -0xd6e472e12e061ab6,0, -0x26d29d661885a7d2,0, -0x95b345bca6be91e0,0, -0x27bc61628fe9a7da,0, -0x94ddb9b831d291e8,0, -0x64eb563f07512c8c,0, -0xd78a8ee5b96a1abe,0, -0x97ebbdaa2e761b46,0, -0x248a6570904d2d74,0, -0xd4bc8af7a6ce9010,0, -0x67dd522d18f5a622,0, -}; -} - -#endif \ No newline at end of file diff --git a/libOTe/Tools/bitpolymul/gfext_aesni.h b/libOTe/Tools/bitpolymul/gfext_aesni.h deleted file mode 100644 index 86e4ea9f..00000000 --- a/libOTe/Tools/bitpolymul/gfext_aesni.h +++ /dev/null @@ -1,275 +0,0 @@ -#pragma once -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - - -#include -#include -#include "bpmDefines.h" - -namespace bpm { -// -// /// X^64 + X^4 + X^3 + X + 1 -// /// 0x1b - alignas(32) const uint64_t _gf2ext64_reducer[4] = { 0x415A776C2D361B00ULL,0x1bULL,0x415A776C2D361B00ULL,0x1bULL }; - - inline - __m128i _gf2ext64_reduce_sse(__m128i x0) - { - __m128i reducer = _mm_load_si128((__m128i const*)_gf2ext64_reducer); - //__m128i *reducer = (__m128i *)_gf2ext128_reducer; - __m128i r0 = _mm_clmulepi64_si128(x0, reducer, 0x11); - __m128i r1 = _mm_shuffle_epi8(reducer, r0); - __m128i r2 = _mm_xor_si128(x0, r0); - r1 = _mm_xor_si128(r1, _mm_slli_si128(r2, 8)); - return _mm_srli_si128(r1, 8); - } - - - inline - __m128i _gf2ext64_reduce_x2_sse(__m128i x0, __m128i y0) - { - __m128i reducer = _mm_load_si128((__m128i const*)_gf2ext64_reducer); - //__m128i *reducer = (__m128i *)_gf2ext128_reducer; - __m128i r0 = _mm_clmulepi64_si128(x0, reducer, 0x11); - __m128i s0 = _mm_clmulepi64_si128(y0, reducer, 0x11); - __m128i r2 = _mm_xor_si128(x0, r0); - __m128i s2 = _mm_xor_si128(y0, s0); - __m128i pr = _mm_unpacklo_epi64(r2, s2); - - __m128i rr = _mm_unpackhi_epi64(r0, s0); - __m128i rr2 = _mm_shuffle_epi8(reducer, rr); - - return _mm_xor_si128(pr, rr2); - } -// - inline - __m256i _gf2ext64_reduce_x4_avx2(__m128i w0, __m128i x0, __m128i y0, __m128i z0) - { - __m256i reducer2 = _mm256_load_si256((__m256i const*)_gf2ext64_reducer); - //__m128i *reducer = (__m128i *)_gf2ext128_reducer; - __m128i reducer = _mm256_castsi256_si128(reducer2); - __m128i r0 = _mm_clmulepi64_si128(w0, reducer, 0x11); - __m128i s0 = _mm_clmulepi64_si128(x0, reducer, 0x11); - __m128i t0 = _mm_clmulepi64_si128(y0, reducer, 0x11); - __m128i u0 = _mm_clmulepi64_si128(z0, reducer, 0x11); - __m128i r2 = _mm_xor_si128(w0, r0); - __m128i s2 = _mm_xor_si128(x0, s0); - __m128i t2 = _mm_xor_si128(y0, t0); - __m128i u2 = _mm_xor_si128(z0, u0); - __m256i pr1 = _mm256_castsi128_si256(_mm_unpacklo_epi64(r2, s2)); - __m256i pr2 = _mm256_inserti128_si256(pr1, _mm_unpacklo_epi64(t2, u2), 1); - - __m256i rr1 = _mm256_castsi128_si256(_mm_unpackhi_epi64(r0, s0)); - __m256i rr2 = _mm256_inserti128_si256(rr1, _mm_unpackhi_epi64(t0, u0), 1); - return _mm256_xor_si256(pr2, _mm256_shuffle_epi8(reducer2, rr2)); - } - -// - inline - __m128i _gf2ext64_mul_hi_sse(__m128i a0, __m128i b0) - { - __m128i c0 = _mm_clmulepi64_si128(a0, b0, 1); - __m128i c3 = _gf2ext64_reduce_sse(c0); - return c3; - } - - inline - __m128i _gf2ext64_mul_2x1_sse(__m128i a0a1, __m128i b0) - { - __m128i c0 = _mm_clmulepi64_si128(a0a1, b0, 0); - __m128i c1 = _mm_clmulepi64_si128(a0a1, b0, 1); - __m128i c3 = _gf2ext64_reduce_x2_sse(c0, c1); - return c3; - } - - inline - __m256i _gf2ext64_mul_4x1_avx2(__m256i a, __m128i b0) - { - __m128i al = _mm256_castsi256_si128(a); - __m128i c0 = _mm_clmulepi64_si128(al, b0, 0); - __m128i c1 = _mm_clmulepi64_si128(al, b0, 1); - __m128i ah = _mm256_extracti128_si256(a, 1); - __m128i c2 = _mm_clmulepi64_si128(ah, b0, 0); - __m128i c3 = _mm_clmulepi64_si128(ah, b0, 1); - - return _gf2ext64_reduce_x4_avx2(c0, c1, c2, c3); - } - - - inline - __m256i _gf2ext64_mul_4x4_avx2(__m256i a, __m256i b) - { - __m128i al = _mm256_castsi256_si128(a); - __m128i bl = _mm256_castsi256_si128(b); - __m128i c0 = _mm_clmulepi64_si128(al, bl, 0); - __m128i c1 = _mm_clmulepi64_si128(al, bl, 0x11); - __m128i ah = _mm256_extracti128_si256(a, 1); - __m128i bh = _mm256_extracti128_si256(b, 1); - __m128i c2 = _mm_clmulepi64_si128(ah, bh, 0); - __m128i c3 = _mm_clmulepi64_si128(ah, bh, 0x11); - - return _gf2ext64_reduce_x4_avx2(c0, c1, c2, c3); - } - - - inline - void gf2ext64_mul_4x4_avx2(uint8_t* c, const uint8_t* a, const uint8_t* b) - { - __m256i as = _mm256_load_si256((__m256i const*)a); - __m256i bs = _mm256_load_si256((__m256i const*)b); - __m256i cs = _gf2ext64_mul_4x4_avx2(as, bs); - - _mm256_store_si256((__m256i*) c, cs); - } - - - -// - - ///////////////////////////////////////////// - - - /// X^128 + X^7 + X^2 + X + 1 - /// 0x 8 7 - alignas(32) const uint64_t _gf2ext128_reducer[2] = { 0x87ULL,0x0ULL }; - - //USED; - inline - __m128i _gf2ext128_reduce_sse(__m128i x0, __m128i x128) - { - __m128i reducer = _mm_load_si128((__m128i const*)_gf2ext128_reducer); - //__m128i *reducer = (__m128i *)_gf2ext128_reducer; - __m128i x64 = _mm_clmulepi64_si128(x128, reducer, 1); /// 0_32 , xx2_32 , xx1 , xx0 - x128 = _mm_xor_si128(x128, _mm_shuffle_epi32(x64, 0xfe)); // 0,0,0,xx2 ; 0xfe --> 3,3,3,2 - x0 = _mm_xor_si128(x0, _mm_shuffle_epi32(x64, 0x4f)); // xx1 , xx0 , 0 , 0 ; 0x4f --> 1,0,3,3 --> xx1,xx0,0,0 - x0 = _mm_xor_si128(x0, _mm_clmulepi64_si128(x128, reducer, 0)); - return x0; - } - - -#define _MUL_128_KARATSUBA( c0,c1,a0,b0 ) \ -do {\ - c0 = _mm_clmulepi64_si128( a0,b0 , 0x00 ); \ - c1 = _mm_clmulepi64_si128( a0,b0 , 0x11 ); \ - __m128i _tt0 = _mm_xor_si128(a0, _mm_srli_si128(a0,8)); \ - __m128i _tt1 = _mm_xor_si128(b0,_mm_srli_si128(b0,8)); \ - __m128i _tt2 = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128( _tt0, _tt1 , 0 ),c0),c1); \ - c0 = _mm_xor_si128(c0, _mm_slli_si128( _tt2 , 8 )); \ - c1 = _mm_xor_si128(c1,_mm_srli_si128( _tt2 , 8 )); \ -} while(0) - - - //USED; - inline - void gf2ext128_mul_sse(uint8_t* c, const uint8_t* a, const uint8_t* b) - { - __m128i a0 = _mm_load_si128((__m128i const*)a); - __m128i b0 = _mm_load_si128((__m128i const*)b); - __m128i c0, c128; - _MUL_128_KARATSUBA(c0, c128, a0, b0); - - __m128i c3 = _gf2ext128_reduce_sse(c0, c128); - //__m128i c3 = _gf_aesgcm_reduce_sse( c0 , c128 ); - _mm_store_si128((__m128i*) c, c3); - } - - - inline - __m128i _gf2ext128_mul_sse(__m128i a0, __m128i b0) - { - __m128i c0, c128; - _MUL_128_KARATSUBA(c0, c128, a0, b0); - __m128i c3 = _gf2ext128_reduce_sse(c0, c128); - return c3; - } - - - inline - __m256i _gf2ext128_mul_2x1_avx2(__m256i a0a1, __m128i b0) - { - __m128i a0 = _mm256_castsi256_si128(a0a1); - __m128i a1 = _mm256_extracti128_si256(a0a1, 1); - - __m128i c0, c128; - __m128i d0, d128; - _MUL_128_KARATSUBA(c0, c128, a0, b0); - _MUL_128_KARATSUBA(d0, d128, a1, b0); - __m128i c3 = _gf2ext128_reduce_sse(c0, c128); - __m128i d3 = _gf2ext128_reduce_sse(d0, d128); - - __m256i r = _mm256_castsi128_si256(c3); - - return _mm256_inserti128_si256(r, d3, 1); - } - - - - ////////////////////////////////////////////////////////////////////////////////////// - - - //// s7 = x^64 + x^32 + x16 + x8 + x4 + x2 + x - - - alignas(32) const uint64_t _s7[2] = { 0x100010116ULL,0x1ULL }; - - inline - __m256i div_s7(__m256i a) - { - __m128i r_s7 = _mm_load_si128((__m128i const*)_s7); - __m128i a1 = _mm256_extracti128_si256(a, 1); - __m128i a0 = _mm256_castsi256_si128(a); - - __m128i a1h_s7 = _mm_clmulepi64_si128(a1, r_s7, 1); - a1 = _mm_xor_si128(a1, _mm_srli_si128(_mm_xor_si128(a1, a1h_s7), 8)); - a0 = _mm_xor_si128(a0, _mm_slli_si128(a1h_s7, 8)); - - a0 = _mm_xor_si128(a0, _mm_slli_si128(a1, 8)); - a0 = _mm_xor_si128(a0, _mm_clmulepi64_si128(a1, r_s7, 0)); - - __m256i r = _mm256_castsi128_si256(a0); - return _mm256_inserti128_si256(r, a1, 1); - } - - - //USED; - inline - __m256i exp_s7(__m256i a) - { - __m128i r_s7 = _mm_load_si128((__m128i const*)_s7); - __m128i a1 = _mm256_extracti128_si256(a, 1); - __m128i a0 = _mm256_castsi256_si128(a); - - a0 = _mm_xor_si128(a0, _mm_clmulepi64_si128(a1, r_s7, 0)); - a0 = _mm_xor_si128(a0, _mm_slli_si128(a1, 8)); - __m128i a1h_s7 = _mm_clmulepi64_si128(a1, r_s7, 1); - a0 = _mm_xor_si128(a0, _mm_slli_si128(a1h_s7, 8)); - a1 = _mm_xor_si128(a1, _mm_srli_si128(_mm_xor_si128(a1, a1h_s7), 8)); - - __m256i r = _mm256_castsi128_si256(a0); - return _mm256_inserti128_si256(r, a1, 1); - } - -} -#endif - diff --git a/libOTe/Tools/bitpolymul/ska.h b/libOTe/Tools/bitpolymul/ska.h deleted file mode 100644 index 9dafcbc4..00000000 --- a/libOTe/Tools/bitpolymul/ska.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - - -namespace bpm { - inline - unsigned get_s_k_a_cantor(unsigned k, unsigned a) { return (a >> k); } -} -#endif diff --git a/libOTe/Tools/bitpolymul/transpose.h b/libOTe/Tools/bitpolymul/transpose.h deleted file mode 100644 index fa8b8ee7..00000000 --- a/libOTe/Tools/bitpolymul/transpose.h +++ /dev/null @@ -1,402 +0,0 @@ -#pragma once -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - - -#include -#include -#include "bpmDefines.h" -#include "transpose_bit.h" - -namespace bpm { - - alignas(32) const uint8_t _tr_4x4[32] = { 0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15 ,0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15 }; - - //USED; - inline - void tr_avx2_4x4_b8(uint8_t* _r, const uint8_t* a) { - - __m256i r0 = _mm256_load_si256((__m256i*) a); - __m256i r1 = _mm256_load_si256((__m256i*) (a + 32)); - __m256i r2 = _mm256_load_si256((__m256i*) (a + 64)); - __m256i r3 = _mm256_load_si256((__m256i*) (a + 96)); - - __m256i t0 = _mm256_shuffle_epi8(r0, *(__m256i*)_tr_4x4); // 00,01,02,03 - __m256i t1 = _mm256_shuffle_epi8(r1, *(__m256i*)_tr_4x4); // 10,11,12,13 - __m256i t2 = _mm256_shuffle_epi8(r2, *(__m256i*)_tr_4x4); // 20,21,22,23 - __m256i t3 = _mm256_shuffle_epi8(r3, *(__m256i*)_tr_4x4); // 30,31,32,33 - - __m256i t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11 - __m256i t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13 - __m256i t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31 - __m256i t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33 - - __m256i r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30 - __m256i r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31 - __m256i r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32 - __m256i r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33 - - __m256i s0 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4); - __m256i s1 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4); - __m256i s2 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4); - __m256i s3 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4); - - _mm256_store_si256((__m256i*) _r, s0); - _mm256_store_si256((__m256i*) (_r + 32), s1); - _mm256_store_si256((__m256i*) (_r + 64), s2); - _mm256_store_si256((__m256i*) (_r + 96), s3); - } - - - - //USED; - inline - void tr_16x16_b2_from_4x4_b8_1_4(uint8_t* r, const uint8_t* a) { - - __m256i a0 = _mm256_load_si256((__m256i*) a); // 00,04,08,0c - __m256i a4 = _mm256_load_si256((__m256i*) (a + 32 * 4)); // 10,14,18,1c - __m256i a8 = _mm256_load_si256((__m256i*) (a + 32 * 8)); // 20,24,28,2c - __m256i ac = _mm256_load_si256((__m256i*) (a + 32 * 12)); // 30,34,38,3c - - __m256i a04l = _mm256_unpacklo_epi32(a0, a4); // 00,10,04,14 - __m256i a04h = _mm256_unpackhi_epi32(a0, a4); // 08,18,0c,1c - __m256i a8cl = _mm256_unpacklo_epi32(a8, ac); // 20,30,24,34 - __m256i a8ch = _mm256_unpackhi_epi32(a8, ac); // 28,38,2c,3c - - __m256i b0 = _mm256_unpacklo_epi64(a04l, a8cl); // 00,10,20,30 - __m256i b4 = _mm256_unpackhi_epi64(a04l, a8cl); // 04,14,24,34 - __m256i b8 = _mm256_unpacklo_epi64(a04h, a8ch); // 08,18,28,38 - __m256i bc = _mm256_unpackhi_epi64(a04h, a8ch); // 0c,1c,2c,3c - - _mm256_store_si256((__m256i*) (r + 32 * 0), b0); - _mm256_store_si256((__m256i*) (r + 32 * 4), b4); - _mm256_store_si256((__m256i*) (r + 32 * 8), b8); - _mm256_store_si256((__m256i*) (r + 32 * 12), bc); - } - - - //USED; - inline - void tr_16x16_b2_avx2(uint8_t* r, const uint8_t* a) { - alignas(32) uint8_t temp[32 * 16]; - for (unsigned i = 0; i < 4; i++) tr_avx2_4x4_b8(temp + i * 32 * 4, a + i * 32 * 4); - tr_16x16_b2_from_4x4_b8_1_4(r, temp); - tr_16x16_b2_from_4x4_b8_1_4(r + 32, temp + 32); - tr_16x16_b2_from_4x4_b8_1_4(r + 32 * 2, temp + 32 * 2); - tr_16x16_b2_from_4x4_b8_1_4(r + 32 * 3, temp + 32 * 3); - } - - //USED; - inline - void tr_8x8_b4_avx2(uint8_t* _r, const uint8_t* a, const uint64_t mem_len) { - /// code of 4x4_b8 - __m256i r0 = _mm256_load_si256((__m256i*) a); - __m256i r1 = _mm256_load_si256((__m256i*) (a + mem_len * 1)); - __m256i r2 = _mm256_load_si256((__m256i*) (a + mem_len * 2)); - __m256i r3 = _mm256_load_si256((__m256i*) (a + mem_len * 3)); - - __m256i t0 = _mm256_shuffle_epi8(r0, *(__m256i*)_tr_4x4); // 00,01,02,03 - __m256i t1 = _mm256_shuffle_epi8(r1, *(__m256i*)_tr_4x4); // 10,11,12,13 - __m256i t2 = _mm256_shuffle_epi8(r2, *(__m256i*)_tr_4x4); // 20,21,22,23 - __m256i t3 = _mm256_shuffle_epi8(r3, *(__m256i*)_tr_4x4); // 30,31,32,33 - - __m256i t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11 - __m256i t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13 - __m256i t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31 - __m256i t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33 - - __m256i r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30 - __m256i r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31 - __m256i r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32 - __m256i r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33 - - __m256i s0 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4); - __m256i s1 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4); - __m256i s2 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4); - __m256i s3 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4); - - /// repeat 4x4_b8 - r0 = _mm256_load_si256((__m256i*) (a + mem_len * 4)); - r1 = _mm256_load_si256((__m256i*) (a + mem_len * 5)); - r2 = _mm256_load_si256((__m256i*) (a + mem_len * 6)); - r3 = _mm256_load_si256((__m256i*) (a + mem_len * 7)); - - t0 = _mm256_shuffle_epi8(r0, *(__m256i*)_tr_4x4); // 00,01,02,03 - t1 = _mm256_shuffle_epi8(r1, *(__m256i*)_tr_4x4); // 10,11,12,13 - t2 = _mm256_shuffle_epi8(r2, *(__m256i*)_tr_4x4); // 20,21,22,23 - t3 = _mm256_shuffle_epi8(r3, *(__m256i*)_tr_4x4); // 30,31,32,33 - - t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11 - t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13 - t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31 - t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33 - - r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30 - r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31 - r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32 - r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33 - - __m256i s4 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4); - __m256i s5 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4); - __m256i s6 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4); - __m256i s7 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4); - - /// transpose s0,..., s7 - t0 = _mm256_unpacklo_epi32(s0, s4); // s0_0 , s4_0 , s0_1 , s4_1 - t1 = _mm256_unpackhi_epi32(s0, s4); // s0_2 , s4_2 , s0_3 , s4_3 - s0 = _mm256_unpacklo_epi64(t0, t1); // s0_0 , s4_0 , s0_2 , s4_2 - s4 = _mm256_unpackhi_epi64(t0, t1); // s0_1 , s4_1 , s0_3 , s4_3 - - t2 = _mm256_unpacklo_epi32(s1, s5); - t3 = _mm256_unpackhi_epi32(s1, s5); - s1 = _mm256_unpacklo_epi64(t2, t3); - s5 = _mm256_unpackhi_epi64(t2, t3); - - t0 = _mm256_unpacklo_epi32(s2, s6); - t1 = _mm256_unpackhi_epi32(s2, s6); - s2 = _mm256_unpacklo_epi64(t0, t1); - s6 = _mm256_unpackhi_epi64(t0, t1); - - t2 = _mm256_unpacklo_epi32(s3, s7); - t3 = _mm256_unpackhi_epi32(s3, s7); - s3 = _mm256_unpacklo_epi64(t2, t3); - s7 = _mm256_unpackhi_epi64(t2, t3); - - _mm256_store_si256((__m256i*) _r, s0); - _mm256_store_si256((__m256i*) (_r + mem_len * 1), s1); - _mm256_store_si256((__m256i*) (_r + mem_len * 2), s2); - _mm256_store_si256((__m256i*) (_r + mem_len * 3), s3); - _mm256_store_si256((__m256i*) (_r + mem_len * 4), s4); - _mm256_store_si256((__m256i*) (_r + mem_len * 5), s5); - _mm256_store_si256((__m256i*) (_r + mem_len * 6), s6); - _mm256_store_si256((__m256i*) (_r + mem_len * 7), s7); - } - - //USED; - inline - void transpose_8x8_b4_avx2(uint8_t* _r, const uint8_t* a) { -#if 0 - tr_8x8_b4_avx2(_r, a, 32); -#else - __m256i a0 = _mm256_load_si256((__m256i*) a); - __m256i a1 = _mm256_load_si256((__m256i*) (a + 32 * 1)); - __m256i a2 = _mm256_load_si256((__m256i*) (a + 32 * 2)); - __m256i a3 = _mm256_load_si256((__m256i*) (a + 32 * 3)); - __m256i a4 = _mm256_load_si256((__m256i*) (a + 32 * 4)); - __m256i a5 = _mm256_load_si256((__m256i*) (a + 32 * 5)); - __m256i a6 = _mm256_load_si256((__m256i*) (a + 32 * 6)); - __m256i a7 = _mm256_load_si256((__m256i*) (a + 32 * 7)); - - __m256i t0, t1, t2, t3; - t0 = _mm256_unpacklo_epi32(a0, a4); - t1 = _mm256_unpackhi_epi32(a0, a4); - a0 = _mm256_unpacklo_epi64(t0, t1); - a4 = _mm256_unpackhi_epi64(t0, t1); - - t2 = _mm256_unpacklo_epi32(a1, a5); - t3 = _mm256_unpackhi_epi32(a1, a5); - a1 = _mm256_unpacklo_epi64(t2, t3); - a5 = _mm256_unpackhi_epi64(t2, t3); - - t0 = _mm256_unpacklo_epi32(a2, a6); - t1 = _mm256_unpackhi_epi32(a2, a6); - a2 = _mm256_unpacklo_epi64(t0, t1); - a6 = _mm256_unpackhi_epi64(t0, t1); - - t2 = _mm256_unpacklo_epi32(a3, a7); - t3 = _mm256_unpackhi_epi32(a3, a7); - a3 = _mm256_unpacklo_epi64(t2, t3); - a7 = _mm256_unpackhi_epi64(t2, t3); - - /// code of 4x4_b8 - t0 = _mm256_shuffle_epi8(a0, *(__m256i*)_tr_4x4); // 00,01,02,03 - t1 = _mm256_shuffle_epi8(a1, *(__m256i*)_tr_4x4); // 10,11,12,13 - t2 = _mm256_shuffle_epi8(a2, *(__m256i*)_tr_4x4); // 20,21,22,23 - t3 = _mm256_shuffle_epi8(a3, *(__m256i*)_tr_4x4); // 30,31,32,33 - - __m256i t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11 - __m256i t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13 - __m256i t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31 - __m256i t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33 - - __m256i r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30 - __m256i r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31 - __m256i r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32 - __m256i r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33 - - __m256i s0 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4); - __m256i s1 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4); - __m256i s2 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4); - __m256i s3 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4); - - /// repeat 4x4_b8 - t0 = _mm256_shuffle_epi8(a4, *(__m256i*)_tr_4x4); // 00,01,02,03 - t1 = _mm256_shuffle_epi8(a5, *(__m256i*)_tr_4x4); // 10,11,12,13 - t2 = _mm256_shuffle_epi8(a6, *(__m256i*)_tr_4x4); // 20,21,22,23 - t3 = _mm256_shuffle_epi8(a7, *(__m256i*)_tr_4x4); // 30,31,32,33 - - t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11 - t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13 - t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31 - t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33 - - r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30 - r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31 - r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32 - r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33 - - __m256i s4 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4); - __m256i s5 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4); - __m256i s6 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4); - __m256i s7 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4); - - _mm256_store_si256((__m256i*) _r, s0); - _mm256_store_si256((__m256i*) (_r + 32 * 1), s1); - _mm256_store_si256((__m256i*) (_r + 32 * 2), s2); - _mm256_store_si256((__m256i*) (_r + 32 * 3), s3); - _mm256_store_si256((__m256i*) (_r + 32 * 4), s4); - _mm256_store_si256((__m256i*) (_r + 32 * 5), s5); - _mm256_store_si256((__m256i*) (_r + 32 * 6), s6); - _mm256_store_si256((__m256i*) (_r + 32 * 7), s7); -#endif - } - - - - inline - void transpose_8x8_h4zero_b4_avx2(uint8_t* _r, const uint8_t* a) { - __m256i a0 = _mm256_load_si256((__m256i*) a); - __m256i a1 = _mm256_load_si256((__m256i*) (a + 32 * 1)); - __m256i a2 = _mm256_load_si256((__m256i*) (a + 32 * 2)); - __m256i a3 = _mm256_load_si256((__m256i*) (a + 32 * 3)); - __m256i a4 = _mm256_load_si256((__m256i*) (a + 32 * 4)); - __m256i a5 = _mm256_load_si256((__m256i*) (a + 32 * 5)); - __m256i a6 = _mm256_load_si256((__m256i*) (a + 32 * 6)); - __m256i a7 = _mm256_load_si256((__m256i*) (a + 32 * 7)); - - __m256i t0, t1, t2, t3; - t0 = _mm256_unpacklo_epi32(a0, a4); - t1 = _mm256_unpackhi_epi32(a0, a4); - a0 = _mm256_unpacklo_epi64(t0, t1); - - t2 = _mm256_unpacklo_epi32(a1, a5); - t3 = _mm256_unpackhi_epi32(a1, a5); - a1 = _mm256_unpacklo_epi64(t2, t3); - - t0 = _mm256_unpacklo_epi32(a2, a6); - t1 = _mm256_unpackhi_epi32(a2, a6); - a2 = _mm256_unpacklo_epi64(t0, t1); - - t2 = _mm256_unpacklo_epi32(a3, a7); - t3 = _mm256_unpackhi_epi32(a3, a7); - a3 = _mm256_unpacklo_epi64(t2, t3); - - /// code of 4x4_b8 - t0 = _mm256_shuffle_epi8(a0, *(__m256i*)_tr_4x4); // 00,01,02,03 - t1 = _mm256_shuffle_epi8(a1, *(__m256i*)_tr_4x4); // 10,11,12,13 - t2 = _mm256_shuffle_epi8(a2, *(__m256i*)_tr_4x4); // 20,21,22,23 - t3 = _mm256_shuffle_epi8(a3, *(__m256i*)_tr_4x4); // 30,31,32,33 - - __m256i t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11 - __m256i t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13 - __m256i t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31 - __m256i t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33 - - __m256i r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30 - __m256i r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31 - __m256i r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32 - __m256i r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33 - - __m256i s0 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4); - __m256i s1 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4); - __m256i s2 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4); - __m256i s3 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4); - - _mm256_store_si256((__m256i*) _r, s0); - _mm256_store_si256((__m256i*) (_r + 32 * 1), s1); - _mm256_store_si256((__m256i*) (_r + 32 * 2), s2); - _mm256_store_si256((__m256i*) (_r + 32 * 3), s3); - - } - - - - - - - - //USED; - inline - void tr_bit_8x8_b32_avx2(uint8_t* _r, const uint8_t* a) { - for (unsigned i = 0; i < 8; i++) { - tr_bit_8x8_b4_avx(_r + (32 * i), a + (32 * i)); - } - - tr_8x8_b4_avx2(_r, _r, 32); - - for (unsigned i = 0; i < 8; i++) { - tr_bit_8x8_b4_avx(_r + (32 * i), _r + (32 * i)); - } - } - - - - //USED; - inline - void tr_bit_64x64_b4_avx2(uint8_t* _r, const uint8_t* a) { - for (unsigned i = 0; i < 8; i++) { - tr_bit_8x8_b32_avx2(_r + (32 * 8 * i), a + (32 * 8 * i)); - } - - for (unsigned i = 0; i < 8; i++) { - tr_8x8_b4_avx2(_r + 32 * i, _r + 32 * i, 32 * 8); - } - } - - - //USED; - inline - void tr_bit_128x128_b2_avx2(uint8_t* _r, const uint8_t* a) { - tr_bit_64x64_b4_avx2(_r, a); - tr_bit_64x64_b4_avx2(_r + 64 * 32, a + 64 * 32); - - for (unsigned i = 0; i < 64; i++) { - __m256i m00_m01 = _mm256_load_si256((__m256i*) (_r + 32 * i)); // 00 , 01 - __m256i m10_m11 = _mm256_load_si256((__m256i*) (_r + 32 * i + 32 * 64)); // 10 , 11 - __m256i t0 = _mm256_unpacklo_epi64(m00_m01, m10_m11); // 00 , 10 - __m256i t1 = _mm256_unpackhi_epi64(m00_m01, m10_m11); // 01 , 11 - _mm256_store_si256((__m256i*) (_r + 32 * i), t0); - _mm256_store_si256((__m256i*) (_r + 32 * i + 32 * 64), t1); - - } - } - - - - - - -} -#endif - - diff --git a/libOTe/Tools/bitpolymul/transpose_bit.h b/libOTe/Tools/bitpolymul/transpose_bit.h deleted file mode 100644 index 957a8a7c..00000000 --- a/libOTe/Tools/bitpolymul/transpose_bit.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once -/* - -Code is borrowed from HOEVEN, LARRIEU, and LECERF. - -*/ - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - -#include -#include -#include "bpmDefines.h" - -namespace bpm { - - alignas(32) const uint64_t _tr_bit_mask_4[4] = { 0x00000000f0f0f0f0ULL,0x00000000f0f0f0f0ULL,0x00000000f0f0f0f0ULL,0x00000000f0f0f0f0ULL }; - alignas(32) const uint64_t _tr_bit_mask_2[4] = { 0x0000cccc0000ccccULL,0x0000cccc0000ccccULL,0x0000cccc0000ccccULL,0x0000cccc0000ccccULL }; - alignas(32) const uint64_t _tr_bit_mask_1[4] = { 0x00aa00aa00aa00aaULL,0x00aa00aa00aa00aaULL,0x00aa00aa00aa00aaULL,0x00aa00aa00aa00aaULL }; - - - inline - __m256i tr_bit_8x8_b4_ymmx1(__m256i n) { - __m256i a; - - a = and256(xor256(_mm256_srli_epi64(n, 28), n), (*(__m256i*)_tr_bit_mask_4)); n = xor256(n, a); - a = _mm256_slli_epi64(a, 28); n = xor256(n, a); - a = and256(xor256(_mm256_srli_epi64(n, 14), n), (*(__m256i*)_tr_bit_mask_2)); n = xor256(n, a); - a = _mm256_slli_epi64(a, 14); n = xor256(n, a); - a = and256(xor256(_mm256_srli_epi64(n, 7), n), (*(__m256i*)_tr_bit_mask_1)); n = xor256(n, a); - a = _mm256_slli_epi64(a, 7); n = xor256(n, a); - - return n; - } - - - //USED; - inline - void tr_bit_8x8_b4_avx(uint8_t* _r, const uint8_t* m) { - - __m256i n = _mm256_load_si256((__m256i*) m); - __m256i r = tr_bit_8x8_b4_ymmx1(n); - _mm256_store_si256((__m256i*) _r, r); - } - - -} -#endif - - diff --git a/libOTe/Tools/bitpolymul/trunc_btfy_tab.h b/libOTe/Tools/bitpolymul/trunc_btfy_tab.h deleted file mode 100644 index 30984b76..00000000 --- a/libOTe/Tools/bitpolymul/trunc_btfy_tab.h +++ /dev/null @@ -1,1068 +0,0 @@ -#pragma once -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - - -#include "stdint.h" - - - -namespace bpm { - - - alignas(32) const uint64_t beta_mul_64_bm4r_ext_8[2 * 128 * 4 * 2] = { - 0x8d8cadac21200100,0x9c9dbcbd30311011,0x8d8cadac21200100,0x9c9dbcbd30311011, - 0xfe769810ee668800,0x8008e66e9018f67e,0xfe769810ee668800,0x8008e66e9018f67e, - 0xb2b25454e6e60000,0xa2a24444f6f61010,0xb2b25454e6e60000,0xa2a24444f6f61010, - 0xbf50cf209f70ef00,0xdc33ac43fc138c63,0xbf50cf209f70ef00,0xdc33ac43fc138c63, - 0xe3e3707093930000,0xc7c75454b7b72424,0xe3e3707093930000,0xc7c75454b7b72424, - 0xc5f4a8995c6d3100,0xaa9bc7f633025e6f,0xc5f4a8995c6d3100,0xaa9bc7f633025e6f, - 0xc7c7d7d710100000,0x3c3c2c2cebebfbfb,0xc7c7d7d710100000,0x3c3c2c2cebebfbfb, - 0x5f51ddd38c820e00,0xf0fe727c232da1af,0x5f51ddd38c820e00,0xf0fe727c232da1af, - 0x8080949414140000,0x8181959515150101,0x8080949414140000,0x8181959515150101, - 0x4de4d37a379ea900,0x57fec9602d84b31a,0x4de4d37a379ea900,0x57fec9602d84b31a, - 0x5d5d141449490000,0xa3a3eaeab7b7fefe,0x5d5d141449490000,0xa3a3eaeab7b7fefe, - 0xd357119546c28400,0xe8acc489b1f59dd,0xd357119546c28400,0xe8acc489b1f59dd, - 0xe9e91a1af3f30000,0x303f0f01919eaea,0xe9e91a1af3f30000,0x303f0f01919eaea, - 0xf0646bff0f9b9400,0xdc4847d323b7b82c,0xf0646bff0f9b9400,0xdc4847d323b7b82c, - 0x5050777727270000,0x5d5d7a7a2a2a0d0d,0x5050777727270000,0x5d5d7a7a2a2a0d0d, - 0x7e5aeecab4902400,0xffdb6f4b3511a581,0x7e5aeecab4902400,0xffdb6f4b3511a581, - 0xede1333fd2de0c00,0xa6aa78749995474b,0xede1333fd2de0c00,0xa6aa78749995474b, - 0x7688be4036c8fe00,0xe41a2cd2a45a6c92,0x7688be4036c8fe00,0xe41a2cd2a45a6c92, - 0x7a583a1862402200,0x1b395b7903214361,0x7a583a1862402200,0x1b395b7903214361, - 0xea90a7dd374d7a00,0x6b11265cb6ccfb81,0xea90a7dd374d7a00,0x6b11265cb6ccfb81, - 0x5273d9f8aa8b2100,0xfbda7051032288a9,0x5273d9f8aa8b2100,0xfbda7051032288a9, - 0xf534d819ec2dc100,0x46876baa5f9e72b3,0xf534d819ec2dc100,0x46876baa5f9e72b3, - 0xd4c3c3d400171700,0xd0c7c7d004131304,0xd4c3c3d400171700,0xd0c7c7d004131304, - 0xf9d6230cf5da2f00,0x827d2fd042bdef1,0xf9d6230cf5da2f00,0x827d2fd042bdef1, - 0x4ca91cf9b550e500,0x39dc698cc0259075,0x4ca91cf9b550e500,0x39dc698cc0259075, - 0xc2a57710d2b56700,0x661b3d41671a3c4,0xc2a57710d2b56700,0x661b3d41671a3c4, - 0x515dbbb7e6ea0c00,0xd0dc3a36676b8d81,0x515dbbb7e6ea0c00,0xd0dc3a36676b8d81, - 0x7bf68c017af78d00,0x489f37e0588f27f,0x7bf68c017af78d00,0x489f37e0588f27f, - 0x1262b4c4d6a67000,0x4838ee9e8cfc2a5a,0x1262b4c4d6a67000,0x4838ee9e8cfc2a5a, - 0xbf58709728cfe700,0x1ef9d136896e46a1,0xbf58709728cfe700,0x1ef9d136896e46a1, - 0x8c5ded3cb061d100,0x9140f021ad7ccc1d,0x8c5ded3cb061d100,0x9140f021ad7ccc1d, - 0x51eaeb5001babb00,0xa31819a2f34849f2,0x51eaeb5001babb00,0xa31819a2f34849f2, - 0x6e54261c72483a00,0x90aad8e28cb6c4fe,0x6e54261c72483a00,0x90aad8e28cb6c4fe, - 0xd4f0e4c41034200,0x490b4a0805470644,0xd4f0e4c41034200,0x490b4a0805470644, - 0xac29d653ff7a8500,0xa520df5af6738c09,0xac29d653ff7a8500,0xa520df5af6738c09, - 0x3296a90d3f9ba400,0x2581be1a288cb317,0x3296a90d3f9ba400,0x2581be1a288cb317, - 0x61f6b02746d19700,0xc4531582e37432a5,0x61f6b02746d19700,0xc4531582e37432a5, - 0x74ddd47d09a0a900,0x5aca50c78d1d871,0x74ddd47d09a0a900,0x5aca50c78d1d871, - 0xb288566cdee43a00,0x7e449aa01228f6cc,0xb288566cdee43a00,0x7e449aa01228f6cc, - 0xf9d7cae41d332e00,0xc6e8f5db220c113f,0xf9d7cae41d332e00,0xc6e8f5db220c113f, - 0xc088d29a5a124800,0x4b035911d199c38b,0xc088d29a5a124800,0x4b035911d199c38b, - 0xd4220bfd29dff600,0x18eec731e5133acc,0xd4220bfd29dff600,0x18eec731e5133acc, - 0x3417715266452300,0xeecdab88bc9ff9da,0x3417715266452300,0xeecdab88bc9ff9da, - 0xbc74d61ea26ac800,0x3cb69a11dd577bf,0xbc74d61ea26ac800,0x3cb69a11dd577bf, - 0xbe30149a24aa8e00,0xba34109e20ae8a04,0xbe30149a24aa8e00,0xba34109e20ae8a04, - 0x7157c3e594b22600,0xcaec785e2f099dbb,0x7157c3e594b22600,0xcaec785e2f099dbb, - 0xfc268d57ab71da00,0xf12b805aa67cd70d,0xfc268d57ab71da00,0xf12b805aa67cd70d, - 0x22a3b8391b9a8100,0xbd3c27a684051e9f,0x22a3b8391b9a8100,0xbd3c27a684051e9f, - 0x8bfc1265ee997700,0x4235dbac2750bec9,0x8bfc1265ee997700,0x4235dbac2750bec9, - 0xfb2c4a9d66b1d700,0xb36402d52ef99f48,0xfb2c4a9d66b1d700,0xb36402d52ef99f48, - 0x2c30a8b498841c00,0xb1ad35290519819d,0x2c30a8b498841c00,0xb1ad35290519819d, - 0xc41378af6bbcd700,0xda0d66b175a2c91e,0xc41378af6bbcd700,0xda0d66b175a2c91e, - 0x52535b5a08090100,0xf3f2fafba9a8a0a1,0x52535b5a08090100,0xf3f2fafba9a8a0a1, - 0x82519142c013d300,0x27f434e765b676a5,0x82519142c013d300,0x27f434e765b676a5, - 0x5c2094e8b4c87c00,0xb6ca7e025e2296ea,0x5c2094e8b4c87c00,0xb6ca7e025e2296ea, - 0x4848fefeb6b60000,0xaaaa1c1c5454e2e2,0x4848fefeb6b60000,0xaaaa1c1c5454e2e2, - 0x4f142e753a615b00,0xa0fbc19ad58eb4ef,0x4f142e753a615b00,0xa0fbc19ad58eb4ef, - 0x750c7801740d7900,0x423b4f36433a4e37,0x750c7801740d7900,0x423b4f36433a4e37, - 0x36da26cafc10ec00,0x22ce32dee804f814,0x36da26cafc10ec00,0x22ce32dee804f814, - 0x61bac31879a2db00,0x419ae3385982fb20,0x61bac31879a2db00,0x419ae3385982fb20, - 0x8eb70a33bd843900,0xe6df625bd5ec5168,0x8eb70a33bd843900,0xe6df625bd5ec5168, - 0xc6b9fa85433c7f00,0xa1de9de2245b1867,0xc6b9fa85433c7f00,0xa1de9de2245b1867, - 0xf248813bc973ba00,0xb70dc47e8c36ff45,0xf248813bc973ba00,0xb70dc47e8c36ff45, - 0xb2c5f38436417700,0xf285b3c476013740,0xb2c5f38436417700,0xf285b3c476013740, - 0x5898bb7b23e3c000,0x4c8caf6f37f7d414,0x5898bb7b23e3c000,0x4c8caf6f37f7d414, - 0x76b31edbad68c500,0x9653fe3b4d8825e0,0x76b31edbad68c500,0x9653fe3b4d8825e0, - 0xd064ac18c87cb400,0x52e62e9a4afe3682,0xd064ac18c87cb400,0x52e62e9a4afe3682, - 0x519664a3f235c700,0xa562905706c133f4,0x519664a3f235c700,0xa562905706c133f4, - 0x7b64322d56491f00,0x8d92c4dba0bfe9f6,0x7b64322d56491f00,0x8d92c4dba0bfe9f6, - 0x4f02723f703d4d00,0xcd80f0bdf2bfcf82,0x4f02723f703d4d00,0xcd80f0bdf2bfcf82, - 0xf139cd05f43cc800,0x76be4a8273bb4f87,0xf139cd05f43cc800,0x76be4a8273bb4f87, - 0xecb06539d5895c00,0x5c89d53965b0ec,0xecb06539d5895c00,0x5c89d53965b0ec, - 0xa63959c660ff9f00,0x50cfaf30960969f6,0xa63959c660ff9f00,0x50cfaf30960969f6, - 0x7d1e82e19cff6300,0xd3b02c4f3251cdae,0x7d1e82e19cff6300,0xd3b02c4f3251cdae, - 0xab28bd3e95168300,0x86059013b83bae2d,0xab28bd3e95168300,0x86059013b83bae2d, - 0x6109f39bfa926800,0x325aa0c8a9c13b53,0x6109f39bfa926800,0x325aa0c8a9c13b53, - 0xf6864a3accbc7000,0xc6b67a0afc8c4030,0xf6864a3accbc7000,0xc6b67a0afc8c4030, - 0xa9690bcb62a2c000,0xd61674b41dddbf7f,0xa9690bcb62a2c000,0xd61674b41dddbf7f, - 0xe8b25f05edb75a00,0x7c26cb917923ce94,0xe8b25f05edb75a00,0x7c26cb917923ce94, - 0x67e5da583fbd8200,0xcc4e71f3941629ab,0x67e5da583fbd8200,0xcc4e71f3941629ab, - 0x8e750df67883fb00,0x44bfc73cb24931ca,0x8e750df67883fb00,0x44bfc73cb24931ca, - 0xe451fc49ad18b500,0x95208d38dc69c471,0xe451fc49ad18b500,0x95208d38dc69c471, - 0x51a34dbfee1cf200,0x3f11fedbc4ea052,0x51a34dbfee1cf200,0x3f11fedbc4ea052, - 0x7dcaa21568dfb700,0xe0573f88f5422a9d,0x7dcaa21568dfb700,0xe0573f88f5422a9d, - 0x67d702b2d565b000,0x5beb3e8ee9598c3c,0x67d702b2d565b000,0x5beb3e8ee9598c3c, - 0xb428811da9359c00,0x9804ad318519b02c,0xb428811da9359c00,0x9804ad318519b02c, - 0xb3f31050e3a34000,0x9cdc3f7fcc8c6f2f,0xb3f31050e3a34000,0x9cdc3f7fcc8c6f2f, - 0x3d00734e734e3d00,0x4d70033e033e4d70,0x3d00734e734e3d00,0x4d70033e033e4d70, - 0xdf4c22b16efd9300,0xbe2d43d00f9cf261,0xdf4c22b16efd9300,0xbe2d43d00f9cf261, - 0x36e9419ea877df00,0xb768c01f29f65e81,0x36e9419ea877df00,0xb768c01f29f65e81, - 0xd499afe2367b4d00,0xd39ea8e5317c4a07,0xd499afe2367b4d00,0xd39ea8e5317c4a07, - 0xcfc9edeb24220600,0x5c5a7e78b7b19593,0xcfc9edeb24220600,0x5c5a7e78b7b19593, - 0xc5c3dfd91c1a0600,0x9a9c80864345595f,0xc5c3dfd91c1a0600,0x9a9c80864345595f, - 0x9387120695811400,0xdfcb5e4ad9cd584c,0x9387120695811400,0xdfcb5e4ad9cd584c, - 0xbc469d67db21fa00,0x728853a915ef34ce,0xbc469d67db21fa00,0x728853a915ef34ce, - 0x52c555c290079700,0x980f9f085acd5dca,0x52c555c290079700,0x980f9f085acd5dca, - 0xd7549f1ccb488300,0xc142890add5e9516,0xd7549f1ccb488300,0xc142890add5e9516, - 0x21a8d25b7af38900,0xc44d37be9f166ce5,0x21a8d25b7af38900,0xc44d37be9f166ce5, - 0x8bba5e6fe4d53100,0x5c6d89b83302e6d7,0x8bba5e6fe4d53100,0x5c6d89b83302e6d7, - 0xc565df7fba1aa000,0x9f3f8525e040fa5a,0xc565df7fba1aa000,0x9f3f8525e040fa5a, - 0x17c457849340d300,0x70a330e3f427b467,0x17c457849340d300,0x70a330e3f427b467, - 0xac286eea46c28400,0x6de9af2b870345c1,0xac286eea46c28400,0x6de9af2b870345c1, - 0xf96f29bf46d09600,0xbe286ef80197d147,0xf96f29bf46d09600,0xbe286ef80197d147, - 0xf444bb0bff4fb000,0x76c639897dcd3282,0xf444bb0bff4fb000,0x76c639897dcd3282, - 0xc4f93805c1fc3d00,0x3a07c6fb3f02c3fe,0xc4f93805c1fc3d00,0x3a07c6fb3f02c3fe, - 0x58ca9a0850c29200,0x861444d68e1c4cde,0x58ca9a0850c29200,0x861444d68e1c4cde, - 0x5e045208560c5a00,0x6832643e603a6c36,0x5e045208560c5a00,0x6832643e603a6c36, - 0xa9aac8cb62610300,0x1a197b78d1d2b0b3,0xa9aac8cb62610300,0x1a197b78d1d2b0b3, - 0xf87dac29d1548500,0x47c213966eeb3abf,0xf87dac29d1548500,0x47c213966eeb3abf, - 0x663ffea7c1985900,0xc89150096f36f7ae,0x663ffea7c1985900,0xc89150096f36f7ae, - 0x926e3ec250acfc00,0x897525d94bb7e71b,0x926e3ec250acfc00,0x897525d94bb7e71b, - 0x208f02ad8d22af00,0x369914bb9b34b916,0x208f02ad8d22af00,0x369914bb9b34b916, - 0x2a0b24052f0e2100,0xdffed1f0dafbd4f5,0x2a0b24052f0e2100,0xdffed1f0dafbd4f5, - 0xf1bccd8d7c31400,0xc3d700141b0fd8cc,0xf1bccd8d7c31400,0xc3d700141b0fd8cc, - 0xce0aca0ec004c400,0xe521e125eb2fef2b,0xce0aca0ec004c400,0xe521e125eb2fef2b, - 0xdd97f1bb662c4a00,0x96dcbaf02d67014b,0xdd97f1bb662c4a00,0x96dcbaf02d67014b, - 0x8756fd2cab7ad100,0xbda71a027f65d8c,0x8756fd2cab7ad100,0xbda71a027f65d8c, - 0x410b206a2b614a00,0xd69cb7fdbcf6dd97,0x410b206a2b614a00,0xd69cb7fdbcf6dd97, - 0x754acfff8ab5300,0x2f7c84d7d0837b28,0x754acfff8ab5300,0x2f7c84d7d0837b28, - 0xa9b4766bc2df1d00,0xeef3312c85985a47,0xa9b4766bc2df1d00,0xeef3312c85985a47, - 0x49820dc68f44cb00,0x8e45ca0148830cc7,0x49820dc68f44cb00,0x8e45ca0148830cc7, - 0xe97cc752bb2e9500,0x7ce952c72ebb0095,0xe97cc752bb2e9500,0x7ce952c72ebb0095, - 0x687d9c89e1f41500,0xd2c726335b4eafba,0x687d9c89e1f41500,0xd2c726335b4eafba, - 0x73eadc4536af9900,0x3da4920b78e1d74e,0x73eadc4536af9900,0x3da4920b78e1d74e, - 0xb8ad0a1fa7b21500,0x1005a2b70f1abda8,0xb8ad0a1fa7b21500,0x1005a2b70f1abda8, - 0x44f3fd4a0eb9b700,0xf4434dfabe0907b0,0x44f3fd4a0eb9b700,0xf4434dfabe0907b0, - 0x4e97f42d63bad900,0xa87112cb855c3fe6,0x4e97f42d63bad900,0xa87112cb855c3fe6, - 0x4d7e45763b083300,0x86b58ebdf0c3f8cb,0x4d7e45763b083300,0x86b58ebdf0c3f8cb, - 0x73b75f9be82cc400,0x71b55d99ea2ec602,0x73b75f9be82cc400,0x71b55d99ea2ec602, - 0x7b7ca3a4dfd80700,0x86815e592225fafd,0x7b7ca3a4dfd80700,0x86815e592225fafd, - 0x24ebe6290dc2cf00,0xae616ca38748458a,0x24ebe6290dc2cf00,0xae616ca38748458a, - 0x243cbba3879f1800,0xb3ab2c3410088f97,0x243cbba3879f1800,0xb3ab2c3410088f97, - 0xed17fd07ea10fa00,0x33c923d934ce24de,0xed17fd07ea10fa00,0x33c923d934ce24de, - 0x33b20f8ebd3c8100,0x9e1fa22310912cad,0x33b20f8ebd3c8100,0x9e1fa22310912cad, - 0x9ef0026cf29c6e00,0xa3cd3f51cfa1533d,0x9ef0026cf29c6e00,0xa3cd3f51cfa1533d, - 0x7768c0dfa8b71f00,0xe7f8504f38278f90,0x7768c0dfa8b71f00,0xe7f8504f38278f90, - 0x375bb2dee9856c00,0x2844adc1f69a731f,0x375bb2dee9856c00,0x2844adc1f69a731f, - 0xaf992f19b6803600,0x93a513258abc0a3c,0xaf992f19b6803600,0x93a513258abc0a3c, - 0x7a0f87f288fd7500,0xf1840c790376fe8b,0x7a0f87f288fd7500,0xf1840c790376fe8b, - 0x8015c752d2479500,0xcc598b1e9e0bd94c,0x8015c752d2479500,0xcc598b1e9e0bd94c, - 0x8023be1d9d3ea300,0x48eb76d555f66bc8,0x8023be1d9d3ea300,0x48eb76d555f66bc8, - 0x9c2f21920ebdb300,0x15a6a81b87343a89,0x9c2f21920ebdb300,0x15a6a81b87343a89, - 0x30d356b58566e300,0x8e6de80b3bd85dbe,0x30d356b58566e300,0x8e6de80b3bd85dbe, - 0xa9a6222d848b0f00,0xded1555af3fc7877,0xa9a6222d848b0f00,0xded1555af3fc7877, - 0xa7c9d9b7107e6e00,0x76180866c1afbfd1,0xa7c9d9b7107e6e00,0x76180866c1afbfd1, - 0x6c02f59bf7996e00,0x8ae4137d117f88e6,0x6c02f59bf7996e00,0x8ae4137d117f88e6, - 0xb31f2884379bac00,0xcc6057fb48e4d37f,0xb31f2884379bac00,0xcc6057fb48e4d37f, - 0x24dcd62e0af2f800,0x89717b83a75f55ad,0x24dcd62e0af2f800,0x89717b83a75f55ad, - 0xe29fdca1433e7d00,0xe79ad9a4463b7805,0xe29fdca1433e7d00,0xe79ad9a4463b7805, - 0x4f75caf0bf853a00,0xcdf748723d07b882,0x4f75caf0bf853a00,0xcdf748723d07b882, - 0x9ed3d69b05484d00,0x6924216cf2bfbaf7,0x9ed3d69b05484d00,0x6924216cf2bfbaf7, - 0x4bba837239c8f100,0x4bba837239c8f100,0x4bba837239c8f100,0x4bba837239c8f100, - 0xf0fe2a24d4da0e00,0x353befe1111fcbc5,0xf0fe2a24d4da0e00,0x353befe1111fcbc5, - 0xa1c3a5c766046200,0xb6d4b2d071137517,0xa1c3a5c766046200,0xb6d4b2d071137517, - 0x733a94ddaee74900,0xfeb71950236ac48d,0x733a94ddaee74900,0xfeb71950236ac48d, - 0x43b2906122d3f100,0x7081a35211e0c233,0x43b2906122d3f100,0x7081a35211e0c233, - 0x7281906311e2f300,0x9c6f7e8dff0c1dee,0x7281906311e2f300,0x9c6f7e8dff0c1dee, - 0x681709761e617f00,0x1a657b046c130d72,0x681709761e617f00,0x1a657b046c130d72, - 0xa7876040e7c7200,0xc7e7002087a7406,0xa7876040e7c7200,0xc7e7002087a7406, - 0xe747d2729535a000,0x379702a245e570d0,0xe747d2729535a000,0x379702a245e570d0, - 0x1914a6abb2bf0d00,0x5b56e4e9f0fd4f42,0x1914a6abb2bf0d00,0x5b56e4e9f0fd4f42, - 0xea8a4020caaa600,0x1bbdb11719bfb315,0xea8a4020caaa600,0x1bbdb11719bfb315, - 0xfd5343ed10beae00,0x832d3d936ec0d07e,0xfd5343ed10beae00,0x832d3d936ec0d07e, - 0xa5a5b3b316160000,0x71716767c2c2d4d4,0xa5a5b3b316160000,0x71716767c2c2d4d4, - 0x4ae8c262288aa00,0x2e84a60c08a2802a,0x4ae8c262288aa00,0x2e84a60c08a2802a, - 0xb5017ace7bcfb400,0xb4007bcf7aceb501,0xb5017ace7bcfb400,0xb4007bcf7aceb501, - 0xdddf42429f9d000,0xd2022bfbf6260fdf,0xdddf42429f9d000,0xd2022bfbf6260fdf, - 0xf3c9ffc5360c3a00,0xd2e8dee4172d1b21,0xf3c9ffc5360c3a00,0xd2e8dee4172d1b21, - 0x966f847deb12f900,0xf60fe41d8b729960,0x966f847deb12f900,0xf60fe41d8b729960, - 0xeca5ffb65a134900,0xe5acf6bf531a4009,0xeca5ffb65a134900,0xe5acf6bf531a4009, - 0xd286c49042165400,0x72266430e2b6f4a0,0xd286c49042165400,0x72266430e2b6f4a0, - 0xb02146d767f69100,0x62f39405b52443d2,0xb02146d767f69100,0x62f39405b52443d2, - 0xc563b214d177a600,0xe2449533f6508127,0xc563b214d177a600,0xe2449533f6508127, - 0x8d48ae6be623c500,0x509573b63bfe18dd,0x8d48ae6be623c500,0x509573b63bfe18dd, - 0xdc702d815df1ac00,0xf75b06aa76da872b,0xdc702d815df1ac00,0xf75b06aa76da872b, - 0x7452b395e1c72600,0x90b657710523c2e4,0x7452b395e1c72600,0x90b657710523c2e4, - 0xb8480cfc44b4f000,0x50a0e414ac5c18e8,0xb8480cfc44b4f000,0x50a0e414ac5c18e8, - 0xc11072a362b3d100,0xc61775a465b4d607,0xc11072a362b3d100,0xc61775a465b4d607, - 0x97bfa28a1d352800,0xc9e1fcd4436b765e,0x97bfa28a1d352800,0xc9e1fcd4436b765e, - 0xf62cd00afc26da00,0x429864be48926eb4,0xf62cd00afc26da00,0x429864be48926eb4, - 0x340cdee6d2ea3800,0x2b13c1f9cdf5271f,0x340cdee6d2ea3800,0x2b13c1f9cdf5271f, - 0x5fc8c156099e9700,0xd84f46d18e191087,0x5fc8c156099e9700,0xd84f46d18e191087, - 0x4cf36cd39f20bf00,0x11ae318ec27de25d,0x4cf36cd39f20bf00,0x11ae318ec27de25d, - 0xed2f2def02c0c200,0xaf6d6fad40828042,0xed2f2def02c0c200,0xaf6d6fad40828042, - 0x190da8bca5b11400,0xbfab0e1a0317b2a6,0x190da8bca5b11400,0xbfab0e1a0317b2a6, - 0x6d276e2449034a00,0x4309400a672d642e,0x6d276e2449034a00,0x4309400a672d642e, - 0xb3bda2ac1f110e00,0x323c232d9e908f81,0xb3bda2ac1f110e00,0x323c232d9e908f81, - 0x30e213c1f123d200,0x6cbe4f9dad7f8e5c,0x30e213c1f123d200,0x6cbe4f9dad7f8e5c, - 0x97ec790295ee7b00,0x4d36a3d84f34a1da,0x97ec790295ee7b00,0x4d36a3d84f34a1da, - 0x5cebbc0b57e0b700,0x6bdc8b3c60d78037,0x5cebbc0b57e0b700,0x6bdc8b3c60d78037, - 0x30380f07373f0800,0x60685f57676f5850,0x30380f07373f0800,0x60685f57676f5850, - 0xdc3dc121fd1ce00,0xe12f30fef33d22ec,0xdc3dc121fd1ce00,0xe12f30fef33d22ec, - 0xc7894a04c38d4e00,0x1d5390de195794da,0xc7894a04c38d4e00,0x1d5390de195794da, - 0xbb19ac0eb517a200,0x1bb90cae15b702a0,0xbb19ac0eb517a200,0x1bb90cae15b702a0, - 0x1e2c3d0f11233200,0xc3e2f1d03312012,0x1e2c3d0f11233200,0xc3e2f1d03312012, - 0x7af3e56c169f8900,0xd84921b61e8fe77,0x7af3e56c169f8900,0xd84921b61e8fe77, - 0xaa72409832ead800,0xfe2614cc66be8c54,0xaa72409832ead800,0xfe2614cc66be8c54, - 0xdcdd80815d5c0100,0xf2f3aeaf73722f2e,0xdcdd80815d5c0100,0xf2f3aeaf73722f2e, - 0xd8eae2d20a38300,0xbb38189b961535b6,0xd8eae2d20a38300,0xbb38189b961535b6, - 0x5add65e2b83f8700,0x68139bee463db5c,0x5add65e2b83f8700,0x68139bee463db5c, - 0x3b8450efd46bbf00,0xf946922d16a97dc2,0x3b8450efd46bbf00,0xf946922d16a97dc2, - 0x2d903885a815bd00,0x79c46cd1fc41e954,0x2d903885a815bd00,0x79c46cd1fc41e954, - 0xe3111def0cfef200,0xb3414dbf5caea250,0xe3111def0cfef200,0xb3414dbf5caea250, - 0xe19e2e51b0cf7f00,0x778c8b7562999e6,0xe19e2e51b0cf7f00,0x778c8b7562999e6, - 0x974cd803944fdb00,0x449f0bd0479c08d3,0x974cd803944fdb00,0x449f0bd0479c08d3, - 0xd92bf002db29f200,0x6f42fdd04f62ddf,0xd92bf002db29f200,0x6f42fdd04f62ddf, - 0xcb56a538f36e9d00,0x4996af73ca152cf,0xcb56a538f36e9d00,0x4996af73ca152cf, - 0x26238386a0a50500,0x838626230500a0a5,0x26238386a0a50500,0x838626230500a0a5, - 0xd6843c6eb8ea5200,0x7c2e96c41240f8aa,0xd6843c6eb8ea5200,0x7c2e96c41240f8aa, - 0x6f41e0cea18f2e00,0x755bfad4bb95341a,0x6f41e0cea18f2e00,0x755bfad4bb95341a, - 0x982e2e9800b6b600,0x67d1d167ff4949ff,0x982e2e9800b6b600,0x67d1d167ff4949ff, - 0xc2acd5bb79176e00,0xe688f19f5d334a24,0xc2acd5bb79176e00,0xe688f19f5d334a24, - 0x44aa14fabe50ee00,0x9876c826628c32dc,0x44aa14fabe50ee00,0x9876c826628c32dc, - 0x34a21482b6209600,0x63f543d5e177c157,0x34a21482b6209600,0x63f543d5e177c157, - 0x620cb8d6b4da6e00,0x46289cf290fe4a24,0x620cb8d6b4da6e00,0x46289cf290fe4a24, - 0xef7d0e9c73e19200,0x9f0d7eec0391e270,0xef7d0e9c73e19200,0x9f0d7eec0391e270, - 0x90f17d1c8ced6100,0xb0d15d3caccd4120,0x90f17d1c8ced6100,0xb0d15d3caccd4120, - 0xba7cd016ac6ac600,0xe4228e48f234985e,0xba7cd016ac6ac600,0xe4228e48f234985e, - 0xdb88ce9d46155300,0xa591f4c97c482d1,0xdb88ce9d46155300,0xa591f4c97c482d1, - 0xccf6734985bf3a00,0x7f45c0fa360c89b3,0xccf6734985bf3a00,0x7f45c0fa360c89b3, - 0xa6fee5bd1b435800,0xe4bca7ff59011a42,0xa6fee5bd1b435800,0xe4bca7ff59011a42, - 0x3ab029a399138a00,0x41cb52d8e268f17b,0x3ab029a399138a00,0x41cb52d8e268f17b, - 0x9b924d44dfd60900,0x343de2eb7079a6af,0x9b924d44dfd60900,0x343de2eb7079a6af, - 0x44ddc9591d84900,0x7039a8e1e5ac3d74,0x44ddc9591d84900,0x7039a8e1e5ac3d74, - 0xa1b1f8e849591000,0x617138288999d0c0,0xa1b1f8e849591000,0x617138288999d0c0, - 0xe26b4ac321a88900,0x1198b930d25b7af3,0xe26b4ac321a88900,0x1198b930d25b7af3, - 0x5940160f564f1900,0x372e78613821776e,0x5940160f564f1900,0x372e78613821776e, - 0xdbb2127ba0c96900,0x6a03a3ca1178d8b1,0xdbb2127ba0c96900,0x6a03a3ca1178d8b1, - 0x92639c6dff0ef100,0x72837c8d1fee11e0,0x92639c6dff0ef100,0x72837c8d1fee11e0, - 0xafa2bfb21d100d00,0x878a979a35382528,0xafa2bfb21d100d00,0x878a979a35382528, - 0xc9ede8cc05212400,0x1f3b3e1ad3f7f2d6,0xc9ede8cc05212400,0x1f3b3e1ad3f7f2d6, - 0xa9a28289202b0b00,0x4f44646fc6cdede6,0xa9a28289202b0b00,0x4f44646fc6cdede6, - 0xa4f592c367365100,0x6b3a5d0ca8f99ecf,0xa4f592c367365100,0x6b3a5d0ca8f99ecf, - 0xe3304c9f7cafd300,0xfd2e528162b1cd1e,0xe3304c9f7cafd300,0xfd2e528162b1cd1e, - 0xe6ca0529cfe32c00,0xdff33c10f6da1539,0xe6ca0529cfe32c00,0xdff33c10f6da1539, - 0xcd403cb17cf18d00,0xc74a36bb76fb870a,0xcd403cb17cf18d00,0xc74a36bb76fb870a, - 0xeda64f04e9a24b00,0x92d9307b96dd347f,0xeda64f04e9a24b00,0x92d9307b96dd347f, - 0x86be7941c7ff3800,0xf6ce0931b78f4870,0x86be7941c7ff3800,0xf6ce0931b78f4870, - 0x71a4a87d0cd9d500,0xcb1e12c7b6636fba,0x71a4a87d0cd9d500,0xcb1e12c7b6636fba, - 0x757d848cf9f10800,0x1911e8e0959d646c,0x757d848cf9f10800,0x1911e8e0959d646c, - 0xf0349e5aaa6ec400,0x9cd67a353973df9,0xf0349e5aaa6ec400,0x9cd67a353973df9, - 0x2d18d2e7caff3500,0x72478db895a06a5f,0x2d18d2e7caff3500,0x72478db895a06a5f, - 0x9e148a0a941e800,0x31d970989179d038,0x9e148a0a941e800,0x31d970989179d038, - 0xac55af56fa03f900,0x38c13bc26e976d94,0xac55af56fa03f900,0x38c13bc26e976d94, - 0x3c04a898a49c300,0xdc1f955655961cdf,0x3c04a898a49c300,0xdc1f955655961cdf, - 0x71cbc97302b8ba00,0x3b9bb0170cac872,0x71cbc97302b8ba00,0x3b9bb0170cac872, - 0xcecdf6f53b380300,0x7a7942418f8cb7b4,0xcecdf6f53b380300,0x7a7942418f8cb7b4, - 0x85d9f7ab2e725c00,0x48143a66e3bf91cd,0x85d9f7ab2e725c00,0x48143a66e3bf91cd, - 0x7275313644430700,0x90e4a4d3f387c7b,0x7275313644430700,0x90e4a4d3f387c7b, - 0x8e1fef7ef0619100,0x3aab5bca44d525b4,0x8e1fef7ef0619100,0x3aab5bca44d525b4, - 0x11e28e7d6c9ff300,0xdd2e42b1a0533fcc,0x11e28e7d6c9ff300,0xdd2e42b1a0533fcc, - 0x933bcb63f058a800,0xd27a8a22b119e941,0x933bcb63f058a800,0xd27a8a22b119e941, - 0x2c00012d012d2c00,0xf0dcddf1ddf1f0dc,0x2c00012d012d2c00,0xf0dcddf1ddf1f0dc, - 0x469033e5a375d600,0xd701a27432e44791,0x469033e5a375d600,0xd701a27432e44791, - 0x5237fb9ecca96500,0x1f7ab6d381e4284d,0x5237fb9ecca96500,0x1f7ab6d381e4284d, - 0x7e7f3c3d43420100,0x8180c3c2bcbdfeff,0x7e7f3c3d43420100,0x8180c3c2bcbdfeff, - 0x68688f8fe7e70000,0xe7e7000068688f8f,0x68688f8fe7e70000,0xe7e7000068688f8f, - 0x2211d8ebc9fa3300,0xddee27143605ccff,0x2211d8ebc9fa3300,0xddee27143605ccff, - 0x4e4e8484caca0000,0xf2f238387676bcbc,0x4e4e8484caca0000,0xf2f238387676bcbc, - 0x543dbad387ee6900,0xd3ba3d540069ee87,0x543dbad387ee6900,0xd3ba3d540069ee87, - 0xcccc1212dede0000,0x1b1bc5c50909d7d7,0xcccc1212dede0000,0x1b1bc5c50909d7d7, - 0xac45719834dde900,0x678eba53ff1622cb,0xac45719834dde900,0x678eba53ff1622cb, - 0x4b4b030348480000,0xfdfdb5b5fefeb6b6,0x4b4b030348480000,0xfdfdb5b5fefeb6b6, - 0x4e1d21723c6f5300,0x580b37642a794516,0x4e1d21723c6f5300,0x580b37642a794516, - 0x8a8a1e1e94940000,0xeaea7e7ef4f46060,0x8a8a1e1e94940000,0xeaea7e7ef4f46060, - 0xa1a8a5ac0d040900,0x8f868b82232a272e,0xa1a8a5ac0d040900,0x8f868b82232a272e, - 0xf9f9b7b74e4e0000,0xe4e4aaaa53531d1d,0xf9f9b7b74e4e0000,0xe4e4aaaa53531d1d, - 0xcbeecce922072500,0x8bae8ca962476540,0xcbeecce922072500,0x8bae8ca962476540, - 0xd5d53434e1e10000,0x606e7e73232d3d3,0xd5d53434e1e10000,0x606e7e73232d3d3, - 0x1897d8574fc08f00,0x36b9f67961eea12e,0x1897d8574fc08f00,0x36b9f67961eea12e, - 0x4949dede97970000,0xf8f86f6f2626b1b1,0x4949dede97970000,0xf8f86f6f2626b1b1, - 0x34e3f72014c3d700,0x35e2f62115c2d601,0x34e3f72014c3d700,0x35e2f62115c2d601, - 0x23f2e13112c3d00,0x576a7b4644796855,0x23f2e13112c3d00,0x576a7b4644796855, - 0x9a92424ad0d80800,0x6e66b6be242cfcf4,0x9a92424ad0d80800,0x6e66b6be242cfcf4, - 0x7874c9c5bdb10c00,0xe3ef525e262a979b,0x7874c9c5bdb10c00,0xe3ef525e262a979b, - 0x1083a93a2ab99300,0x891a30a3b3200a99,0x1083a93a2ab99300,0x891a30a3b3200a99, - 0xa4aa5d53f7f90e00,0x737d8a84202ed9d7,0xa4aa5d53f7f90e00,0x737d8a84202ed9d7, - 0x8cd5540d81d85900,0x851d089055cdd84,0x8cd5540d81d85900,0x851d089055cdd84, - 0x4047060141460700,0x4542030444430205,0x4047060141460700,0x4542030444430205, - 0x4fa4be551af1eb00,0x2ac1db307f948e65,0x4fa4be551af1eb00,0x2ac1db307f948e65, - 0xdded3303deee3000,0xdded3303deee3000,0xdded3303deee3000,0xdded3303deee3000, - 0x90a85868f8c0300,0x2122adaea7a42b28,0x90a85868f8c0300,0x2122adaea7a42b28, - 0x901f3ab525aa8f00,0xa827028d1d92b738,0x901f3ab525aa8f00,0xa827028d1d92b738, - 0x4c12b4eaa6f85e00,0x5709aff1bde3451b,0x4c12b4eaa6f85e00,0x5709aff1bde3451b, - 0x7025e1b4c4915500,0x90c501542471b5e0,0x7025e1b4c4915500,0x90c501542471b5e0, - 0xc1b45227e6937500,0x4336d0a56411f782,0xc1b45227e6937500,0x4336d0a56411f782, - 0xfe1011ff01efee00,0x28c6c729d73938d6,0xfe1011ff01efee00,0x28c6c729d73938d6, - 0x8228ba109238aa00,0x7ad3f9517bd2f85,0x8228ba109238aa00,0x7ad3f9517bd2f85, - 0xb79b200cbb972c00,0x19358ea2153982ae,0xb79b200cbb972c00,0x19358ea2153982ae, - 0x6fa25b96f934cd00,0x458871bcd31ee72a,0x6fa25b96f934cd00,0x458871bcd31ee72a, - 0x21e2c40726e5c300,0xf13214d7f63513d0,0x21e2c40726e5c300,0xf13214d7f63513d0, - 0x8c8aded854520600,0xdbdd898f03055157,0x8c8aded854520600,0xdbdd898f03055157, - 0x6e190d7a14637700,0x92e5f186e89f8bfc,0x6e190d7a14637700,0x92e5f186e89f8bfc, - 0x4fdd099bd4469200,0x168450c28d1fcb59,0x4fdd099bd4469200,0x168450c28d1fcb59, - 0xec7e92927eec00,0x5db123cfcf23b15d,0xec7e92927eec00,0x5db123cfcf23b15d, - 0x7e10177907696e00,0xe08e89e799f7f09e,0x7e10177907696e00,0xe08e89e799f7f09e, - 0xbb5dd2348f69e600,0xcb2da244ff199670,0xbb5dd2348f69e600,0xcb2da244ff199670, - 0x87f62151d6a7700,0x88ffe2959deaf780,0x87f62151d6a7700,0x88ffe2959deaf780, - 0x791cb9dca5c06500,0x5e3b9efb82e74227,0x791cb9dca5c06500,0x5e3b9efb82e74227, - 0x87b3a39710243400,0xa49080b433071723,0x87b3a39710243400,0xa49080b433071723, - 0xde2ec737e919f000,0x6f9f768658a841b1,0xde2ec737e919f000,0x6f9f768658a841b1, - 0x5ab74dadf71ae00,0x228c53fdf8568927,0x5ab74dadf71ae00,0x228c53fdf8568927, - 0xbb832018a39b3800,0x84bc1f279ca4073f,0xbb832018a39b3800,0x84bc1f279ca4073f, - 0xb0f8b2fa4a024800,0x84cc86ce7e367c34,0xb0f8b2fa4a024800,0x84cc86ce7e367c34, - 0x6f1e42335c2d7100,0xc0b1ed9cf382deaf,0x6f1e42335c2d7100,0xc0b1ed9cf382deaf, - 0x7a8ea0542edaf400,0xcd3917e3996d43b7,0x7a8ea0542edaf400,0xcd3917e3996d43b7, - 0x7f33175b24684c00,0x3d715519662a0e42,0x7f33175b24684c00,0x3d715519662a0e42, - 0xf7c41221d6e53300,0x8dbe685bac9f497a,0xf7c41221d6e53300,0x8dbe685bac9f497a, - 0x4fbbf4f4bb4f00,0xffb0440b0b44b0ff,0x4fbbf4f4bb4f00,0xffb0440b0b44b0ff, - 0x8405f170f4758100,0xd455a120a425d150,0x8405f170f4758100,0xd455a120a425d150, - 0xb240a85ae81af200,0x699b738133c129db,0xb240a85ae81af200,0x699b738133c129db, - 0xdead5724fa897300,0x592ad0a37d0ef487,0xdead5724fa897300,0x592ad0a37d0ef487, - 0x68201c543c744800,0x723a064e266e521a,0x68201c543c744800,0x723a064e266e521a, - 0x219acb7051eabb00,0x9b2071caeb5001ba,0x219acb7051eabb00,0x9b2071caeb5001ba, - 0x80b75562e2d53700,0x536486b13106e4d3,0x80b75562e2d53700,0x536486b13106e4d3, - 0x6d91f9056894fc00,0x6995fd016c90f804,0x6d91f9056894fc00,0x6995fd016c90f804, - 0x5cb17895c924ed00,0x668b42aff31ed73a,0x5cb17895c924ed00,0x668b42aff31ed73a, - 0x5a4f55451f0a100,0x1abbea4b4eefbe1f,0x5a4f55451f0a100,0x1abbea4b4eefbe1f, - 0x32bcaa2416988e00,0x73fdeb6557d9cf41,0x32bcaa2416988e00,0x73fdeb6557d9cf41, - 0xda3d44a3799ee700,0x43a4dd3ae0077e99,0xda3d44a3799ee700,0x43a4dd3ae0077e99, - 0xf9d25b7089a22b00,0x6e45cce71e35bc97,0xf9d25b7089a22b00,0x6e45cce71e35bc97, - 0x67c341e58226a400,0xe94dcf6b0ca82a8e,0x67c341e58226a400,0xe94dcf6b0ca82a8e, - 0xdbae7b0ed5a07500,0x205580f52e5b8efb,0xdbae7b0ed5a07500,0x205580f52e5b8efb, - 0x5d8528f8a57dd00,0x24f973aeab76fc21,0x5d8528f8a57dd00,0x24f973aeab76fc21, - 0xac027cd27ed0ae00,0xea0de70dc720ca2,0xac027cd27ed0ae00,0xea0de70dc720ca2, - 0x1c90da564ac68c00,0x911d57dbc74b018d,0x1c90da564ac68c00,0x911d57dbc74b018d, - 0xc04c5ad6169a8c00,0x1a96800ccc4056da,0xc04c5ad6169a8c00,0x1a96800ccc4056da, - 0xfadf2c09f3d62500,0x3411e2c73d18ebce,0xfadf2c09f3d62500,0x3411e2c73d18ebce, - 0xcf77e35b942cb800,0xb901952de25ace76,0xcf77e35b942cb800,0xb901952de25ace76, - 0xf46a9806f26c9e00,0x31af5dc337a95bc5,0xf46a9806f26c9e00,0x31af5dc337a95bc5, - 0xf0fee9e717190e00,0xb4baada3535d4a44,0xf0fee9e717190e00,0xb4baada3535d4a44, - 0x845b06d95d82df00,0xf12e73ac28f7aa75,0x845b06d95d82df00,0xf12e73ac28f7aa75, - 0x2b745b042f705f00,0xda85aaf5de81aef1,0x2b745b042f705f00,0xda85aaf5de81aef1, - 0x2f65561c33794a00,0x713b08426d27145e,0x2f65561c33794a00,0x713b08426d27145e, - 0x21f25586a774d300,0x33e04794b566c112,0x21f25586a774d300,0x33e04794b566c112, - 0xb3d27d1cafce6100,0xe0812e4ffc9d3253,0xb3d27d1cafce6100,0xe0812e4ffc9d3253, - 0x11fc34d9c825ed00,0xa74a826f7e935bb6,0x11fc34d9c825ed00,0xa74a826f7e935bb6, - 0x596d77431a2e3400,0x3f0b11257c485266,0x596d77431a2e3400,0x3f0b11257c485266, - 0x5c7f684b17342300,0x1c3f280b57746340,0x5c7f684b17342300,0x1c3f280b57746340, - 0xfee4b5af514b1a00,0x554f1e04fae0b1ab,0xfee4b5af514b1a00,0x554f1e04fae0b1ab, - 0x573c7a11462d6b00,0x5932741f4823650e,0x573c7a11462d6b00,0x5932741f4823650e, - 0x624e476b09252c00,0xe222b076549406c,0x624e476b09252c00,0xe222b076549406c, - 0xf58f6e14e19b7a00,0x2258b9c3364cadd7,0xf58f6e14e19b7a00,0x2258b9c3364cadd7, - 0x24e65a98bc7ec200,0x75b70bc9ed2f9351,0x24e65a98bc7ec200,0x75b70bc9ed2f9351, - 0xafb4445ff0eb1b00,0x8c97677cd3c83823,0xafb4445ff0eb1b00,0x8c97677cd3c83823, - 0xd2277f8a58adf500,0xe81d45b06297cf3a,0xd2277f8a58adf500,0xe81d45b06297cf3a, - 0xdef1b39c426d2f00,0x113e7c538da2e0cf,0xdef1b39c426d2f00,0x113e7c538da2e0cf, - 0x99667d821be4ff00,0xce312ad54cb3a857,0x99667d821be4ff00,0xce312ad54cb3a857, - 0xc62dfe15d338eb00,0x5eb5668d4ba07398,0xc62dfe15d338eb00,0x5eb5668d4ba07398, - 0xfbe60d1de6fb100,0x3e8f51e0ef5e8031,0xfbe60d1de6fb100,0x3e8f51e0ef5e8031, - 0x63d544f29127b600,0x3b52492f147d660,0x63d544f29127b600,0x3b52492f147d660, - 0x2ce728e3cf04cb00,0xaf64ab604c874883,0x2ce728e3cf04cb00,0xaf64ab604c874883, - 0xefda7a4fa0953500,0x8bbe1e2bc4f15164,0xefda7a4fa0953500,0x8bbe1e2bc4f15164, - 0x160f435a4c551900,0x3128647d6b723e27,0x160f435a4c551900,0x3128647d6b723e27, - 0x6ef775ec821b9900,0xcf56d44d23ba38a1,0x6ef775ec821b9900,0xcf56d44d23ba38a1, - 0xde0f11c11fced00,0xa74a5bb6bb5647aa,0xde0f11c11fced00,0xa74a5bb6bb5647aa, - 0xdb953f71aae44e00,0x82cc6628f3bd1759,0xdb953f71aae44e00,0x82cc6628f3bd1759, - 0xf42b37e81cc3df00,0xd30c10cf3be4f827,0xf42b37e81cc3df00,0xd30c10cf3be4f827, - 0x7c51c6eb97ba2d00,0x406dfad7ab86113c,0x7c51c6eb97ba2d00,0x406dfad7ab86113c, - 0x1c39ffdac6e32500,0x604583a6ba9f597c,0x1c39ffdac6e32500,0x604583a6ba9f597c, - 0x8ef7126be59c7900,0xfb82671e90e90c75,0x8ef7126be59c7900,0xfb82671e90e90c75, - 0xffafaafa05555000,0xfcaca9f906565303,0xffafaafa05555000,0xfcaca9f906565303, - 0x3f041b2b142f300,0xcf3c8d7e7d8e3fcc,0x3f041b2b142f300,0xcf3c8d7e7d8e3fcc, - 0x9f4aa277e83dd500,0x1fca22f768bd5580,0x9f4aa277e83dd500,0x1fca22f768bd5580, - 0x6b01b6dcb7dd6a00,0x244ef993f892254f,0x6b01b6dcb7dd6a00,0x244ef993f892254f, - 0x76f9da5523ac8f00,0xaa250689ff7053dc,0x76f9da5523ac8f00,0xaa250689ff7053dc, - 0x166bf78a9ce17d00,0x7d009ce1f78a166b,0x166bf78a9ce17d00,0x7d009ce1f78a166b, - 0x30e6e33505d3d600,0x78aeab7d4d9b9e48,0x30e6e33505d3d600,0x78aeab7d4d9b9e48, - 0x20b2a03212809200,0xa93b29bb9b091b89,0x20b2a03212809200,0xa93b29bb9b091b89, - 0xf3aff6aa59055c00,0x570b520efda1f8a4,0xf3aff6aa59055c00,0x570b520efda1f8a4, - 0xfba60c51aaf75d00,0xb5e8421fe4b9134e,0xfba60c51aaf75d00,0xb5e8421fe4b9134e, - 0xa3628849ea2bc100,0xa0618b4ae928c203,0xa3628849ea2bc100,0xa0618b4ae928c203, - 0xd1fc2d00d1fc2d00,0xcee3321fcee3321f,0xd1fc2d00d1fc2d00,0xcee3321fcee3321f, - 0x4d00a5e8a5e84d00,0xb46e3aee3ae0b46,0x4d00a5e8a5e84d00,0xb46e3aee3ae0b46, - 0x8647dc1d9b5ac100,0xa465fe3fb978e322,0x8647dc1d9b5ac100,0xa465fe3fb978e322, - 0xb9bd84843d39000,0x2dbdfe6e65f5b626,0xb9bd84843d39000,0x2dbdfe6e65f5b626, - 0x82ab577efcd52900,0x5a738fa6240df1d8,0x82ab577efcd52900,0x5a738fa6240df1d8, - 0xb1f9246cdd954800,0x18508dc5743ce1a9,0xb1f9246cdd954800,0x18508dc5743ce1a9, - 0x5697814117d6c00,0xed8190fcf99584e8,0x5697814117d6c00,0xed8190fcf99584e8, - 0x2249e78caec56b00,0x660da3c8ea812f44,0x2249e78caec56b00,0x660da3c8ea812f44, - 0x93f0610291f26300,0xe6851477e4871675,0x93f0610291f26300,0xe6851477e4871675, - 0x4a84c8064c82ce00,0x65abe72963ade12f,0x4a84c8064c82ce00,0x65abe72963ade12f, - 0x8670ce38be48f600,0x7f8937c147b10ff9,0x8670ce38be48f600,0x7f8937c147b10ff9, - 0xbfd2cea31c716d00,0x6e031f72cda0bcd1,0xbfd2cea31c716d00,0x6e031f72cda0bcd1, - 0x89167be46df29f00,0xd74825ba33acc15e,0x89167be46df29f00,0xd74825ba33acc15e, - 0x6b3d2472194f5600,0xe7b1a8fe95c3da8c,0x6b3d2472194f5600,0xe7b1a8fe95c3da8c, - 0x80ce80ce4e004e00,0x501e501e9ed09ed0,0x80ce80ce4e004e00,0x501e501e9ed09ed0, - 0x5ac31089d34a9900,0x77ee3da4fe67b42d,0x5ac31089d34a9900,0x77ee3da4fe67b42d, - 0x775398bccbef2400,0x2b0fc4e097b3785c,0x775398bccbef2400,0x2b0fc4e097b3785c, - 0xa7f21742e5b05500,0x5104e1b41346a3f6,0xa7f21742e5b05500,0x5104e1b41346a3f6, - 0xceb2fc8c423e700,0x29ce0aede106c225,0xceb2fc8c423e700,0x29ce0aede106c225, - 0x67ffe57d1a829800,0x56ced44c2bb3a931,0x67ffe57d1a829800,0x56ced44c2bb3a931, - 0xb42767f440d39300,0x59ca8a19ad3e7eed,0xb42767f440d39300,0x59ca8a19ad3e7eed, - 0x4f612d034c622e00,0xd3fdb19fd0feb29c,0x4f612d034c622e00,0xd3fdb19fd0feb29c, - 0x9750c90e995ec700,0xf433aa6dfa3da463,0x9750c90e995ec700,0xf433aa6dfa3da463, - 0x645ffbc0a49f3b00,0xd0eb4f74102b8fb4,0x645ffbc0a49f3b00,0xd0eb4f74102b8fb4, - 0x931b951d8e068800,0xd850b831098169e,0x931b951d8e068800,0xd850b831098169e, - 0x7e50a28cf2dc2e00,0xf2dc2e007e50a28c,0x7e50a28cf2dc2e00,0xf2dc2e007e50a28c, - 0xa3548671d225f700,0x2cdb09fe5daa788f,0xa3548671d225f700,0x2cdb09fe5daa788f, - 0x1d41184459055c00,0xc29ec79b86da83df,0x1d41184459055c00,0xc29ec79b86da83df, - 0x7ace1ca8d266b400,0xa511c3770db96bdf,0x7ace1ca8d266b400,0xa511c3770db96bdf, - 0x392d697d44501400,0x8c98dcc8f1e5a1b5,0x392d697d44501400,0x8c98dcc8f1e5a1b5, - 0x6b74554a213e1f00,0x9a85a4bbd0cfeef1,0x6b74554a213e1f00,0x9a85a4bbd0cfeef1, - 0xd0eb073cecd73b00,0xbd866a5181ba566d,0xd0eb073cecd73b00,0xbd866a5181ba566d, - 0xb44c25dd6991f800,0x1ee68f77c33b52aa,0xb44c25dd6991f800,0x1ee68f77c33b52aa, - 0xe65a338f69d5bc00,0x942841fd1ba7ce72,0xe65a338f69d5bc00,0x942841fd1ba7ce72, - 0xe32c8f40a36ccf00,0xa966c50ae926854a,0xe32c8f40a36ccf00,0xa966c50ae926854a, - 0x1fa2813c239ebd00,0x84391aa7b805269b,0x1fa2813c239ebd00,0x84391aa7b805269b, - 0x83ddfca2217f5e00,0xffa180de5d03227c,0x83ddfca2217f5e00,0xffa180de5d03227c, - 0x486c0521694d2400,0x76523b1f57731a3e,0x486c0521694d2400,0x76523b1f57731a3e, - 0xb37b3af24189c800,0xc20a4b8330f8b971,0xb37b3af24189c800,0xc20a4b8330f8b971, - 0xd5a0205580f57500,0x2055d5a0750080f5,0xd5a0205580f57500,0x2055d5a0750080f5, - 0xebef84806b6f0400,0xeeea81856e6a0105,0xebef84806b6f0400,0xeeea81856e6a0105, - 0xef2033fc13dccf00,0xcf0013dc33fcef20,0xef2033fc13dccf00,0xcf0013dc33fcef20, - 0x3f983493ac0ba700,0xac0ba7003f983493,0x3f983493ac0ba700,0xac0ba7003f983493, - 0x29483c5d74156100,0xd0b1c5a48dec98f9,0x29483c5d74156100,0xd0b1c5a48dec98f9, - 0xfbc34b7388b03800,0xf8c048708bb33b03,0xfbc34b7388b03800,0xf8c048708bb33b03, - 0x86d8b6e86e305e00,0x732d431d9bc5abf5,0x86d8b6e86e305e00,0x732d431d9bc5abf5, - 0x6626014127674000,0xc484a3e385c5e2a2,0x6626014127674000,0xc484a3e385c5e2a2, - 0x37cea0596e97f900,0x6b92fc0532cba55c,0x37cea0596e97f900,0x6b92fc0532cba55c, - 0x1bbc73d4cf68a700,0xff5897302b8c43e4,0x1bbc73d4cf68a700,0xff5897302b8c43e4, - 0x3ca6e27844de9a00,0xf95d14b77eda933,0x3ca6e27844de9a00,0xf95d14b77eda933, - 0x1da2e25d40ffbf00,0xdc63239c813e7ec1,0x1da2e25d40ffbf00,0xdc63239c813e7ec1, - 0x3ebcde5c62e08200,0x47c5a7251b99fb79,0x3ebcde5c62e08200,0x47c5a7251b99fb79, - 0x6110cbbadbaa7100,0xbbca11600170abda,0x6110cbbadbaa7100,0xbbca11600170abda, - 0x53fead0d5ef3a00,0xbe84516b6e5481bb,0x53fead0d5ef3a00,0xbe84516b6e5481bb, - 0x5ac17fe4be259b00,0x33a8168dd74cf269,0x5ac17fe4be259b00,0x33a8168dd74cf269, - 0x873ec47dfa43b900,0x62db21981fa65ce5,0x873ec47dfa43b900,0x62db21981fa65ce5, - 0xad2b4fc964e28600,0xc14723a5088eea6c,0xad2b4fc964e28600,0xc14723a5088eea6c, - 0xdda5ceb66b137800,0x463e552df088e39b,0xdda5ceb66b137800,0x463e552df088e39b, - 0x5c349ef6aac26800,0x1a72d8b0ec842e46,0x5c349ef6aac26800,0x1a72d8b0ec842e46, - 0xca96e3bf75295c00,0x4a16633ff5a9dc80,0xca96e3bf75295c00,0x4a16633ff5a9dc80, - 0xc26ecc6cae02a00,0x3319d3f9f5df153f,0xc26ecc6cae02a00,0x3319d3f9f5df153f, - 0xf9d55e728ba72c00,0xc5e9624eb79b103c,0xf9d55e728ba72c00,0xc5e9624eb79b103c, - 0x42bdd12e6c93ff00,0xe31c708fcd325ea1,0x42bdd12e6c93ff00,0xe31c708fcd325ea1, - 0xb594ba9b2e0f2100,0x31103e1faa8ba584,0xb594ba9b2e0f2100,0x31103e1faa8ba584, - 0xfd6b3bad50c69600,0xc9aca5ca13767f1,0xfd6b3bad50c69600,0xc9aca5ca13767f1, - 0xe3a77034d7934400,0xade93e7a99dd0a4e,0xe3a77034d7934400,0xade93e7a99dd0a4e, - 0x48763709417f3e00,0x3d03427c340a4b75,0x48763709417f3e00,0x3d03427c340a4b75, - 0x2228c8c2e0ea0a00,0x868c6c66444eaea4,0x2228c8c2e0ea0a00,0x868c6c66444eaea4, - 0x9cfff4970b686300,0x23404b28b4d7dcbf,0x9cfff4970b686300,0x23404b28b4d7dcbf, - 0xdc65ef568a33b900,0xe75ed46db108823b,0xdc65ef568a33b900,0xe75ed46db108823b, - 0x3867e7b880df5f00,0x732cacf3cb94144b,0x3867e7b880df5f00,0x732cacf3cb94144b, - 0x963f7fd640e9a900,0x359cdc75e34a0aa3,0x963f7fd640e9a900,0x359cdc75e34a0aa3, - 0x31b58f0b3abe8400,0xdf5b61e5d4506aee,0x31b58f0b3abe8400,0xdf5b61e5d4506aee, - 0xea316fb45e85db00,0xa8732df61cc79942,0xea316fb45e85db00,0xa8732df61cc79942, - 0xb5b54949fcfc0000,0x747488883d3dc1c1,0xb5b54949fcfc0000,0x747488883d3dc1c1, - 0x43d2910142d3900,0xedd4c0f9fdc4d0e9,0x43d2910142d3900,0xedd4c0f9fdc4d0e9, - 0xb31ea508bb16ad00,0x76db60cd7ed368c5,0xb31ea508bb16ad00,0x76db60cd7ed368c5, - 0xf6822e5aacd87400,0x1460ccb84e3a96e2,0xf6822e5aacd87400,0x1460ccb84e3a96e2, - 0xa78ae9c4634e2d00,0xe8c5a68b2c01624f,0xa78ae9c4634e2d00,0xe8c5a68b2c01624f, - 0x1dabcf7964d2b600,0xfd4b2f99843256e0,0x1dabcf7964d2b600,0xfd4b2f99843256e0, - 0xa315e452f147b600,0x259362d477c13086,0xa315e452f147b600,0x259362d477c13086, - 0x81d27320a1f25300,0x491abbe8693a9bc8,0x81d27320a1f25300,0x491abbe8693a9bc8, - 0xe7268b4aad6cc100,0x21e04d8c6baa07c6,0xe7268b4aad6cc100,0x21e04d8c6baa07c6, - 0x5a4e44540e1a100,0x2786c66762c38322,0x5a4e44540e1a100,0x2786c66762c38322, - 0x5d98b6732eebc500,0xe32608cd90557bbe,0x5d98b6732eebc500,0xe32608cd90557bbe, - 0x91943732a3a60500,0xc4c16267f6f35055,0x91943732a3a60500,0xc4c16267f6f35055, - 0x3e9008a69836ae00,0x5cf26ac4fa54cc62,0x3e9008a69836ae00,0x5cf26ac4fa54cc62, - 0x1f94d9524dc68b00,0xe9622fa4bb307df6,0x1f94d9524dc68b00,0xe9622fa4bb307df6, - 0xedbb1640adfb5600,0x194fe2b4590fa2f4,0xedbb1640adfb5600,0x194fe2b4590fa2f4, - 0x1836745a426c2e00,0xfed092bca48ac8e6,0x1836745a426c2e00,0xfed092bca48ac8e6, - 0xb7110dab1cbaa600,0x5ef8e442f5534fe9,0xb7110dab1cbaa600,0x5ef8e442f5534fe9, - 0x6347c2e685a12400,0xc8ec694d2e0a8fab,0x6347c2e685a12400,0xc8ec694d2e0a8fab, - 0xf3d59fb94a6c2600,0x89afe5c330165c7a,0xf3d59fb94a6c2600,0x89afe5c330165c7a, - 0xa5053c9c3999a000,0x4dedd474d17148e8,0xa5053c9c3999a000,0x4dedd474d17148e8, - 0xef21f43ad51bce00,0xc50bde10ff31e42a,0xef21f43ad51bce00,0xc50bde10ff31e42a, - 0x6263626301000100,0x585958593b3a3b3a,0x6263626301000100,0x585958593b3a3b3a, - 0xf9e4c6db223f1d00,0x1f02203dc4d9fbe6,0xf9e4c6db223f1d00,0x1f02203dc4d9fbe6, - 0xfe067f877981f800,0x1ae29b639d651ce4,0xfe067f877981f800,0x1ae29b639d651ce4, - 0xfb35e22cd719ce00,0xee20f739c20cdb15,0xfb35e22cd719ce00,0xee20f739c20cdb15, - 0xd262da6ab808b000,0x95259d2dff4ff747,0xd262da6ab808b000,0x95259d2dff4ff747, - 0x53c031a2f1629300,0xac3fce5d0e9d6cff,0x53c031a2f1629300,0xac3fce5d0e9d6cff, - 0x5b7bfede85a52000,0x86a623035878fddd,0x5b7bfede85a52000,0x86a623035878fddd, - 0xf9d43518e1cc2d00,0x8fa2436e97ba5b76,0xf9d43518e1cc2d00,0x8fa2436e97ba5b76, - 0x4edc63f1bf2d9200,0x68fa45d7990bb426,0x4edc63f1bf2d9200,0x68fa45d7990bb426, - 0xc964973af35ead00,0x45e81bb67fd2218c,0xc964973af35ead00,0x45e81bb67fd2218c, - 0x6f3d21731c4e5200,0x2f7d61335c0e1240,0x6f3d21731c4e5200,0x2f7d61335c0e1240, - 0x101df7faeae70d00,0x68658f82929f7578,0x101df7faeae70d00,0x68658f82929f7578, - 0x24aaa6280c828e00,0xa9272ba5810f038d,0x24aaa6280c828e00,0xa9272ba5810f038d, - 0xb34652a714e1f500,0x8d786c992adfcb3e,0xb34652a714e1f500,0x8d786c992adfcb3e, - 0x72bb8f4634fdc900,0x3af3c70e7cb58148,0x72bb8f4634fdc900,0x3af3c70e7cb58148, - 0xdff4361dc2e92b00,0xdbf03219c6ed2f04,0xdff4361dc2e92b00,0xdbf03219c6ed2f04, - 0x17e81ee1f609ff00,0x4db244bbac53a55a,0x17e81ee1f609ff00,0x4db244bbac53a55a, - 0xe3492e8467cdaa00,0xc66c0ba142e88f25,0xe3492e8467cdaa00,0xc66c0ba142e88f25, - 0xb062bd6fdf0dd200,0x13c11ecc7cae71a3,0xb062bd6fdf0dd200,0x13c11ecc7cae71a3, - 0xdbb1e68c573d6a00,0x6c06513be08addb7,0xdbb1e68c573d6a00,0x6c06513be08addb7, - 0x754797a5d0e23200,0x586aba88fdcf1f2d,0x754797a5d0e23200,0x586aba88fdcf1f2d, - 0xd5273cce1be9f200,0x83716a984dbfa456,0xd5273cce1be9f200,0x83716a984dbfa456, - 0xa522e767c245800,0x277f035b5109752d,0xa522e767c245800,0x277f035b5109752d, - 0xf302c938cb3af100,0xe415de2fdc2de617,0xf302c938cb3af100,0xe415de2fdc2de617, - 0x7a61d4cfb5ae1b00,0x869d28334952e7fc,0x7a61d4cfb5ae1b00,0x869d28334952e7fc, - 0x9b98797ae1e20300,0x5655b4b72c2fcecd,0x9b98797ae1e20300,0x5655b4b72c2fcecd, - 0x6601462147206700,0x6a0d4a2d4b2c6b0c,0x6601462147206700,0x6a0d4a2d4b2c6b0c, - 0x2e3668705e461800,0x140c524a647c223a,0x2e3668705e461800,0x140c524a647c223a, - 0x3223213002131100,0xeafbf9e8dacbc9d8,0x3223213002131100,0xeafbf9e8dacbc9d8, - 0x617a233859421b00,0x1c075e45243f667d,0x617a233859421b00,0x1c075e45243f667d, - 0x582df085dda87500,0xd1a4790c5421fc89,0x582df085dda87500,0xd1a4790c5421fc89, - 0xce8c3c7eb0f24200,0xf5b707458bc9793b,0xce8c3c7eb0f24200,0xf5b707458bc9793b, - 0x79743d3049440d00,0x808dc4c9b0bdf4f9,0x79743d3049440d00,0x808dc4c9b0bdf4f9, - 0x787edcdaa2a40600,0x5452f0f68e882a2c,0x787edcdaa2a40600,0x5452f0f68e882a2c, - 0xe427e427c300c300,0x93509350b477b477,0xe427e427c300c300,0x93509350b477b477, - 0xe1ab2d6786cc4a00,0xb9f3753fde941258,0xe1ab2d6786cc4a00,0xb9f3753fde941258, - 0x5b63d3ebb0883800,0xad95251d467ecef6,0x5b63d3ebb0883800,0xad95251d467ecef6, - 0xa6aebfb711190800,0x9b93828a2c24353d,0xa6aebfb711190800,0x9b93828a2c24353d, - 0xa84c28cc6480e400,0x42a6c2268e6a0eea,0xa84c28cc6480e400,0x42a6c2268e6a0eea, - 0xfd2827f20fdad500,0xa4717eab56838c59,0xfd2827f20fdad500,0xa4717eab56838c59, - 0xcb68f7549f3ca300,0x5dfe61c209aa3596,0xcb68f7549f3ca300,0x5dfe61c209aa3596, - 0x91fbb8d243296a00,0x9cf6b5df4e24670d,0x91fbb8d243296a00,0x9cf6b5df4e24670d, - 0x89da1546cf9c5300,0x7526e9ba3360affc,0x89da1546cf9c5300,0x7526e9ba3360affc, - 0xe6b22d799fcb5400,0xaafe6135d387184c,0xe6b22d799fcb5400,0xaafe6135d387184c, - 0xd5587dfd28a5800,0xf6ae7c242971a3fb,0xd5587dfd28a5800,0xf6ae7c242971a3fb, - }; - - - alignas(32) const uint64_t i_beta_mul_64_bm4r_ext_8[2 * 128 * 4 * 2] = { - 0xb8b96a6bd3d20100,0x3e3feced55548786,0xb8b96a6bd3d20100,0x3e3feced55548786, - 0x80a06e4eceee2000,0x4d6da3830323edcd,0x80a06e4eceee2000,0x4d6da3830323edcd, - 0x8484a3a327270000,0xc1c1e6e662624545,0x8484a3a327270000,0xc1c1e6e662624545, - 0x34bf20ab9f148b00,0xf279e66d59d24dc6,0x34bf20ab9f148b00,0xf279e66d59d24dc6, - 0xe0e0cfcf2f2f0000,0x9595baba5a5a7575,0xe0e0cfcf2f2f0000,0x9595baba5a5a7575, - 0xbaf4420cb6f84e00,0x6f2197d9632d9bd5,0xbaf4420cb6f84e00,0x6f2197d9632d9bd5, - 0x9f9f5b5bc4c40000,0x606c2c25d5d9999,0x9f9f5b5bc4c40000,0x606c2c25d5d9999, - 0xc7a2e48146236500,0x82e7a1c403662045,0xc7a2e48146236500,0x82e7a1c403662045, - 0x606434345450000,0x2e2e6b6b6d6d2828,0x606434345450000,0x2e2e6b6b6d6d2828, - 0x5560182d784d3500,0xcbfe86b3e6d3ab9e,0x5560182d784d3500,0xcbfe86b3e6d3ab9e, - 0x48482e2e66660000,0x6767010149492f2f,0x48482e2e66660000,0x6767010149492f2f, - 0x286fd592bafd4700,0xbff842052d6ad097,0x286fd592bafd4700,0xbff842052d6ad097, - 0xc2c23434f6f60000,0x3d3dcbcb0909ffff,0xc2c23434f6f60000,0x3d3dcbcb0909ffff, - 0xc822d03af218ea00,0x4ca654be769c6e84,0xc822d03af218ea00,0x4ca654be769c6e84, - 0x3939d5d5ecec0000,0x66668a8ab3b35f5f,0x3939d5d5ecec0000,0x66668a8ab3b35f5f, - 0x1b858a140f919e00,0x6ff1fe607be5ea74,0x1b858a140f919e00,0x6ff1fe607be5ea74, - 0x7809f687ff8e7100,0xccbd42334b3ac5b4,0x7809f687ff8e7100,0xccbd42334b3ac5b4, - 0xa38f96ba19352c00,0x79554c60c3eff6da,0xa38f96ba19352c00,0x79554c60c3eff6da, - 0x434b2f27646c0800,0xcfc7a3abe8e0848c,0x434b2f27646c0800,0xcfc7a3abe8e0848c, - 0x5d0359075a045e00,0x1648124c114f154b,0x5d0359075a045e00,0x1648124c114f154b, - 0xd1df5e50818f0e00,0x4a44c5cb1a14959b,0xd1df5e50818f0e00,0x4a44c5cb1a14959b, - 0xacdfcab915667300,0x344752218dfeeb98,0xacdfcab915667300,0x344752218dfeeb98, - 0xaf3a15802fba9500,0x1a8fa0359a0f20b5,0xaf3a15802fba9500,0x1a8fa0359a0f20b5, - 0x9531d074e145a400,0x54f011b5208465c1,0x9531d074e145a400,0x54f011b5208465c1, - 0xbe1813b50bada600,0xa50308ae10b6bd1b,0xbe1813b50bada600,0xa50308ae10b6bd1b, - 0x5fd3d9550a868c00,0xbe3238b4eb676de1,0x5fd3d9550a868c00,0xbe3238b4eb676de1, - 0xacd1f58824597d00,0x304d6914b8c5e19c,0xacd1f58824597d00,0x304d6914b8c5e19c, - 0xfd6903976afe9400,0x72e68c18e5711b8f,0xfd6903976afe9400,0x72e68c18e5711b8f, - 0x8e6437dd53b9ea00,0xfe5b65cd2386b81,0x8e6437dd53b9ea00,0xfe5b65cd2386b81, - 0xe52cb970955cc900,0x1fd6438a6fa633fa,0xe52cb970955cc900,0x1fd6438a6fa633fa, - 0x17ad82382f95ba00,0x6cd6f94354eec17b,0x17ad82382f95ba00,0x6cd6f94354eec17b, - 0x30b3cb4878fb8300,0x3ebdc54676f58d0e,0x30b3cb4878fb8300,0x3ebdc54676f58d0e, - 0xc16d0fa362ceac00,0x16bad874b5197bd7,0xc16d0fa362ceac00,0x16bad874b5197bd7, - 0xbfab998d32261400,0xf1b293d8296a4b0,0xbfab998d32261400,0xf1b293d8296a4b0, - 0xc2f02113d1e33200,0xdbe9380ac8fa2b19,0xc2f02113d1e33200,0xdbe9380ac8fa2b19, - 0x5d04fba2ffa65900,0x154cb3eab7ee1148,0x5d04fba2ffa65900,0x154cb3eab7ee1148, - 0xdff8c5e23d1a2700,0x3c1b2601def9c4e3,0xdff8c5e23d1a2700,0x3c1b2601def9c4e3, - 0xbda7e2f8455f1a00,0x455f1a00bda7e2f8,0xbda7e2f8455f1a00,0x455f1a00bda7e2f8, - 0xe632ca1ef82cd400,0x29fd05d137e31bcf,0xe632ca1ef82cd400,0x29fd05d137e31bcf, - 0xe916b04fa659ff00,0x7c8325da33cc6a95,0xe916b04fa659ff00,0x7c8325da33cc6a95, - 0xf4a6ce9c683a5200,0x2270184abeec84d6,0xf4a6ce9c683a5200,0x2270184abeec84d6, - 0xc0b896ee2e567800,0x572f0179b9c1ef97,0xc0b896ee2e567800,0x572f0179b9c1ef97, - 0x2bb962f2d94b900,0x5ce5c87173cae75e,0x2bb962f2d94b900,0x5ce5c87173cae75e, - 0xee7055cb25bb9e00,0x5ec0e57b950b2eb0,0xee7055cb25bb9e00,0x5ec0e57b950b2eb0, - 0xee0a64846a8ee00,0x638dcb252bc5836d,0xee0a64846a8ee00,0x638dcb252bc5836d, - 0x2a483c5e74166200,0x593b4f2d07651173,0x2a483c5e74166200,0x593b4f2d07651173, - 0x49d02eb7fe679900,0x69f00e97de47b920,0x49d02eb7fe679900,0x69f00e97de47b920, - 0x9d978c861b110a00,0x8f859e9409031812,0x9d978c861b110a00,0x8f859e9409031812, - 0xe0d8073fdfe73800,0x6f5788b05068b78f,0xe0d8073fdfe73800,0x6f5788b05068b78f, - 0xe3219052b173c200,0xcd0fbe7c9f5dec2e,0xe3219052b173c200,0xcd0fbe7c9f5dec2e, - 0xf6b5c3837536400,0x593d0a6e61053256,0xf6b5c3837536400,0x593d0a6e61053256, - 0xd34abc25f66f9900,0x6bf2049d4ed721b8,0xd34abc25f66f9900,0x6bf2049d4ed721b8, - 0x8b55ad73f826de00,0x75ab538d06d820fe,0x8b55ad73f826de00,0x75ab538d06d820fe, - 0x4766d9f8bf9e2100,0xe9c8775611308fae,0x4766d9f8bf9e2100,0xe9c8775611308fae, - 0x3cfce2221edec000,0xa66678b884445a9a,0x3cfce2221edec000,0xa66678b884445a9a, - 0xfc51913cc06dad00,0x4de0208d71dc1cb1,0xfc51913cc06dad00,0x4de0208d71dc1cb1, - 0x876524c641a3e200,0xdf3d7c9e19fbba58,0x876524c641a3e200,0xdf3d7c9e19fbba58, - 0x4a8a985812d2c000,0x13d3c1014b8b9959,0x4a8a985812d2c000,0x13d3c1014b8b9959, - 0x5288449ecc16da00,0x23f935efbd67ab71,0x5288449ecc16da00,0x23f935efbd67ab71, - 0x4237126725507500,0x9eebcebbf98ca9dc,0x4237126725507500,0x9eebcebbf98ca9dc, - 0x3fe6954c73aad900,0x4f96e53c03daa970,0x3fe6954c73aad900,0x4f96e53c03daa970, - 0x47cfc64e09818800,0x24aca52d6ae2eb63,0x47cfc64e09818800,0x24aca52d6ae2eb63, - 0xb98b4476cffd3200,0xb587487ac3f13e0c,0xb98b4476cffd3200,0xb587487ac3f13e0c, - 0xe7b90e5eb9e7500,0xccb95227295cb7c2,0xe7b90e5eb9e7500,0xccb95227295cb7c2, - 0x3eff71b08e4fc100,0xe524aa6b55941adb,0x3eff71b08e4fc100,0xe524aa6b55941adb, - 0x476184a2e5c32600,0x99bf5a7c3b1df8de,0x476184a2e5c32600,0x99bf5a7c3b1df8de, - 0x63f89a0162f99b00,0x7ce7851e7de6841f,0x63f89a0162f99b00,0x7ce7851e7de6841f, - 0x4eba1de9a753f400,0x29dd7a8ec0349367,0x4eba1de9a753f400,0x29dd7a8ec0349367, - 0xe25fa914f64bbd00,0xec51a71af845b30e,0xe25fa914f64bbd00,0xec51a71af845b30e, - 0x52f72386d471a500,0x52f72386d471a500,0x52f72386d471a500,0x52f72386d471a500, - 0xf9c4023fc6fb3d00,0xa994526f96ab6d50,0xf9c4023fc6fb3d00,0xa994526f96ab6d50, - 0x925b25ec7eb7c900,0xea235d9406cfb178,0x925b25ec7eb7c900,0xea235d9406cfb178, - 0xbf963e17a8812900,0x755cf4dd624be3ca,0xbf963e17a8812900,0x755cf4dd624be3ca, - 0xe1b1baea0b5b5000,0x45151e4eaffff4a4,0xe1b1baea0b5b5000,0x45151e4eaffff4a4, - 0xaee791d8763f4900,0xa2eb9dd47a33450c,0xaee791d8763f4900,0xa2eb9dd47a33450c, - 0x17a511a3b406b200,0x17a511a3b406b200,0x17a511a3b406b200,0x17a511a3b406b200, - 0x2e6a9edaf4b04400,0xd59165210f4bbffb,0x2e6a9edaf4b04400,0xd59165210f4bbffb, - 0x87972e3eb9a91000,0x3a2a93830414adbd,0x87972e3eb9a91000,0x3a2a93830414adbd, - 0xe1bea0ff1e415f00,0xe4bba5fa1b445a05,0xe1bea0ff1e415f00,0xe4bba5fa1b445a05, - 0x689a7d8fe715f200,0x11e304f69e6c8b79,0x689a7d8fe715f200,0x11e304f69e6c8b79, - 0x4e20e48ac4aa6e00,0xc2ac68064826e28c,0x4e20e48ac4aa6e00,0xc2ac68064826e28c, - 0x91a40633a2973500,0xecd97b4edfea487d,0x91a40633a2973500,0xecd97b4edfea487d, - 0xe8e76b648c830f00,0xeee16d628a850906,0xe8e76b648c830f00,0xeee16d628a850906, - 0x462894fabcd26e00,0x8ce25e307618a4ca,0x462894fabcd26e00,0x8ce25e307618a4ca, - 0x5eddd0530d8e8300,0x82010c8fd1525fdc,0x5eddd0530d8e8300,0x82010c8fd1525fdc, - 0xbbba5e5fe4e50100,0xb0b15554efee0a0b,0xbbba5e5fe4e50100,0xb0b15554efee0a0b, - 0xff4363df209cbc00,0xbb7972bd46848f4,0xff4363df209cbc00,0xbb7972bd46848f4, - 0xe76235b057d28500,0x46c39411f67324a1,0xe76235b057d28500,0x46c39411f67324a1, - 0xfcd589a9557c200,0x589a0fcdc2009557,0xfcd589a9557c200,0x589a0fcdc2009557, - 0xda40cb518b119a00,0x4fd55ec41e840f95,0xda40cb518b119a00,0x4fd55ec41e840f95, - 0xeb7d17816afc9600,0xd84e24b259cfa533,0xeb7d17816afc9600,0xd84e24b259cfa533, - 0x86945e4ccad81200,0x1705cfdd5b498391,0x86945e4ccad81200,0x1705cfdd5b498391, - 0x496093baf3da2900,0x674ebd94ddf4072e,0x496093baf3da2900,0x674ebd94ddf4072e, - 0x43f8259edd66bb00,0x76cd10abe8538e35,0x43f8259edd66bb00,0x76cd10abe8538e35, - 0x82d6194dcf9b5400,0x5c08c79311458ade,0x82d6194dcf9b5400,0x5c08c79311458ade, - 0x2969195970304000,0xedaddd9db4f484c4,0x2969195970304000,0xedaddd9db4f484c4, - 0x886258b23ad0ea00,0x1ebd13bb3596389,0x886258b23ad0ea00,0x1ebd13bb3596389, - 0x2d15b888a59d300,0x13c04a999b48c211,0x2d15b888a59d300,0x13c04a999b48c211, - 0x28759fc2eab75d00,0xda876d301845aff2,0x28759fc2eab75d00,0xda876d301845aff2, - 0x88a8301098b82000,0x2c0c94b43c1c84a4,0x88a8301098b82000,0x2c0c94b43c1c84a4, - 0xa029008929a08900,0x73fad35afa735ad3,0xa029008929a08900,0x73fad35afa735ad3, - 0x6230ebb9db895200,0xa5f72c7e1c4e95c7,0x6230ebb9db895200,0xa5f72c7e1c4e95c7, - 0x4a76407c360a3c00,0xba86b08cc6faccf0,0x4a76407c360a3c00,0xba86b08cc6faccf0, - 0xf9d2ddf60f242b00,0xfad1def50c272803,0xf9d2ddf60f242b00,0xfad1def50c272803, - 0x4d4fd2d29f9d000,0xcdcf52521f1d808,0x4d4fd2d29f9d000,0xcdcf52521f1d808, - 0x82777c890bfef500,0x13e6ed189a6f6491,0x82777c890bfef500,0x13e6ed189a6f6491, - 0x135be8a0b3fb4800,0x99d1622a3971c28a,0x135be8a0b3fb4800,0x99d1622a3971c28a, - 0x35268a99acbf1300,0x5d4ee2f1c4d77b68,0x35268a99acbf1300,0x5d4ee2f1c4d77b68, - 0x881b74e76ffc9300,0x8f1c73e068fb9407,0x881b74e76ffc9300,0x8f1c73e068fb9407, - 0xb6acecf6405a1a00,0xf4eeaeb402185842,0xb6acecf6405a1a00,0xf4eeaeb402185842, - 0x1ad0559f854fca00,0x864cc90319d3569c,0x1ad0559f854fca00,0x864cc90319d3569c, - 0x632dc48ae9a74e00,0x9bd53c72115fb6f8,0x632dc48ae9a74e00,0x9bd53c72115fb6f8, - 0x6d0e4a2944276300,0x563571127f1c583b,0x6d0e4a2944276300,0x563571127f1c583b, - 0x5a2e24540e7a700,0x2b8ccc6b6ec9892e,0x5a2e24540e7a700,0x2b8ccc6b6ec9892e, - 0x9749fe2eb967d00,0x3e43a8d5dca14a37,0x9749fe2eb967d00,0x3e43a8d5dca14a37, - 0x42f53780c275b700,0x18af6dda982fed5a,0x42f53780c275b700,0x18af6dda982fed5a, - 0xef2dea28c705c200,0xa86aad6f80428547,0xef2dea28c705c200,0xa86aad6f80428547, - 0x884007cf478fc800,0x2ae2a56de52d6aa2,0x884007cf478fc800,0x2ae2a56de52d6aa2, - 0x959915198c800c00,0xbbb73b37a2ae222e,0x959915198c800c00,0xbbb73b37a2ae222e, - 0xf0209343b363d000,0xada69b949992afa,0xf0209343b363d000,0xada69b949992afa, - 0x5e9e90500ecec00,0xe90505e9ec0000ec,0x5e9e90500ecec00,0xe90505e9ec0000ec, - 0x9da5350d90a83800,0x774fdfe77a42d2ea,0x9da5350d90a83800,0x774fdfe77a42d2ea, - 0xf45f8328dc77ab00,0x2c875bf004af73d8,0xf45f8328dc77ab00,0x2c875bf004af73d8, - 0x40dd5ac7871a9d00,0x920f881555c84fd2,0x40dd5ac7871a9d00,0x920f881555c84fd2, - 0x35e7855762b0d200,0xcc1e7cae9b492bf9,0x35e7855762b0d200,0xcc1e7cae9b492bf9, - 0xd41beb24f03fcf00,0xae61915e8a45b57a,0xd41beb24f03fcf00,0xae61915e8a45b57a, - 0x424ce5eba9a70e00,0xb3bd141a5856fff1,0x424ce5eba9a70e00,0xb3bd141a5856fff1, - 0xa24630d47692e400,0xf612648022c6b054,0xa24630d47692e400,0xf612648022c6b054, - 0x24d033c7e317f400,0x20d437c3e713f004,0x24d033c7e317f400,0x20d437c3e713f004, - 0x39dad83b02e1e300,0x618280635ab9bb58,0x39dad83b02e1e300,0x618280635ab9bb58, - 0x79b4e12c5598cd00,0x74b9ec215895c00d,0x79b4e12c5598cd00,0x74b9ec215895c00d, - 0x35ddeb0336dee800,0xc62e18f0c52d1bf3,0x35ddeb0336dee800,0xc62e18f0c52d1bf3, - 0x6da45a93fe37c900,0x76bf4188e52cd21b,0x6da45a93fe37c900,0x76bf4188e52cd21b, - 0x7f0438433c477b00,0xa714d3649320e75,0x7f0438433c477b00,0xa714d3649320e75, - 0x6c85ee076b82e900,0x29c0ab422ec7ac45,0x6c85ee076b82e900,0x29c0ab422ec7ac45, - 0x977da74dda30ea00,0x3fd50fe5729842a8,0x977da74dda30ea00,0x3fd50fe5729842a8, - 0x7bcb08b8c373b000,0x6ddd1eaed565a616,0x7bcb08b8c373b000,0x6ddd1eaed565a616, - 0x8480cfcb4f4b0400,0xc4c08f8b0f0b4440,0x8480cfcb4f4b0400,0xc4c08f8b0f0b4440, - 0x3cea5a8cb066d600,0xe73181576bbd0ddb,0x3cea5a8cb066d600,0xe73181576bbd0ddb, - 0x23c5f61033d5e600,0xaf497a9cbf596a8c,0x23c5f61033d5e600,0xaf497a9cbf596a8c, - 0xd10ed40bda05df00,0xc21dc718c916cc13,0xd10ed40bda05df00,0xc21dc718c916cc13, - 0x3922cad1e8f31b00,0x2239d1caf3e8001b,0x3922cad1e8f31b00,0x2239d1caf3e8001b, - 0x71a2835322f1d00,0xa3be8c91968bb9a4,0x71a2835322f1d00,0xa3be8c91968bb9a4, - 0x7907403e47397e00,0xd0aee997ee90d7a9,0x7907403e47397e00,0xd0aee997ee90d7a9, - 0x6ba2ae670cc5c900,0x34fdf138539a965f,0x6ba2ae670cc5c900,0x34fdf138539a965f, - 0x34a18e1b2fba9500,0x42d7f86d59cce376,0x34a18e1b2fba9500,0x42d7f86d59cce376, - 0x36b6ba3a0c8c8000,0x47c7cb4b7dfdf171,0x36b6ba3a0c8c8000,0x47c7cb4b7dfdf171, - 0xa4d61b69cdbf7200,0x7d0fc2b01466abd9,0xa4d61b69cdbf7200,0x7d0fc2b01466abd9, - 0x83b92d1794ae3a00,0x9ea4300a89b3271d,0x83b92d1794ae3a00,0x9ea4300a89b3271d, - 0x6ecc8d2f41e3a200,0xa20041e38d2f6ecc,0x6ecc8d2f41e3a200,0xa20041e38d2f6ecc, - 0xf672fe7a8c088400,0x5ade52d620a428ac,0xf672fe7a8c088400,0x5ade52d620a428ac, - 0xc7785fe02798bf00,0x229dba05c27d5ae5,0xc7785fe02798bf00,0x229dba05c27d5ae5, - 0xbccbadda66117700,0x33442255e99ef88f,0xbccbadda66117700,0x33442255e99ef88f, - 0xec23d817fb34cf00,0xb9768d42ae619a55,0xec23d817fb34cf00,0xb9768d42ae619a55, - 0xf0095aa353aaf900,0x20d98a73837a29d0,0xf0095aa353aaf900,0x20d98a73837a29d0, - 0xb25329c87a9be100,0x7190ea0bb95822c3,0xb25329c87a9be100,0x7190ea0bb95822c3, - 0x5a963ff3a965cc00,0x7cb62aef438915d,0x5a963ff3a965cc00,0x7cb62aef438915d, - 0xe6d57d4ea89b3300,0x15268ebd5b68c0f3,0xe6d57d4ea89b3300,0x15268ebd5b68c0f3, - 0xe4c02404e0c4200,0x67256b2927652b69,0xe4c02404e0c4200,0x67256b2927652b69, - 0x9ef81177e98f6600,0xa2c42d4bd5b35a3c,0x9ef81177e98f6600,0xa2c42d4bd5b35a3c, - 0x21628fccedae4300,0x682bc685a4e70a49,0x21628fccedae4300,0x682bc685a4e70a49, - 0x97a399ad3a0e3400,0xdaeed4e07743794d,0x97a399ad3a0e3400,0xdaeed4e07743794d, - 0x3147f385b4c27600,0xd4a21660512793e5,0x3147f385b4c27600,0xd4a21660512793e5, - 0xf86d45d028bd9500,0x93062ebb43d6fe6b,0xf86d45d028bd9500,0x93062ebb43d6fe6b, - 0xa8f392c9613a5b00,0xb8e382d9712a4b10,0xa8f392c9613a5b00,0xb8e382d9712a4b10, - 0x7cf854d0ac288400,0xb135991d61e549cd,0x7cf854d0ac288400,0xb135991d61e549cd, - 0x95b8ad8015382d00,0xfed3c6eb7e53466b,0x95b8ad8015382d00,0xfed3c6eb7e53466b, - 0xac9f88bb17243300,0xbc8f98ab07342310,0xac9f88bb17243300,0xbc8f98ab07342310, - 0xe30920ca29c3ea00,0xec062fc526cce50f,0xe30920ca29c3ea00,0xec062fc526cce50f, - 0xf3d1f5d724062200,0x33113517e4c6e2c0,0xf3d1f5d724062200,0x33113517e4c6e2c0, - 0xc5ab523cf9976e00,0x9af40d63a6c8315f,0xc5ab523cf9976e00,0x9af40d63a6c8315f, - 0x3c5c84e4d8b86000,0x3e5e86e6daba6202,0x3c5c84e4d8b86000,0x3e5e86e6daba6202, - 0xe0207cbc5c9cc000,0xe92975b55595c909,0xe0207cbc5c9cc000,0xe92975b55595c909, - 0xc3a5355390f66600,0xf89e0e68abcd5d3b,0xc3a5355390f66600,0xf89e0e68abcd5d3b, - 0x92ab5168fac33900,0x3b02f8c1536a90a9,0x92ab5168fac33900,0x3b02f8c1536a90a9, - 0xb7014cfa4dfbb600,0x15a3ee58ef5914a2,0xb7014cfa4dfbb600,0x15a3ee58ef5914a2, - 0xf268ab31c3599a00,0xab31f2689a00c359,0xf268ab31c3599a00,0xab31f2689a00c359, - 0xe17f76e809979e00,0xb72920be5fc1c856,0xe17f76e809979e00,0xb72920be5fc1c856, - 0x3f76f9b08fc64900,0xfdb43b724d048bc2,0x3f76f9b08fc64900,0xfdb43b724d048bc2, - 0x31289c85b4ad1900,0xa8b1051c2d348099,0x31289c85b4ad1900,0xa8b1051c2d348099, - 0xa75e3bc2659cf900,0x6e97f20bac5530c9,0xa75e3bc2659cf900,0x6e97f20bac5530c9, - 0x222c414f6d630e00,0x6b650806242a4749,0x222c414f6d630e00,0x6b650806242a4749, - 0x52deb23e6ce08c00,0x800c60ecbe325ed2,0x52deb23e6ce08c00,0x800c60ecbe325ed2, - 0x414cfcf1b0bd0d00,0xeae7575a1b16a6ab,0x414cfcf1b0bd0d00,0xeae7575a1b16a6ab, - 0x8bb589b73c023e00,0x19271b25ae90ac92,0x8bb589b73c023e00,0x19271b25ae90ac92, - 0x764a9cacdae6300,0x566abc8cfac6102,0x764a9cacdae6300,0x566abc8cfac6102, - 0x81bdab97162a3c00,0x201c0a36b78b9da1,0x81bdab97162a3c00,0x201c0a36b78b9da1, - 0x8a3d992ea413b700,0x6add79ce44f357e0,0x8a3d992ea413b700,0x6add79ce44f357e0, - 0xbab43c3288860e00,0xfaf47c72c8c64e40,0xbab43c3288860e00,0xfaf47c72c8c64e40, - 0x33917edcef4da200,0x1ebc53f1c2608f2d,0x33917edcef4da200,0x1ebc53f1c2608f2d, - 0x29efdc1a33f5c600,0x4482b1775e98ab6d,0x29efdc1a33f5c600,0x4482b1775e98ab6d, - 0xe17e0e9170ef9f00,0x3da2d24dac3343dc,0xe17e0e9170ef9f00,0x3da2d24dac3343dc, - 0xa7bbffe344581c00,0xd2ce8a96312d6975,0xa7bbffe344581c00,0xd2ce8a96312d6975, - 0x1ca004b8a418bc00,0xbf03a71b07bb1fa3,0x1ca004b8a418bc00,0xbf03a71b07bb1fa3, - 0x7e66948cf2ea1800,0x948c7e661800f2ea,0x7e66948cf2ea1800,0x948c7e661800f2ea, - 0x224ca2ccee806e00,0x355bb5dbf9977917,0x224ca2ccee806e00,0x355bb5dbf9977917, - 0x4c52405e120c1e00,0xb1afbda3eff1e3fd,0x4c52405e120c1e00,0xb1afbda3eff1e3fd, - 0x80ec563abad66c00,0xb8d46e0282ee5438,0x80ec563abad66c00,0xb8d46e0282ee5438, - 0xeeb3d588663b5d00,0x64395f02ecb1d78a,0xeeb3d588663b5d00,0x64395f02ecb1d78a, - 0x53dfb73b68e48c00,0x64e8800c5fd3bb37,0x53dfb73b68e48c00,0x64e8800c5fd3bb37, - 0xfc5059f509a5ac00,0x3a969f33cf636ac6,0xfc5059f509a5ac00,0x3a969f33cf636ac6, - 0xcbd02932f9e21b00,0x51ee7fc372cd5ce,0xcbd02932f9e21b00,0x51ee7fc372cd5ce, - 0x5ba640bde61bfd00,0x9a67817c27da3cc1,0x5ba640bde61bfd00,0x9a67817c27da3cc1, - 0x565d8d86d0db0b00,0x565d8d86d0db0b00,0x565d8d86d0db0b00,0x565d8d86d0db0b00, - 0x8696afbf39291000,0x4f5f6676f0e0d9c9,0x8696afbf39291000,0x4f5f6676f0e0d9c9, - 0x916fc33dac52fe00,0xe51bb749d8268a74,0x916fc33dac52fe00,0xe51bb749d8268a74, - 0x92d47a3caee84600,0xda9c3274e6a00e48,0x92d47a3caee84600,0xda9c3274e6a00e48, - 0x26e9549bbd72cf00,0x1ed16ca3854af738,0x26e9549bbd72cf00,0x1ed16ca3854af738, - 0x32cb27deec15f900,0xaa53bf46748d6198,0x32cb27deec15f900,0xaa53bf46748d6198, - 0xcdb3e39d502e7e00,0xe896c6b8750b5b25,0xcdb3e39d502e7e00,0xe896c6b8750b5b25, - 0xc999bded24745000,0x21715505cc9cb8e8,0xc999bded24745000,0x21715505cc9cb8e8, - 0x280c6b4f67432400,0x795d3a1e36127551,0x280c6b4f67432400,0x795d3a1e36127551, - 0xd0ca859f4f551a00,0xf155a40908ac5df,0xd0ca859f4f551a00,0xf155a40908ac5df, - 0x5167d6e0b1873600,0x94a213257442f3c5,0x5167d6e0b1873600,0x94a213257442f3c5, - 0x43defd6d2eb3900,0xe0d90b32360fdde4,0x43defd6d2eb3900,0xe0d90b32360fdde4, - 0x417f98a6e7d93e00,0x13fd8e6a7997e40,0x417f98a6e7d93e00,0x13fd8e6a7997e40, - 0x34e96eb3875add00,0x20fd7aa7934ec914,0x34e96eb3875add00,0x20fd7aa7934ec914, - 0xaaa2464ee4ec0800,0x535bbfb71d15f1f9,0xaaa2464ee4ec0800,0x535bbfb71d15f1f9, - 0xf2a07725d7855200,0x7022f5a75507d082,0xf2a07725d7855200,0x7022f5a75507d082, - 0x89b34b71f8c23a00,0x7e44bc860f35cdf7,0x89b34b71f8c23a00,0x7e44bc860f35cdf7, - 0x47b6e11057a6f100,0xe71641b0f70651a0,0x47b6e11057a6f100,0xe71641b0f70651a0, - 0x1bc7fe2239e5dc00,0xb76b528e954970ac,0x1bc7fe2239e5dc00,0xb76b528e954970ac, - 0x5488db07538fdc00,0xe23e6db1e5396ab6,0x5488db07538fdc00,0xe23e6db1e5396ab6, - 0xf22c588674aade00,0xd80672ac5e80f42a,0xf22c588674aade00,0xd80672ac5e80f42a, - 0x6e1ccdbfd1a37200,0x8cfe2f5d334190e2,0x6e1ccdbfd1a37200,0x8cfe2f5d334190e2, - 0xde2ac430ee1af400,0x2f618ec32c628dc,0xde2ac430ee1af400,0x2f618ec32c628dc, - 0x3a0b8bba80b13100,0xf4c545744e7fffce,0x3a0b8bba80b13100,0xf4c545744e7fffce, - 0x2cdb1cebc730f700,0x9265a255798e49be,0x2cdb1cebc730f700,0x9265a255798e49be, - 0x56141d5f094b4200,0xf6b4bdffa9ebe2a0,0x56141d5f094b4200,0xf6b4bdffa9ebe2a0, - 0xb7ac455ee9f21b00,0xe7fc150eb9a24b50,0xb7ac455ee9f21b00,0xe7fc150eb9a24b50, - 0x968ad8c4524e1c00,0x21e4c50c6da8894,0x968ad8c4524e1c00,0x21e4c50c6da8894, - 0x1ddacc0b16d1c700,0x2cebfd3a27e0f631,0x1ddacc0b16d1c700,0x2cebfd3a27e0f631, - 0x28539be0c8b37b00,0x99e22a517902cab1,0x28539be0c8b37b00,0x99e22a517902cab1, - 0xc38281c003424100,0x91d0d39251101352,0xc38281c003424100,0x91d0d39251101352, - 0x8681beb93f380700,0xbeb9868107003f38,0x8681beb93f380700,0xbeb9868107003f38, - 0xefd77b43ac943800,0x122a86be5169c5fd,0xefd77b43ac943800,0x122a86be5169c5fd, - 0x9ec67e26b8e05800,0x366ed68e1048f0a8,0x9ec67e26b8e05800,0x366ed68e1048f0a8, - 0x875fed35b26ad800,0x71a91bc3449c2ef6,0x875fed35b26ad800,0x71a91bc3449c2ef6, - 0x2bc23ad3f811e900,0x78916980ab42ba53,0x2bc23ad3f811e900,0x78916980ab42ba53, - 0x2211417250633300,0xf0c393a082b1e1d2,0x2211417250633300,0xf0c393a082b1e1d2, - 0x6966303f56590f00,0xefe0b6b9d0df8986,0x6966303f56590f00,0xefe0b6b9d0df8986, - 0x1d93850b16988e00,0x38d9b150886901e,0x1d93850b16988e00,0x38d9b150886901e, - 0x6b48b497fcdf2300,0x81a25e7d1635c9ea,0x6b48b497fcdf2300,0x81a25e7d1635c9ea, - 0x40094a03430a4900,0xde97d49ddd94d79e,0x40094a03430a4900,0xde97d49ddd94d79e, - 0x74019aef9bee7500,0x4b3ea5d0a4d14a3f,0x74019aef9bee7500,0x4b3ea5d0a4d14a3f, - 0x36691c43752a5f00,0x2f70055a6c334619,0x36691c43752a5f00,0x2f70055a6c334619, - 0xbba91507bcae1200,0xcfdd6173c8da6674,0xbba91507bcae1200,0xcfdd6173c8da6674, - 0x2980993910b9a00,0xa90019b99039208,0x2980993910b9a00,0xa90019b99039208, - 0xfc3bb0778b4cc700,0xac6be027db1c9750,0xfc3bb0778b4cc700,0xac6be027db1c9750, - 0x70ed1f82f26f9d00,0x118c7ee3930efc61,0x70ed1f82f26f9d00,0x118c7ee3930efc61, - 0x8c5ac7119d4bd600,0xeb3da076fa2cb167,0x8c5ac7119d4bd600,0xeb3da076fa2cb167, - 0x8a18fe6ce6749200,0x9a08ee7cf6648210,0x8a18fe6ce6749200,0x9a08ee7cf6648210, - 0xfa5b48e913b2a100,0x75d4c7669c3d2e8f,0xfa5b48e913b2a100,0x75d4c7669c3d2e8f, - 0x6d660d066b600b00,0xd066d660b006b60,0x6d660d066b600b00,0xd066d660b006b60, - 0xc5c16763a6a20400,0xa8ac0a0ecbcf696d,0xc5c16763a6a20400,0xa8ac0a0ecbcf696d, - 0x1b48f2a1bae95300,0x4112a8fbe0b3095a,0x1b48f2a1bae95300,0x4112a8fbe0b3095a, - 0xcaca47478d8d0000,0x5c5cd1d11b1b9696,0xcaca47478d8d0000,0x5c5cd1d11b1b9696, - 0x56ac83792fd5fa00,0x976d42b8ee143bc1,0x56ac83792fd5fa00,0x976d42b8ee143bc1, - 0x9f9febeb74740000,0x13136767f8f88c8c,0x9f9febeb74740000,0x13136767f8f88c8c, - 0x13dbfd3526eec800,0x5098be7665ad8b43,0x13dbfd3526eec800,0x5098be7665ad8b43, - 0x65659f9ffafa0000,0x5252a8a8cdcd3737,0x65659f9ffafa0000,0x5252a8a8cdcd3737, - 0x96bf8da4321b2900,0x153c0e27b198aa83,0x96bf8da4321b2900,0x153c0e27b198aa83, - 0xf1f10909f8f80000,0x5656aeae5f5fa7a7,0xf1f10909f8f80000,0x5656aeae5f5fa7a7, - 0xf4d29bbd496f2600,0x2246d4bbf99d0f6,0xf4d29bbd496f2600,0x2246d4bbf99d0f6, - 0x3d3d0a0a37370000,0xe7e7d0d0ededdada,0x3d3d0a0a37370000,0xe7e7d0d0ededdada, - 0x1e4a8bdfc1955400,0xf4a061352b7fbeea,0x1e4a8bdfc1955400,0xf4a061352b7fbeea, - 0x1e1e565648480000,0x4c4c04041a1a5252,0x1e1e565648480000,0x4c4c04041a1a5252, - 0x5fbe36d78869e100,0xf5149c7d22c34baa,0x5fbe36d78869e100,0xf5149c7d22c34baa, - 0x7373efef9c9c0000,0x8f8f13136060fcfc,0x7373efef9c9c0000,0x8f8f13136060fcfc, - 0x1fe840b7a85ff700,0x4f35bacb344ec1b,0x1fe840b7a85ff700,0x4f35bacb344ec1b, - 0x6666ddddbbbb0000,0x6969d2d2b4b40f0f,0x6666ddddbbbb0000,0x6969d2d2b4b40f0f, - 0x423fa1dc9ee37d00,0x5e23bdc082ff611c,0x423fa1dc9ee37d00,0x5e23bdc082ff611c, - 0xca4b1b9a50d18100,0x1c9dcd4c860757d6,0xca4b1b9a50d18100,0x1c9dcd4c860757d6, - 0xba8993a3192a300,0xb81b2a89822110b3,0xba8993a3192a300,0xb81b2a89822110b3, - 0xa5ce99f2573c6b00,0xa8c394ff5a31660d,0xa5ce99f2573c6b00,0xa8c394ff5a31660d, - 0xab2831b2199a8300,0x5fdcc546ed6e77f4,0xab2831b2199a8300,0x5fdcc546ed6e77f4, - 0xf607a958ae5ff100,0xc83997669061cf3e,0xf607a958ae5ff100,0xc83997669061cf3e, - 0xa531fa6ecb5f9400,0x9b0fc450f561aa3e,0xa531fa6ecb5f9400,0x9b0fc450f561aa3e, - 0x7f39afe996d04600,0x9cda4c0a7533a5e3,0x7f39afe996d04600,0x9cda4c0a7533a5e3, - 0x7d1588e09df56800,0x86ee731b660e93fb,0x7d1588e09df56800,0x86ee731b660e93fb, - 0x52013f6c3e6d5300,0xaffcc291c390aefd,0x52013f6c3e6d5300,0xaffcc291c390aefd, - 0x488c79bdf531c400,0xdf1bee2a62a65397,0x488c79bdf531c400,0xdf1bee2a62a65397, - 0xd7a77303d4a47000,0xd2a27606d1a17505,0xd7a77303d4a47000,0xd2a27606d1a17505, - 0xb7ff7e3681c94800,0x145cdd95226aeba3,0xb7ff7e3681c94800,0x145cdd95226aeba3, - 0x6399c03a59a3fa00,0xd72d748eed174eb4,0x6399c03a59a3fa00,0xd72d748eed174eb4, - 0xd7ceb1a87f661900,0xf1e8978e59403f26,0xd7ceb1a87f661900,0xf1e8978e59403f26, - 0x5f3e98f9a6c76100,0x86e741207f1eb8d9,0x5f3e98f9a6c76100,0x86e741207f1eb8d9, - 0xcc31af529e63fd00,0x6c910ff23ec35da0,0xcc31af529e63fd00,0x6c910ff23ec35da0, - 0xe6a1b3f412554700,0xabecfeb95f180a4d,0xe6a1b3f412554700,0xabecfeb95f180a4d, - 0x37012f192e183600,0x6157794f784e6056,0x37012f192e183600,0x6157794f784e6056, - 0x286eca8ca4e24600,0x4600a4e2ca8c286e,0x286eca8ca4e24600,0x4600a4e2ca8c286e, - 0xca68f2509a38a200,0x8e2cb614de7ce644,0xca68f2509a38a200,0x8e2cb614de7ce644, - 0x5db2ee015cb3ef00,0xbc530fe0bd520ee1,0x5db2ee015cb3ef00,0xbc530fe0bd520ee1, - 0xf92f00d62ff9d600,0x15c3ec3ac3153aec,0xf92f00d62ff9d600,0x15c3ec3ac3153aec, - 0xb25147a416f5e300,0xf41701e250b3a546,0xb25147a416f5e300,0xf41701e250b3a546, - 0x9dbd22029fbf2000,0xad8d1232af8f1030,0x9dbd22029fbf2000,0xad8d1232af8f1030, - 0x4ce911b4f85da500,0x3f9a62c78b2ed673,0x4ce911b4f85da500,0x3f9a62c78b2ed673, - 0xf9ca6556af9c3300,0xc6f55a6990a30c3f,0xf9ca6556af9c3300,0xc6f55a6990a30c3f, - 0x4e9865b3fd2bd600,0xc412ef3977a15c8a,0x4e9865b3fd2bd600,0xc412ef3977a15c8a, - 0x4677625315243100,0xf0c1d4e5a39287b6,0x4677625315243100,0xf0c1d4e5a39287b6, - 0x2e601d537d334e00,0x86c8b5fbd59be6a8,0x2e601d537d334e00,0x86c8b5fbd59be6a8, - 0x44c455d591118000,0x890998185cdc4dcd,0x44c455d591118000,0x890998185cdc4dcd, - 0x3e1d6447795a2300,0x9ab9c0e3ddfe87a4,0x3e1d6447795a2300,0x9ab9c0e3ddfe87a4, - 0x2167561031774600,0x442733514526325,0x2167561031774600,0x442733514526325, - 0xf371078576f48200,0xe8cfa788b097ffd,0xf371078576f48200,0xe8cfa788b097ffd, - 0xa719912f8836be00,0x843ab20cab159d23,0xa719912f8836be00,0x843ab20cab159d23, - 0x89c5115dd4984c00,0xb5f92d61e8a4703c,0x89c5115dd4984c00,0xb5f92d61e8a4703c, - 0x50cce47828b49c00,0xd44860fcac301884,0x50cce47828b49c00,0xd44860fcac301884, - 0xa1b1869637271000,0xefffc8d879695e4e,0xa1b1869637271000,0xefffc8d879695e4e, - 0x1f3b391d02262400,0x4c686a4e51757753,0x1f3b391d02262400,0x4c686a4e51757753, - 0x3237fbfeccc90500,0xbcb9757042478b8e,0x3237fbfeccc90500,0xbcb9757042478b8e, - 0x6077d7c7a7b0100,0x2d2c565751502a2b,0x6077d7c7a7b0100,0x2d2c565751502a2b, - 0x2e268f87a9a10800,0xfff75e567870d9d1,0x2e268f87a9a10800,0xfff75e567870d9d1, - 0x73212e7c0f5d5200,0x72202f7d0e5c5301,0x73212e7c0f5d5200,0x72202f7d0e5c5301, - 0x458d38f0b57dc800,0x9951e42c69a114dc,0x458d38f0b57dc800,0x9951e42c69a114dc, - 0x7b0bc7b7ccbc7000,0x373bfcfb4c40878,0x7b0bc7b7ccbc7000,0x373bfcfb4c40878, - 0x4b148fdf94cb500,0x299c65d0d461982d,0x4b148fdf94cb500,0x299c65d0d461982d, - 0xd591145481c5400,0xfbafe7b3beeaa2f6,0xd591145481c5400,0xfbafe7b3beeaa2f6, - 0xc32aa34a8960e900,0xc32aa34a8960e900,0xc32aa34a8960e900,0xc32aa34a8960e900, - 0x235ab6cfec957900,0x4b32dea784fd1168,0x235ab6cfec957900,0x4b32dea784fd1168, - 0xe30eb558bb56ed00,0x43ae15f81bf64da0,0xe30eb558bb56ed00,0x43ae15f81bf64da0, - 0x5ddffa7825a78200,0xf67451d38e0c29ab,0x5ddffa7825a78200,0xf67451d38e0c29ab, - 0x9b96dad74c410d00,0xd004c41dad79b96,0x9b96dad74c410d00,0xd004c41dad79b96, - 0xf0965432c2a46600,0x4e28ea8c7c1ad8be,0xf0965432c2a46600,0x4e28ea8c7c1ad8be, - 0xfcb5b1f8044d4900,0x95dcd8916d242069,0xfcb5b1f8044d4900,0x95dcd8916d242069, - 0x5d24ef96cbb27900,0xa8d11a633e478cf5,0x5d24ef96cbb27900,0xa8d11a633e478cf5, - 0xfae6839f65791c00,0x504c2935cfd3b6aa,0xfae6839f65791c00,0x504c2935cfd3b6aa, - 0xab0ef257fc59a500,0x4aef13b61db844e1,0xab0ef257fc59a500,0x4aef13b61db844e1, - 0x12bd3f90822daf00,0xe946c46b79d654fb,0x12bd3f90822daf00,0xe946c46b79d654fb, - 0x4dbe23d39e6df00,0xf62910cfcb142df2,0x4dbe23d39e6df00,0xf62910cfcb142df2, - 0xe3abb8f81b53400,0x6d59d8ece2d65763,0xe3abb8f81b53400,0x6d59d8ece2d65763, - 0xeaf6f9e50f131c00,0x839f908c667a7569,0xeaf6f9e50f131c00,0x839f908c667a7569, - 0xe171f06081119000,0x4ada5bcb2aba3bab,0xe171f06081119000,0x4ada5bcb2aba3bab, - 0x9d95838b161e0800,0x848c9a920f071119,0x9d95838b161e0800,0x848c9a920f071119, - 0xbc5e24c67a98e200,0xd4364cae12f08a68,0xbc5e24c67a98e200,0xd4364cae12f08a68, - 0x2e7833654b1d5600,0x30662d7b5503481e,0x2e7833654b1d5600,0x30662d7b5503481e, - 0xf9e1e0f801191800,0xa9b1b0a851494850,0xf9e1e0f801191800,0xa9b1b0a851494850, - 0x6177b6a6c7d1100,0xeffe92838594f8e9,0x6177b6a6c7d1100,0xeffe92838594f8e9, - 0x6bf9a93b50c29200,0x8c1e4edcb72575e7,0x6bf9a93b50c29200,0x8c1e4edcb72575e7, - 0x7ed997304ee9a700,0x3b9cd2750bace245,0x7ed997304ee9a700,0x3b9cd2750bace245, - 0x58bf1bfca443e700,0x9f78dc3b638420c7,0x58bf1bfca443e700,0x9f78dc3b638420c7, - 0x13ea34cdde27f900,0xfd04da2330c917ee,0x13ea34cdde27f900,0xfd04da2330c917ee, - 0xd2eba39a48713900,0xa198d0e93b024a73,0xd2eba39a48713900,0xa198d0e93b024a73, - 0xd3a284f526577100,0xb0c1e79645341263,0xd3a284f526577100,0xb0c1e79645341263, - 0x891e05921b8c9700,0x83140f9811869d0a,0x891e05921b8c9700,0x83140f9811869d0a, - 0x1fa33c809f23bc00,0xb30f902c338f10ac,0x1fa33c809f23bc00,0xb30f902c338f10ac, - 0x2542cbac89ee6700,0x166ef88adca4324,0x2542cbac89ee6700,0x166ef88adca4324, - 0x15342b0a1f3e2100,0x86a7b8998cadb293,0x15342b0a1f3e2100,0x86a7b8998cadb293, - 0x32d05bb98b69e200,0xfc1e957745a72cce,0x32d05bb98b69e200,0xfc1e957745a72cce, - 0xed3ffc2ec311d200,0x2bf93ae805d714c6,0xed3ffc2ec311d200,0x2bf93ae805d714c6, - 0x5b3f64643f5b00,0xf2a9cd9696cda9f2,0x5b3f64643f5b00,0xf2a9cd9696cda9f2, - 0xb18885bc0d343900,0x774e437acbf2ffc6,0xb18885bc0d343900,0x774e437acbf2ffc6, - 0x7a1f41245e3b6500,0x9affa1c4bedb85e0,0x7a1f41245e3b6500,0x9affa1c4bedb85e0, - 0x11aa0db6a71cbb00,0x2893348f9e258239,0x11aa0db6a71cbb00,0x2893348f9e258239, - 0x2defad6f4280c200,0xc90b498ba66426e4,0x2defad6f4280c200,0xc90b498ba66426e4, - 0x5e51fdf2aca30f00,0x6768c4cb959a3639,0x5e51fdf2aca30f00,0x6768c4cb959a3639, - 0xded84b4d93950600,0x2721b2b46a6cfff9,0xded84b4d93950600,0x2721b2b46a6cfff9, - 0xad54c33a976ef900,0x1ce5728b26df48b1,0xad54c33a976ef900,0x1ce5728b26df48b1, - 0xb6f1d99e286f4700,0x82c5edaa1c5b7334,0xb6f1d99e286f4700,0x82c5edaa1c5b7334, - 0x3681cb7c4afdb700,0x3285cf784ef9b304,0x3681cb7c4afdb700,0x3285cf784ef9b304, - 0x9f3e51f06fcea100,0xa1006fce51f09f3e,0x9f3e51f06fcea100,0xa1006fce51f09f3e, - 0x9288a2b82a301a00,0x415b716bf9e3c9d3,0x9288a2b82a301a00,0x415b716bf9e3c9d3, - 0x7b072458235f7c00,0x770b28542f53700c,0x7b072458235f7c00,0x770b28542f53700c, - 0xd7da6e63b4b90d00,0x808d3934e3ee5a57,0xd7da6e63b4b90d00,0x808d3934e3ee5a57, - 0x2b9b40f0db6bb00,0xb40f02b9bb000db6,0x2b9b40f0db6bb00,0xb40f02b9bb000db6, - 0x32264b5f6d791400,0x1d09647042563b2f,0x32264b5f6d791400,0x1d09647042563b2f, - 0x8803cb4bc348800,0x2ba31f979f17ab23,0x8803cb4bc348800,0x2ba31f979f17ab23, - 0x58ea49fba311b200,0xa91bb80a52e043f1,0x58ea49fba311b200,0xa91bb80a52e043f1, - 0xb0698c55e53cd900,0x3fe603da6ab3568f,0xb0698c55e53cd900,0x3fe603da6ab3568f, - 0x2178376e4f165900,0xe7bef1a889d09fc6,0x2178376e4f165900,0xe7bef1a889d09fc6, - 0xb141a959e818f000,0xb848a050e111f909,0xb141a959e818f000,0xb848a050e111f909, - 0x5d951cd48941c800,0xd81099510cc44d85,0x5d951cd48941c800,0xd81099510cc44d85, - 0xa21d7dc260dfbf00,0x69d6b609ab1474cb,0xa21d7dc260dfbf00,0x69d6b609ab1474cb, - 0x23ba3ea7841d9900,0xac35b1280b92168f,0x23ba3ea7841d9900,0xac35b1280b92168f, - 0x56e9912e78c7bf00,0xeb1c976209fe758,0x56e9912e78c7bf00,0xeb1c976209fe758, - 0xc60ce228ee24ca00,0xe329c70dcb01ef25,0xc60ce228ee24ca00,0xe329c70dcb01ef25, - 0xef8a2d48a7c26500,0x97f25530dfba1d78,0xef8a2d48a7c26500,0x97f25530dfba1d78, - 0x46ab18f5b35eed00,0xa64bf81553be0de0,0x46ab18f5b35eed00,0xa64bf81553be0de0, - 0xe67f54cd2bb29900,0x930a21b85ec7ec75,0xe67f54cd2bb29900,0x930a21b85ec7ec75, - 0xf01cde32c22eec00,0x40ac6e82729e5cb0,0xf01cde32c22eec00,0x40ac6e82729e5cb0, - 0xd612cb0fd91dc400,0xdb1fc602d410c90d,0xd612cb0fd91dc400,0xdb1fc602d410c90d, - 0x885f69be36e1d700,0xaf784e9911c6f027,0x885f69be36e1d700,0xaf784e9911c6f027, - 0xa1b05544e5f41100,0x6b7a9f8e2f3edbca,0xa1b05544e5f41100,0x6b7a9f8e2f3edbca, - 0x3e126448765a2c00,0x8ba7d1fdc3ef99b5,0x3e126448765a2c00,0x8ba7d1fdc3ef99b5, - 0x4ebb1beea055f500,0xc03595602edb7b8e,0x4ebb1beea055f500,0xc03595602edb7b8e, - 0xcbfbaa9a51613000,0xae9ecfff34045565,0xcbfbaa9a51613000,0xae9ecfff34045565, - 0x6e970ff69861f900,0xe41d857c12eb738a,0x6e970ff69861f900,0xe41d857c12eb738a, - 0x94dbaae5713e4f00,0x216e1f50c48bfab5,0x94dbaae5713e4f00,0x216e1f50c48bfab5, - 0x2ad4be406a94fe00,0xbb452fd1fb056f91,0x2ad4be406a94fe00,0xbb452fd1fb056f91, - 0x84c7783bbffc4300,0x4003bcff7b3887c4,0x84c7783bbffc4300,0x4003bcff7b3887c4, - 0x508969b9e930d00,0x505dc3cecbc65855,0x508969b9e930d00,0x505dc3cecbc65855, - 0xe85a4ffd15a7b200,0xbf0d18aa42f0e557,0xe85a4ffd15a7b200,0xbf0d18aa42f0e557, - 0x16739df8ee8b6500,0xa8cd23465035dbbe,0x16739df8ee8b6500,0xa8cd23465035dbbe, - 0x175594d6c1834200,0x6f2decaeb9fb3a78,0x175594d6c1834200,0x6f2decaeb9fb3a78, - 0xee901f618ff17e00,0x5b25aad43a44cbb5,0xee901f618ff17e00,0x5b25aad43a44cbb5, - 0x98a65c62fac43e00,0x221ce6d8407e84ba,0x98a65c62fac43e00,0x221ce6d8407e84ba, - 0x10f32ac9d93ae300,0x4e73eddcd2ef714,0x10f32ac9d93ae300,0x4e73eddcd2ef714, - 0xd31123e132f0c200,0x69ab995b884a78ba,0xd31123e132f0c200,0x69ab995b884a78ba, - 0x695daa9ef7c33400,0xb28671452c18efdb,0x695daa9ef7c33400,0xb28671452c18efdb, - 0xffb5cf857a304a00,0xeea4de946b215b11,0xffb5cf857a304a00,0xeea4de946b215b11, - 0xfd08aa5fa257f500,0x9065c732cf3a986d,0xfd08aa5fa257f500,0x9065c732cf3a986d, - 0xce604be52b85ae00,0xd17f54fa349ab11f,0xce604be52b85ae00,0xd17f54fa349ab11f, - 0xd7ac6a11c6bd7b00,0x6813d5ae7902c4bf,0xd7ac6a11c6bd7b00,0x6813d5ae7902c4bf, - 0x9b4a66b72cfdd100,0x3cedc1108b5a76a7,0x9b4a66b72cfdd100,0x3cedc1108b5a76a7, - 0x98ab5261f9ca3300,0xdfec1526be8d7447,0x98ab5261f9ca3300,0xdfec1526be8d7447, - 0x2ce1bf725e93cd00,0xd71a4489a56836fb,0x2ce1bf725e93cd00,0xd71a4489a56836fb, - 0xb6adb4af19021b00,0xc5dec7dc6a716873,0xb6adb4af19021b00,0xc5dec7dc6a716873, - 0xa960935af33ac900,0x6ea7549d34fd0ec7,0xa960935af33ac900,0x6ea7549d34fd0ec7, - 0xe2a57e39db9c4700,0x8ccb1057b5f2296e,0xe2a57e39db9c4700,0x8ccb1057b5f2296e, - 0x357a9ad5e0af4f00,0x1956b6f9cc83632c,0x357a9ad5e0af4f00,0x1956b6f9cc83632c, - 0x2583832500a6a600,0xd37575d3f65050f6,0x2583832500a6a600,0xd37575d3f65050f6, - 0x6d646f660b020900,0xa6afa4adc0c9c2cb,0x6d646f660b020900,0xa6afa4adc0c9c2cb, - 0x8135c672f347b400,0xb105f642c3778430,0x8135c672f347b400,0xb105f642c3778430, - 0x4916c29dd48b5f00,0x5a05d18ec7984c13,0x4916c29dd48b5f00,0x5a05d18ec7984c13, - 0xa45cfb03a75ff800,0x52aa0df551a90ef6,0xa45cfb03a75ff800,0x52aa0df551a90ef6, - 0xcfefdafa35152000,0x14340121eecefbdb,0xcfefdafa35152000,0x14340121eecefbdb, - 0xce7c2a9856e4b200,0x7bc99f2de35107b5,0xce7c2a9856e4b200,0x7bc99f2de35107b5, - 0xf006e711e117f600,0x996f8e78887e9f69,0xf006e711e117f600,0x996f8e78887e9f69, - 0x520b94cd9fc65900,0xcd940b520059c69f,0x520b94cd9fc65900,0xcd940b520059c69f, - 0x534ca7b8ebf41f00,0x78678c93c0df342b,0x534ca7b8ebf41f00,0x78678c93c0df342b, - 0x7d668b90edf61b00,0x776c819ae7fc110a,0x7d668b90edf61b00,0x776c819ae7fc110a, - 0xf2dfcde0123f2d00,0x210c1e33c1ecfed3,0xf2dfcde0123f2d00,0x210c1e33c1ecfed3, - 0xfe0a5fab55a1f400,0x6c98cd39c7336692,0xfe0a5fab55a1f400,0x6c98cd39c7336692, - 0xb8b26c66ded40a00,0x707aa4ae161cc2c8,0xb8b26c66ded40a00,0x707aa4ae161cc2c8, - 0xcfde0e1fd0c11100,0xe5f42435faeb3b2a,0xcfde0e1fd0c11100,0xe5f42435faeb3b2a, - 0xa9947b46efd23d00,0x211cf3ce675ab588,0xa9947b46efd23d00,0x211cf3ce675ab588, - 0xd96be95b8230b200,0xb80a883ae351d361,0xd96be95b8230b200,0xb80a883ae351d361, - 0x707bdbd0a0ab0b00,0xbeb5151e6e65c5ce,0x707bdbd0a0ab0b00,0xbeb5151e6e65c5ce, - 0x9cef790a96e57300,0xd4a73142dead3b48,0x9cef790a96e57300,0xd4a73142dead3b48, - 0x9f065ec758c19900,0xd24b138a158cd44d,0x9f065ec758c19900,0xd24b138a158cd44d, - 0xfe8d2457a9da7300,0xe291384bb5c66f1c,0xfe8d2457a9da7300,0xe291384bb5c66f1c, - 0xd5ef0e34e1db3a00,0x251ffec4112bcaf0,0xd5ef0e34e1db3a00,0x251ffec4112bcaf0, - 0x97f61879ee8f6100,0x7e1ff190076688e9,0x97f61879ee8f6100,0x7e1ff190076688e9, - 0x4040040444440000,0xf3f3b7b7f7f7b3b3,0x4040040444440000,0xf3f3b7b7f7f7b3b3, - 0xa8a7333c949b0f00,0x1817838c242bbfb0,0xa8a7333c949b0f00,0x1817838c242bbfb0, - 0x50a34dbeee1df300,0x2cdf31c292618f7c,0x50a34dbeee1df300,0x2cdf31c292618f7c, - 0xaebb2c3997821500,0x4055c2d7796cfbee,0xaebb2c3997821500,0x4055c2d7796cfbee, - 0x1743d48493c7500,0x97e2abdedfaae396,0x1743d48493c7500,0x97e2abdedfaae396, - 0x9b983033a8ab0300,0x8a892122b9ba1211,0x9b983033a8ab0300,0x8a892122b9ba1211, - 0x442b026d29466f00,0x4629006f2b446d02,0x442b026d29466f00,0x4629006f2b446d02, - 0x2d96d06b46fdbb00,0x8c3771cae75c1aa1,0x2d96d06b46fdbb00,0x8c3771cae75c1aa1, - 0x765d466d1b302b00,0x84afb49fe9c2d9f2,0x765d466d1b302b00,0x84afb49fe9c2d9f2, - 0xecf94555b9ac100,0x80411adbd5144f8e,0xecf94555b9ac100,0x80411adbd5144f8e, - 0xbb354ece75fb800,0x348c6bd3d860873f,0xbb354ece75fb800,0x348c6bd3d860873f, - 0xec67840fe3688b00,0xf972911af67d9e15,0xec67840fe3688b00,0xf972911af67d9e15, - 0x611f522c4d337e00,0x84fab7c9a8d69be5,0x611f522c4d337e00,0x84fab7c9a8d69be5, - 0xf55079dc298ca500,0x49ecc560953019bc,0xf55079dc298ca500,0x49ecc560953019bc, - 0xe35845fe1da6bb00,0x10abb60dee5548f3,0xe35845fe1da6bb00,0x10abb60dee5548f3, - 0x11a408bdac19b500,0x6bde72c7d663cf7a,0x11a408bdac19b500,0x6bde72c7d663cf7a, - 0x3b612f754e145a00,0x9fc58bd1eab0fea4,0x3b612f754e145a00,0x9fc58bd1eab0fea4, - 0xf6ff8d84727b0900,0x373e4c45b3bac8c1,0xf6ff8d84727b0900,0x373e4c45b3bac8c1, - 0xa7339307a0349400,0x31a5059136a20296,0xa7339307a0349400,0x31a5059136a20296, - 0x601d7d00601d7d00,0x4f32522f4f32522f,0x601d7d00601d7d00,0x4f32522f4f32522f, - 0xb9d1593188e06800,0x5830b8d0690189e1,0xb9d1593188e06800,0x5830b8d0690189e1, - 0x9c7319f66a85ef00,0x937c16f9658ae00f,0x9c7319f66a85ef00,0x937c16f9658ae00f, - 0xb769ca14a37dde00,0x27f95a8433ed4e90,0xb769ca14a37dde00,0x27f95a8433ed4e90, - 0xc32134d615f7e200,0x9674618340a2b755,0xc32134d615f7e200,0x9674618340a2b755, - 0x4e6c6a4806242200,0x391b1d3f71535577,0x4e6c6a4806242200,0x391b1d3f71535577, - 0x68312f761e475900,0xb9e0fea7cf9688d1,0x68312f761e475900,0xb9e0fea7cf9688d1, - 0xd30571a774a2d600,0x9c4a3ee83bed994f,0xd30571a774a2d600,0x9c4a3ee83bed994f, - 0x8990dfc64f561900,0x7e672831b8a1eef7,0x8990dfc64f561900,0x7e672831b8a1eef7, - 0x2023a2a181820300,0xbfbc3d3e1e1d9c9f,0x2023a2a181820300,0xbfbc3d3e1e1d9c9f, - 0xe26956dd3fb48b00,0xac27189371fac54e,0xe26956dd3fb48b00,0xac27189371fac54e, - 0xd95f2ea871f78600,0x66e09117ce4839bf,0xd95f2ea871f78600,0x66e09117ce4839bf, - 0x159d76feeb638800,0x1d957ef6e36b8008,0x159d76feeb638800,0x1d957ef6e36b8008, - 0xebebc3c328280000,0x24240c0ce7e7cfcf,0xebebc3c328280000,0x24240c0ce7e7cfcf, - 0x95ba022db8972f00,0x3f10a887123d85aa,0x95ba022db8972f00,0x3f10a887123d85aa, - 0x4a53554c061f1900,0xd3caccd59f868099,0x4a53554c061f1900,0xd3caccd59f868099, - 0xebd3f6ce251d3800,0xb189ac947f47625a,0xebd3f6ce251d3800,0xb189ac947f47625a, - 0x7db9e92d5094c400,0xc1055591ec2878bc,0x7db9e92d5094c400,0xc1055591ec2878bc, - 0x6ac00aaac06aa00,0x4de74be1e74de14b,0x6ac00aaac06aa00,0x4de74be1e74de14b, - 0x37669fcef9a85100,0xd4857c2d1a4bb2e3,0x37669fcef9a85100,0xd4857c2d1a4bb2e3, - 0xd618c00ed816ce00,0x3af42ce234fa22ec,0xd618c00ed816ce00,0x3af42ce234fa22ec, - 0x22cd739cbe51ef00,0x9a75cb2406e957b8,0x22cd739cbe51ef00,0x9a75cb2406e957b8, - 0xa2b64652f0e41400,0x617585913327d7c3,0xa2b64652f0e41400,0x617585913327d7c3, - 0x3c0de1d1eddc300,0xb47769aaa96a74b7,0x3c0de1d1eddc300,0xb47769aaa96a74b7, - 0xaa771dcd67bad00,0x2c8157faf05d8b26,0xaa771dcd67bad00,0x2c8157faf05d8b26, - 0x870aa429ae238d00,0x61ec42cf48c56be6,0x870aa429ae238d00,0x61ec42cf48c56be6, - 0x5ae3b90953eab00,0xca61f45f5af164cf,0x5ae3b90953eab00,0xca61f45f5af164cf, - 0xbc215bc67ae79d00,0xf16c168b37aad04d,0xbc215bc67ae79d00,0xf16c168b37aad04d, - 0x4cd01b87cb579c00,0xc458930f43df1488,0x4cd01b87cb579c00,0xc458930f43df1488, - 0x7405651460117100,0xfd8cec9de998f889,0x7405651460117100,0xfd8cec9de998f889, - 0xf812d832ca20ea00,0x816ba14bb3599379,0xf812d832ca20ea00,0x816ba14bb3599379, - 0xdf7c53f02f8ca300,0xf55679da05a6892a,0xdf7c53f02f8ca300,0xf55679da05a6892a, - 0x16685e2036487e00,0x57b4d33255b6d13,0x16685e2036487e00,0x57b4d33255b6d13, - 0x4d24e78ec3aa6900,0x69aac38ee7244d,0x4d24e78ec3aa6900,0x69aac38ee7244d, - 0xf4853c4db9c87100,0x413089f80c7dc4b5,0xf4853c4db9c87100,0x413089f80c7dc4b5, - 0x237a451c3f665900,0xecb58ad3f0a996cf,0x237a451c3f665900,0xecb58ad3f0a996cf, - 0x5206b4e4b6e2500,0x83a6edc8cde8a386,0x5206b4e4b6e2500,0x83a6edc8cde8a386, - 0x434358581b1b0000,0xacacb7b7f4f4efef,0x434358581b1b0000,0xacacb7b7f4f4efef, - 0x2ccc9a7a56b6e000,0x907026c6ea0a5cbc,0x2ccc9a7a56b6e000,0x907026c6ea0a5cbc, - 0x5825a7da82ff7d00,0x88f5770a522fadd0,0x5825a7da82ff7d00,0x88f5770a522fadd0, - 0x26fb7da0865bdd00,0x7ea325f8de038558,0x26fb7da0865bdd00,0x7ea325f8de038558, - 0x133c002f3c132f00,0xecc3ffd0c3ecd0ff,0x133c002f3c132f00,0xecc3ffd0c3ecd0ff, - 0x8aa97556dcff2300,0xb695496ae0c31f3c,0x8aa97556dcff2300,0xb695496ae0c31f3c, - 0x7d067b0b760d700,0x7aad1acdca1daa7d,0x7d067b0b760d700,0x7aad1acdca1daa7d, - 0xb0c3e49727547300,0xc5b691e252210675,0xb0c3e49727547300,0xc5b691e252210675, - 0x420cc789cb854e00,0x622ce7a9eba56e20,0x420cc789cb854e00,0x622ce7a9eba56e20, - 0x4d3abbcc81f67700,0x5225a4d39ee9681f,0x4d3abbcc81f67700,0x5225a4d39ee9681f, - 0x5192e32071b2c300,0xbe7d0ccf9e5d2cef,0x5192e32071b2c300,0xbe7d0ccf9e5d2cef, - 0x3b7482cdf6b94f00,0xca85733c0748bef1,0x3b7482cdf6b94f00,0xca85733c0748bef1, - 0xfb451ca259e7be00,0xb00e57e912acf54b,0xfb451ca259e7be00,0xb00e57e912acf54b, - 0x8f1ee372fd6c9100,0x9809f465ea7b8617,0x8f1ee372fd6c9100,0x9809f465ea7b8617, - 0x7784956611e2f300,0xa85b4ab9ce3d2cdf,0x7784956611e2f300,0xa85b4ab9ce3d2cdf, - 0xc0de5e4e8e90100,0xa0be3e2eeef0706,0xc0de5e4e8e90100,0xa0be3e2eeef0706, - 0xe92b8644ad6fc200,0x5a9835f71edc71b3,0xe92b8644ad6fc200,0x5a9835f71edc71b3, - 0x67256b294e0c4200,0xda98d694f3b1ffbd,0x67256b294e0c4200,0xda98d694f3b1ffbd, - 0xc7dd4a5a9d87100,0xd3a20b7a7607aedf,0xc7dd4a5a9d87100,0xd3a20b7a7607aedf, - 0x90e68bfd6d1b7600,0xb0c6abdd4d3b5620,0x90e68bfd6d1b7600,0xb0c6abdd4d3b5620, - 0x2b73fba388d05800,0xc79f174f643cb4ec,0x2b73fba388d05800,0xc79f174f643cb4ec, - 0xbe91022d93bc2f00,0xa38c1f308ea1321d,0xbe91022d93bc2f00,0xa38c1f308ea1321d, - 0x79e622bdc45b9f00,0xb926e27d049b5fc0,0x79e622bdc45b9f00,0xb926e27d049b5fc0, - }; - - - -} - -#endif diff --git a/libOTe/Tools/bitpolymul/trunc_btfy_tab_64.h b/libOTe/Tools/bitpolymul/trunc_btfy_tab_64.h deleted file mode 100644 index 0c46007a..00000000 --- a/libOTe/Tools/bitpolymul/trunc_btfy_tab_64.h +++ /dev/null @@ -1,298 +0,0 @@ -#pragma once -/* -Copyright (C) 2017 Ming-Shing Chen - -This file is part of BitPolyMul. - -BitPolyMul is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -BitPolyMul is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with BitPolyMul. If not, see . -*/ - - -#include "libOTe/config.h" -#ifdef ENABLE_SILENTOT - - -#include "stdint.h" - - -namespace bpm { - - - - alignas(32) const uint64_t i_beta_mul_32_bm4r[(64 / 4) * 16 * 2] = { - 0x100c7c6c7c60100,0x405c2c3c2c30405, 0x100c7c6c7c60100,0x405c2c3c2c30405, - 0x9d6863960bfef500,0xfb0e05f06d989366, 0x9d6863960bfef500,0xfb0e05f06d989366, - 0xe1e15e5ebfbf0000,0xa0a01f1ffefe4141, 0xe1e15e5ebfbf0000,0xa0a01f1ffefe4141, - 0x44ae6288cc26ea00,0x45af6389cd27eb01, 0x44ae6288cc26ea00,0x45af6389cd27eb01, - 0xa5a5e4e441410000,0xe5e5a4a401014040, 0xa5a5e4e441410000,0xe5e5a4a401014040, - 0x1a1598978d820f00,0xa5aa2728323db0bf, 0x1a1598978d820f00,0xa5aa2728323db0bf, - 0x7e7e060678780000,0xaeaed6d6a8a8d0d0, 0x7e7e060678780000,0xaeaed6d6a8a8d0d0, - 0xd44337a074e39700,0x6afd891eca5d29be, 0xd44337a074e39700,0x6afd891eca5d29be, - 0xe9e963638a8a0000,0x80800a0ae3e36969, 0xe9e963638a8a0000,0x80800a0ae3e36969, - 0xc46115b571d4a00,0x2f653278743e6923, 0xc46115b571d4a00,0x2f653278743e6923, - 0xc7c7dcdc1b1b0000,0xe3e3f8f83f3f2424, 0xc7c7dcdc1b1b0000,0xe3e3f8f83f3f2424, - 0xf41f678c7893eb00,0x4ca7df34c02b53b8, 0xf41f678c7893eb00,0x4ca7df34c02b53b8, - 0xc0c0565696960000,0xf3f36565a5a53333, 0xc0c0565696960000,0xf3f36565a5a53333, - 0x3b2bafbf84941000,0xd9c94d5d6676f2e2, 0x3b2bafbf84941000,0xd9c94d5d6676f2e2, - 0xf5f5fdfd08080000,0x82828a8a7f7f7777, 0xf5f5fdfd08080000,0x82828a8a7f7f7777, - 0x1fce83524d9cd100,0xa3723feef1206dbc, 0x1fce83524d9cd100,0xa3723feef1206dbc, - 0x4e0f9edf91d04100,0xe6a736773978e9a8, 0x4e0f9edf91d04100,0xe6a736773978e9a8, - 0x8f69e606896fe00,0x946a02fcf40a629c, 0x8f69e606896fe00,0x946a02fcf40a629c, - 0x7bf5e36d16988e00,0x1d93850b70fee866, 0x7bf5e36d16988e00,0x1d93850b70fee866, - 0x42a1ad4e0cefe300,0x7e4e80b49aaa645, 0x42a1ad4e0cefe300,0x7e4e80b49aaa645, - 0xea6b5cdd37b68100,0x1998af2ec44572f3, 0xea6b5cdd37b68100,0x1998af2ec44572f3, - 0x1caa8f392593b600,0x3482a7110dbb9e28, 0x1caa8f392593b600,0x3482a7110dbb9e28, - 0xc39ef6ab68355d00,0x421f772ae9b4dc81, 0xc39ef6ab68355d00,0x421f772ae9b4dc81, - 0x2af3b069439ad900,0x29f0b36a4099da03, 0x2af3b069439ad900,0x29f0b36a4099da03, - 0x3853f19aa2c96b00,0x3c57f59ea6cd6f04, 0x3853f19aa2c96b00,0x3c57f59ea6cd6f04, - 0x8cf85e2aa6d27400,0xf5812753dfab0d79, 0x8cf85e2aa6d27400,0xf5812753dfab0d79, - 0x9ca9083da1943500,0xb3e9faa3603a297, 0x9ca9083da1943500,0xb3e9faa3603a297, - 0xadddc9b914647000,0xa9d9cdbd10607404, 0xadddc9b914647000,0xa9d9cdbd10607404, - 0x3fcc44b7887bf300,0x4ab931c2fd0e8675, 0x3fcc44b7887bf300,0x4ab931c2fd0e8675, - 0x3e01e5dae4db3f00,0xbe81655a645bbf80, 0x3e01e5dae4db3f00,0xbe81655a645bbf80, - 0xd8a2c6bc641e7a00,0x87fd99e33b41255f, 0xd8a2c6bc641e7a00,0x87fd99e33b41255f, - 0xc073ea59992ab300,0xfc4fd665a5168f3c, 0xc073ea59992ab300,0xfc4fd665a5168f3c, - 0x4346484d0e0b0500,0xfafff1f4b7b2bcb9, 0x4346484d0e0b0500,0xfafff1f4b7b2bcb9, - 0x40b6e11757a1f600,0x7c8add2b6b9dca3c, 0x40b6e11757a1f600,0x7c8add2b6b9dca3c, - 0x7a47764b310c3d00,0x320f3e0379447548, 0x7a47764b310c3d00,0x320f3e0379447548, - 0xba3c8b0db7318600,0x29af189e24a21593, 0xba3c8b0db7318600,0x29af189e24a21593, - 0x41eb1fb5f45eaa00,0xcb61953f7ed4208a, 0x41eb1fb5f45eaa00,0xcb61953f7ed4208a, - 0x1a73335a40296900,0x771e5e372d44046d, 0x1a73335a40296900,0x771e5e372d44046d, - 0xcc01a16ca06dcd00,0xf23f9f529e53f33e, 0xcc01a16ca06dcd00,0xf23f9f529e53f33e, - 0xa3b74753f0e41400,0xe3f70713b0a45440, 0xa3b74753f0e41400,0xe3f70713b0a45440, - 0x94954342d6d70100,0x6d6cbabb2f2ef8f9, 0x94954342d6d70100,0x6d6cbabb2f2ef8f9, - 0x51fa0aa1f05bab00,0xcb60903b6ac1319a, 0x51fa0aa1f05bab00,0xcb60903b6ac1319a, - 0x5252dddd8f8f0000,0xfafa75752727a8a8, 0x5252dddd8f8f0000,0xfafa75752727a8a8, - 0x1b418ed4cf955a00,0x540ec19b80da154f, 0x1b418ed4cf955a00,0x540ec19b80da154f, - 0xb27901ca78b3cb00,0xf03b43883af18942, 0xb27901ca78b3cb00,0xf03b43883af18942, - 0x13a143f1e250b200,0x45f715a7b406e456, 0x13a143f1e250b200,0x45f715a7b406e456, - 0x9d3006ab369bad00,0x6dc0f65bc66b5df0, 0x9d3006ab369bad00,0x6dc0f65bc66b5df0, - 0x3b7cdc9ba0e74700,0xaaed4d0a3176d691, 0x3b7cdc9ba0e74700,0xaaed4d0a3176d691, - 0x61cb3c96f75daa00,0x1ab047ed8c26d17b, 0x61cb3c96f75daa00,0x1ab047ed8c26d17b, - 0x60ad0bc6a66bcd00,0x9459ff32529f39f4, 0x60ad0bc6a66bcd00,0x9459ff32529f39f4, - 0x8db76953dee43a00,0x271dc3f9744e90aa, 0x8db76953dee43a00,0x271dc3f9744e90aa, - 0x7d17f09ae78d6a00,0x16b8ce69bf1167c, 0x7d17f09ae78d6a00,0x16b8ce69bf1167c, - 0x4192c5165784d300,0x1ac99e4d0cdf885b, 0x4192c5165784d300,0x1ac99e4d0cdf885b, - 0x50c2bc2e7eec9200,0x92ec7e2ebcc250, 0x50c2bc2e7eec9200,0x92ec7e2ebcc250, - 0x3f7da1e3dc9e4200,0x3072aeecd3914d0f, 0x3f7da1e3dc9e4200,0x3072aeecd3914d0f, - 0x2be3834b60a8c800,0x25ed8d456ea6c60e, 0x2be3834b60a8c800,0x25ed8d456ea6c60e, - 0xeea52b608ec54b00,0x4e058bc02e65eba0, 0xeea52b608ec54b00,0x4e058bc02e65eba0, - 0xa8f3aef55d065b00,0x89d28fd47c277a21, 0xa8f3aef55d065b00,0x89d28fd47c277a21, - 0x91b4a38617322500,0x80a5b29706233411, 0x91b4a38617322500,0x80a5b29706233411, - 0x91f897fe6f066900,0xec85ea83127b147d, 0x91f897fe6f066900,0xec85ea83127b147d, - 0xcd1ed201cc1fd300,0x34e72bf835e62af9, 0xcd1ed201cc1fd300,0x34e72bf835e62af9, - 0xf5ad346c99c15800,0xf5ad346c99c15800, 0xf5ad346c99c15800,0xf5ad346c99c15800, - 0x994724fa63bdde00,0x3be58658c11f7ca2, 0x994724fa63bdde00,0x3be58658c11f7ca2, - 0xaf46678e21c8e900,0x27ceef06a9406188, 0xaf46678e21c8e900,0x27ceef06a9406188, - 0x60f7de4929be9700,0x26b1980f6ff8d146, 0x60f7de4929be9700,0x26b1980f6ff8d146, - 0x4e3df383cdbe700,0xa1467a9d997e42a5, 0x4e3df383cdbe700,0xa1467a9d997e42a5, - 0x3fbc27a49b188300,0xb231aa2916950e8d, 0x3fbc27a49b188300,0xb231aa2916950e8d, - 0x1b367558436e2d00,0x9fb2f1dcc7eaa984, 0x1b367558436e2d00,0x9fb2f1dcc7eaa984, - 0xd773258156f2a400,0xa50157f32480d672, 0xd773258156f2a400,0xa50157f32480d672, - 0xc616a171b767d000,0x4f9f28f83eee5989, 0xc616a171b767d000,0x4f9f28f83eee5989, - 0x3bada2340f999600,0x6cfaf56358cec157, 0x3bada2340f999600,0x6cfaf56358cec157, - 0x54e03f8bdf6bb400,0x9420ff4b1fab74c0, 0x54e03f8bdf6bb400,0x9420ff4b1fab74c0, - 0x25b24fd8fd6a9700,0x6cfb0691b423de49, 0x25b24fd8fd6a9700,0x6cfb0691b423de49, - 0x11e685726394f700,0x936407f0e1167582, 0x11e685726394f700,0x936407f0e1167582, - 0xd942ba21f8639b00,0x811ae279a03bc358, 0xd942ba21f8639b00,0x811ae279a03bc358, - 0xad6d67a70acac000,0xa96963a30ecec404, 0xad6d67a70acac000,0xa96963a30ecec404, - 0xcd6510b875dda800,0xf45c29814ce49139, 0xcd6510b875dda800,0xf45c29814ce49139, - 0x7daae235489fd700,0x92450ddaa77038ef, 0x7daae235489fd700,0x92450ddaa77038ef, - 0x70676b7c0c1b1700,0x8f989483f3e4e8ff, 0x70676b7c0c1b1700,0x8f989483f3e4e8ff, - 0xb925ce52eb779c00,0xc955be229b07ec70, 0xb925ce52eb779c00,0xc955be229b07ec70, - 0x209e3e8eae10b00,0xb4bf555e5c57bdb6, 0x209e3e8eae10b00,0xb4bf555e5c57bdb6, - 0x65792c3c5945100,0x85d411404617d283, 0x65792c3c5945100,0x85d411404617d283, - 0xcadf2a3ff5e01500,0x411e4f13b2edbce, 0xcadf2a3ff5e01500,0x411e4f13b2edbce, - 0x8a14af31bb259e00,0xcc52e977fd63d846, 0x8a14af31bb259e00,0xcc52e977fd63d846, - 0x63d67cc9aa1fb500,0xab1eb40162d77dc8, 0x63d67cc9aa1fb500,0xab1eb40162d77dc8, - 0x87f81966e19e7f00,0xc4bb5a25a2dd3c43, 0x87f81966e19e7f00,0xc4bb5a25a2dd3c43, - 0xbb59be5ce705e200,0xae80fed56b453b1, 0xbb59be5ce705e200,0xae80fed56b453b1, - 0x3137040233350600,0x696f5c5a6b6d5e58, 0x3137040233350600,0x696f5c5a6b6d5e58, - 0x3e8168d7e956bf00,0x219e77c8f649a01f, 0x3e8168d7e956bf00,0x219e77c8f649a01f, - 0xb3ca1d64d7ae7900,0x2a5384fd4e37e099, 0xb3ca1d64d7ae7900,0x2a5384fd4e37e099, - 0xd6eba5984e733d00,0x38054b76a09dd3ee, 0xd6eba5984e733d00,0x38054b76a09dd3ee, - 0xcdcd6868a5a50000,0x1818bdbd7070d5d5, 0xcdcd6868a5a50000,0x1818bdbd7070d5d5, - 0x362a405c6a761c00,0x130f65794f533925, 0x362a405c6a761c00,0x130f65794f533925, - 0x3b0ad9e8d3e23100,0x774695a49fae7d4c, 0x3b0ad9e8d3e23100,0x774695a49fae7d4c, - 0x4ef5a01b55eebb00,0x2b9ec5719a2f74c, 0x4ef5a01b55eebb00,0x2b9ec5719a2f74c, - 0xf344b80ffc4bb700,0xa81fe354a710ec5b, 0xf344b80ffc4bb700,0xa81fe354a710ec5b, - 0xa0d9d9a90970700,0x6166f6f1fbfc6c6b, 0xa0d9d9a90970700,0x6166f6f1fbfc6c6b, - 0xec0c3cdc30d0e000,0x47a797779b7b4bab, 0xec0c3cdc30d0e000,0x47a797779b7b4bab, - 0x27a07ef9de598700,0xa720fe795ed90780, 0x27a07ef9de598700,0xa720fe795ed90780, - 0x6620abed8bcd4600,0x296fe4a2c482094f, 0x6620abed8bcd4600,0x296fe4a2c482094f, - 0x50d42aaefe7a8400,0x3eba44c09014ea6e, 0x50d42aaefe7a8400,0x3eba44c09014ea6e, - 0x27499efed9b7600,0xe0967b0d0f7994e2, 0x27499efed9b7600,0xe0967b0d0f7994e2, - 0x55cf3fa5f06a9a00,0x940efe6431ab5bc1, 0x55cf3fa5f06a9a00,0x940efe6431ab5bc1, - 0xb2fde8a7155a4f00,0x7936236cde9184cb, 0xb2fde8a7155a4f00,0x7936236cde9184cb, - 0x683b5300683b5300,0x4211792a4211792a, 0x683b5300683b5300,0x4211792a4211792a, - 0x2b504b301b607b00,0xf48f94efc4bfa4df, 0x2b504b301b607b00,0xf48f94efc4bfa4df, - 0x982a49fb63d1b200,0xbe0c6fdd45f79426, 0x982a49fb63d1b200,0xbe0c6fdd45f79426, - 0x4604246620624200,0xb5f7d795d391b1f3, 0x4604246620624200,0xb5f7d795d391b1f3, - 0xd88888d800505000,0x65353565bdededbd, 0xd88888d800505000,0x65353565bdededbd, - 0xd7f62504d3f22100,0xbe9f4c6dba9b4869, 0xd7f62504d3f22100,0xbe9f4c6dba9b4869, - 0xf4119a7f8b6ee500,0x39dc57b246a328cd, 0xf4119a7f8b6ee500,0x39dc57b246a328cd, - 0x1cdccb0b17d7c000,0xb47463a3bf7f68a8, 0x1cdccb0b17d7c000,0xb47463a3bf7f68a8, - 0x62bc6fb1d30dde00,0x4da09d7b56bb866, 0x62bc6fb1d30dde00,0x4da09d7b56bb866, - 0x83bbf9c1427a3800,0xf7cf8db5360e4c74, 0x83bbf9c1427a3800,0xf7cf8db5360e4c74, - 0x289915a48c3db100,0xca7bf7466edf53e2, 0x289915a48c3db100,0xca7bf7466edf53e2, - 0x3d6f085a67355200,0xe1b3d486bbe98edc, 0x3d6f085a67355200,0xe1b3d486bbe98edc, - 0x44adea0347aee900,0x34dd9a7337de9970, 0x44adea0347aee900,0x34dd9a7337de9970, - 0x3119163e0f272800,0xe1c9c6eedff7f8d0, 0x3119163e0f272800,0xe1c9c6eedff7f8d0, - 0x605b447f1f243b00,0xd3e8f7ccac9788b3, 0x605b447f1f243b00,0xd3e8f7ccac9788b3, - 0x963eb41c8a22a800,0xfe56dc74e24ac068, 0x963eb41c8a22a800,0xfe56dc74e24ac068, - 0x4577c2f0b5873200,0x7e4cf9cb8ebc093b, 0x4577c2f0b5873200,0x7e4cf9cb8ebc093b, - 0x759a917e0be4ef00,0xbe515ab5c02f24cb, 0x759a917e0be4ef00,0xbe515ab5c02f24cb, - 0xa5a47171d4d5000,0xa5f5e8b8b2e2ffaf, 0xa5a47171d4d5000,0xa5f5e8b8b2e2ffaf, - 0xdfbc7310cfac6300,0x6a09c6a57a19d6b5, 0xdfbc7310cfac6300,0x6a09c6a57a19d6b5, - 0x9d9cb4b528290100,0x58597170edecc4c5, 0x9d9cb4b528290100,0x58597170edecc4c5, - 0x57a8f7085fa0ff00,0x8c732cd3847b24db, 0x57a8f7085fa0ff00,0x8c732cd3847b24db, - 0xeb4bea4aa101a000,0x16b617b75cfc5dfd, 0xeb4bea4aa101a000,0x16b617b75cfc5dfd, - 0x1339e8c2d1fb2a00,0xa18b5a70634998b2, 0x1339e8c2d1fb2a00,0xa18b5a70634998b2, - }; - - - alignas(32) const uint64_t beta_mul_32_bm4r[(64 / 4) * 16 * 2] = { - 0x9796d3d245440100,0x8485c0c156571213, 0x9796d3d245440100,0x8485c0c156571213, - 0xe9b9e8b851015000,0x6d3d6c3cd585d484, 0xe9b9e8b851015000,0x6d3d6c3cd585d484, - 0xd6d6b4b462620000,0x74741616c0c0a2a2, 0xd6d6b4b462620000,0x74741616c0c0a2a2, - 0x679fb1492ed6f800,0xbb436d95f20a24dc, 0x679fb1492ed6f800,0xbb436d95f20a24dc, - 0x191914140d0d0000,0x6a6a67677e7e7373, 0x191914140d0d0000,0x6a6a67677e7e7373, - 0xd36077c417a4b300,0x5ae9fe4d9e2d3a89, 0xd36077c417a4b300,0x5ae9fe4d9e2d3a89, - 0x6363ecec8f8f0000,0xf4f47b7b18189797, 0x6363ecec8f8f0000,0xf4f47b7b18189797, - 0x255189fdd8ac7400,0x483ce490b5c1196d, 0x255189fdd8ac7400,0x483ce490b5c1196d, - 0x9191e6e677770000,0x52522525b4b4c3c3, 0x9191e6e677770000,0x52522525b4b4c3c3, - 0x4c7b3e0945723700,0x427530074b7c390e, 0x4c7b3e0945723700,0x427530074b7c390e, - 0xaaaa6464cece0000,0x41418f8f2525ebeb, 0xaaaa6464cece0000,0x41418f8f2525ebeb, - 0x813e6dd253ecbf00,0xfd4211ae2f90c37c, 0x813e6dd253ecbf00,0xfd4211ae2f90c37c, - 0x3f3f686857570000,0xd2d28585babaeded, 0x3f3f686857570000,0xd2d28585babaeded, - 0xe702a643a441e500,0x7d983cd93edb7f9a, 0xe702a643a441e500,0x7d983cd93edb7f9a, - 0x5b5bb6b6eded0000,0xc7c72a2a71719c9c, 0x5b5bb6b6eded0000,0xc7c72a2a71719c9c, - 0xb7e31d49feaa5400,0xd98d732790c43a6e, 0xb7e31d49feaa5400,0xd98d732790c43a6e, - 0x28ea02c2ea28c00,0xd15d73fffd715fd3, 0x28ea02c2ea28c00,0xd15d73fffd715fd3, - 0x3ff772ba854dc800,0x30f87db58a42c70f, 0x3ff772ba854dc800,0x30f87db58a42c70f, - 0xc7584cd3148b9f00,0x897831cdb4450cf, 0xc7584cd3148b9f00,0x897831cdb4450cf, - 0x6ed065dbb50bbe00,0x7bc570cea01eab15, 0x6ed065dbb50bbe00,0x7bc570cea01eab15, - 0xf10575817084f400,0xe81c6c98699ded19, 0xf10575817084f400,0xe81c6c98699ded19, - 0xd7f80827f0df2f00,0xeac5351acde2123d, 0xd7f80827f0df2f00,0xeac5351acde2123d, - 0x8a1b28b933a29100,0xc35261f07aebd849, 0x8a1b28b933a29100,0xc35261f07aebd849, - 0x5e847fa5fb21da00,0x62b84399c71de63c, 0x5e847fa5fb21da00,0x62b84399c71de63c, - 0xe87745da32ad9f00,0x51cefc638b1426b9, 0xe87745da32ad9f00,0x51cefc638b1426b9, - 0x2c37011a362d1b00,0x8893a5be9289bfa4, 0x2c37011a362d1b00,0x8893a5be9289bfa4, - 0x2dca39def314e700,0x17f003e4c92edd3a, 0x2dca39def314e700,0x17f003e4c92edd3a, - 0x7bcfdd6912a6b400,0x9c283a8ef54153e7, 0x7bcfdd6912a6b400,0x9c283a8ef54153e7, - 0xbdff7e3c81c34200,0x6426a7e5581a9bd9, 0xbdff7e3c81c34200,0x6426a7e5581a9bd9, - 0x2d7e6a3914475300,0x1f4c580b26756132, 0x2d7e6a3914475300,0x1f4c580b26756132, - 0xe60dbb50b65deb00,0xc72c9a71977cca21, 0xe60dbb50b65deb00,0xc72c9a71977cca21, - 0xc88d03468ecb4500,0x286de3a66e2ba5e0, 0xc88d03468ecb4500,0x286de3a66e2ba5e0, - 0x60fad44e2eb49a00,0xfe644ad0b02a049e, 0x60fad44e2eb49a00,0xfe644ad0b02a049e, - 0xce83511cd29f4d00,0x400ddf925c11c38e, 0xce83511cd29f4d00,0x400ddf925c11c38e, - 0xb4b76665d1d20300,0x1310c1c27675a4a7, 0xb4b76665d1d20300,0x1310c1c27675a4a7, - 0x5031f293c3a26100,0x5233f091c1a06302, 0x5031f293c3a26100,0x5233f091c1a06302, - 0x96f69cfc6a0a6000,0x5d3d5737a1c1abcb, 0x96f69cfc6a0a6000,0x5d3d5737a1c1abcb, - 0x87cb105cdb974c00,0x155982ce4905de92, 0x87cb105cdb974c00,0x155982ce4905de92, - 0x8c41ea27ab66cd00,0x569b30fd71bc17da, 0x8c41ea27ab66cd00,0x569b30fd71bc17da, - 0x720bdda4d6af7900,0x30499fe694ed3b42, 0x720bdda4d6af7900,0x30499fe694ed3b42, - 0xf41093778367e400,0xa541c226d236b551, 0xf41093778367e400,0xa541c226d236b551, - 0xf3337cbc4f8fc000,0x12d29d5dae6e21e1, 0xf3337cbc4f8fc000,0x12d29d5dae6e21e1, - 0xf8fa8f8d75770200,0xd2d0a5a75f5d282a, 0xf8fa8f8d75770200,0xd2d0a5a75f5d282a, - 0x548315c29641d700,0x67b026f1a572e433, 0x548315c29641d700,0x67b026f1a572e433, - 0x62974abfdd28f500,0xd326fb0e6c9944b1, 0x62974abfdd28f500,0xd326fb0e6c9944b1, - 0x9b0a54c55ecf9100,0x2fbee071ea7b25b4, 0x9b0a54c55ecf9100,0x2fbee071ea7b25b4, - 0x55e5ad1d48f8b000,0x4cfcb40451e1a919, 0x55e5ad1d48f8b000,0x4cfcb40451e1a919, - 0xc127e90fce28e600,0x8d6ba5438264aa4c, 0xc127e90fce28e600,0x8d6ba5438264aa4c, - 0x47b146b6f107f00,0xeb94fb8480ff90ef, 0x47b146b6f107f00,0xeb94fb8480ff90ef, - 0x4e7b1326685d3500,0xe6d3bb8ec0f59da8, 0x4e7b1326685d3500,0xe6d3bb8ec0f59da8, - 0x7b750c0279770e00,0x737d040a717f0608, 0x7b750c0279770e00,0x737d040a717f0608, - 0x2e18380e20163600,0xcff9d9efc1f7d7e1, 0x2e18380e20163600,0xcff9d9efc1f7d7e1, - 0x4a592b3872611300,0x9784f6e5afbccedd, 0x4a592b3872611300,0x9784f6e5afbccedd, - 0x6344654221062700,0x6c4b6a4d2e09280f, 0x6344654221062700,0x6c4b6a4d2e09280f, - 0x74787874000c0c00,0xf7fbfbf7838f8f83, 0x74787874000c0c00,0xf7fbfbf7838f8f83, - 0xebdb8bbb50603000,0x51613101eada8aba, 0xebdb8bbb50603000,0x51613101eada8aba, - 0x73f75adead298400,0x8400ad295ade73f7, 0x73f75adead298400,0x8400ad295ade73f7, - 0xda3f769349ace500,0x9c7930d50feaa346, 0xda3f769349ace500,0x9c7930d50feaa346, - 0xb59c80a91c352900,0xe8c1ddf44168745d, 0xb59c80a91c352900,0xe8c1ddf44168745d, - 0xda328e66bc54e800,0x38d06c845eb60ae2, 0xda328e66bc54e800,0x38d06c845eb60ae2, - 0x30ab6ff4c45f9b00,0xda41851e2eb571ea, 0x30ab6ff4c45f9b00,0xda41851e2eb571ea, - 0x305a4b21117b6a00,0x600a1b71412b3a50, 0x305a4b21117b6a00,0x600a1b71412b3a50, - 0x2830190129311800,0x425a736b435b726a, 0x2830190129311800,0x425a736b435b726a, - 0x79cafa493083b300,0x843707b4cd7e4efd, 0x79cafa493083b300,0x843707b4cd7e4efd, - 0x586cb185dde93400,0xa7934e7a2216cbff, 0x586cb185dde93400,0xa7934e7a2216cbff, - 0x2b3e8792b9ac1500,0x9c8930250e1ba2b7, 0x2b3e8792b9ac1500,0x9c8930250e1ba2b7, - 0x702ffca3d38c5f00,0x4619ca95e5ba6936, 0x702ffca3d38c5f00,0x4619ca95e5ba6936, - 0xed9c7908e5947100,0x4736d3a24f3edbaa, 0xed9c7908e5947100,0x4736d3a24f3edbaa, - 0x3a34bbb58f810e00,0xbcb23d3309078886, 0x3a34bbb58f810e00,0xbcb23d3309078886, - 0x3b45f688b3cd7e00,0xf6883b457e00b3cd, 0x3b45f688b3cd7e00,0xf6883b457e00b3cd, - 0x1bd675b8a36ecd00,0xc30ead607bb615d8, 0x1bd675b8a36ecd00,0xc30ead607bb615d8, - 0xc1f4deeb2a1f3500,0xc1f4deeb2a1f3500, 0xc1f4deeb2a1f3500,0xc1f4deeb2a1f3500, - 0xda9594db014e4f00,0x1d52531cc68988c7, 0xda9594db014e4f00,0x1d52531cc68988c7, - 0x97aa89b4231e3d00,0x54694a77e0ddfec3, 0x97aa89b4231e3d00,0x54694a77e0ddfec3, - 0x80904c5cdccc1000,0xeafa2636b6a67a6a, 0x80904c5cdccc1000,0xeafa2636b6a67a6a, - 0x22c13eddff1ce300,0xcc2fd03311f20dee, 0x22c13eddff1ce300,0xcc2fd03311f20dee, - 0xe0435bf818bba300,0x63c0d87b9b382083, 0xe0435bf818bba300,0x63c0d87b9b382083, - 0x77d92e80f759ae00,0x8a651ff8826d17f, 0x77d92e80f759ae00,0x8a651ff8826d17f, - 0xa7f0184fe8bf5700,0x4215fdaa0d5ab2e5, 0xa7f0184fe8bf5700,0x4215fdaa0d5ab2e5, - 0x238ff65a79d5ac00,0x76daa30f2c80f955, 0x238ff65a79d5ac00,0x76daa30f2c80f955, - 0xa3943c0ba89f3700,0xba8d2512b1862e19, 0xa3943c0ba89f3700,0xba8d2512b1862e19, - 0x7992a54e37dceb00,0xea0136dda44f7893, 0x7992a54e37dceb00,0xea0136dda44f7893, - 0x205e2e50700e7e00,0x3d43334d6d13631d, 0x205e2e50700e7e00,0x3d43334d6d13631d, - 0xe0ce5a7494ba2e00,0x8ba5311fffd1456b, 0xe0ce5a7494ba2e00,0x8ba5311fffd1456b, - 0x2ece81614fafe000,0x1dfdb2527c9cd333, 0x2ece81614fafe000,0x1dfdb2527c9cd333, - 0xf3f7afab585c0400,0xc2c69e9a696d3531, 0xf3f7afab585c0400,0xc2c69e9a696d3531, - 0x4d73615f122c3e00,0x8fb1a39dd0eefcc2, 0x4d73615f122c3e00,0x8fb1a39dd0eefcc2, - 0x716acfd4a5be1b00,0x5348edf6879c3922, 0x716acfd4a5be1b00,0x5348edf6879c3922, - 0x487d3500487d3500,0xc0f5bd88c0f5bd88, 0x487d3500487d3500,0xc0f5bd88c0f5bd88, - 0xba39c447fd7e8300,0x2dae53d06ae91497, 0xba39c447fd7e8300,0x2dae53d06ae91497, - 0x3ee84197a97fd600,0xd701a87e40963fe9, 0x3ee84197a97fd600,0xd701a87e40963fe9, - 0x98fa482ab2d06200,0x553785e77f1dafcd, 0x98fa482ab2d06200,0x553785e77f1dafcd, - 0xd5ea93ac79463f00,0x81bec7f82d126b54, 0xd5ea93ac79463f00,0x81bec7f82d126b54, - 0x23dfb844679bfc00,0xcf0976b48b4d32f, 0x23dfb844679bfc00,0xcf0976b48b4d32f, - 0xecb6b0ea065c5a00,0x7923257f93c9cf95, 0xecb6b0ea065c5a00,0x7923257f93c9cf95, - 0xa0e6480eaee84600,0xe9af0147e7a10f49, 0xa0e6480eaee84600,0xe9af0147e7a10f49, - 0xa1a2191abbb80300,0xd5d66d6ecfcc7774, 0xa1a2191abbb80300,0xd5d66d6ecfcc7774, - 0x9672a444d236e00,0xd8b6fb959cf2bfd1, 0x9672a444d236e00,0xd8b6fb959cf2bfd1, - 0x20d8a25a7a82f800,0x3fb817959a1db23, 0x20d8a25a7a82f800,0x3fb817959a1db23, - 0x48f6803e76c8be00,0x2e90e65810aed866, 0x48f6803e76c8be00,0x2e90e65810aed866, - 0xffebd3c7382c1400,0x77635b4fb0a49c88, 0xffebd3c7382c1400,0x77635b4fb0a49c88, - 0xfce2d5cb37291e00,0x4957607e829cabb5, 0xfce2d5cb37291e00,0x4957607e829cabb5, - 0xa7ff93cb6c345800,0xa9f19dc5623a560e, 0xa7ff93cb6c345800,0xa9f19dc5623a560e, - 0xb7059c2e992bb200,0x74c65fed5ae871c3, 0xb7059c2e992bb200,0x74c65fed5ae871c3, - 0xa1095ef657ffa800,0x5adfa52f35b0ca4, 0xa1095ef657ffa800,0x5adfa52f35b0ca4, - 0x31d8a34a7b92e900,0xbd542fc6f71e658c, 0x31d8a34a7b92e900,0xbd542fc6f71e658c, - 0x97a6fdcc5b6a3100,0x29184372e5d48fbe, 0x97a6fdcc5b6a3100,0x29184372e5d48fbe, - 0x168869f7e17f9e00,0x801eff6177e90896, 0x168869f7e17f9e00,0x801eff6177e90896, - 0xbbdf7216adc96400,0xcaae0367dcb81571, 0xbbdf7216adc96400,0xcaae0367dcb81571, - 0xa50909a500acac00,0xff5353ff5af6f65a, 0xa50909a500acac00,0xff5353ff5af6f65a, - 0x5ce4ff471ba3b800,0x7bfa41c40f8e35b, 0x5ce4ff471ba3b800,0x7bfa41c40f8e35b, - 0x7531d494e1a5400,0x4d19570304501e4a, 0x7531d494e1a5400,0x4d19570304501e4a, - 0xd97ccf6ab316a500,0xeb4efd5881249732, 0xd97ccf6ab316a500,0xeb4efd5881249732, - 0x47f0f34403b4b700,0xbbcbf084ff8fb4c, 0x47f0f34403b4b700,0xbbcbf084ff8fb4c, - 0x7d77c7cdb0ba0a00,0x7379c9c3beb4040e, 0x7d77c7cdb0ba0a00,0x7379c9c3beb4040e, - 0xd4331bfc28cfe700,0x30d7ff18cc2b03e4, 0xd4331bfc28cfe700,0x30d7ff18cc2b03e4, - 0xf2546fc93b9da600,0xf3556ec83a9ca701, 0xf2546fc93b9da600,0xf3556ec83a9ca701, - 0xfc3cb2728e4ec000,0xea2aa4649858d616, 0xfc3cb2728e4ec000,0xea2aa4649858d616, - 0x1a8882100a989200,0x1f8d87150f9d9705, 0x1a8882100a989200,0x1f8d87150f9d9705, - 0xa2d41365c7b17600,0xb7dbacc6e18dfa9, 0xa2d41365c7b17600,0xb7dbacc6e18dfa9, - 0xa66929e6408fcf00,0xe32c6ca305ca8a45, 0xa66929e6408fcf00,0xe32c6ca305ca8a45, - 0x39a7a739009e9e00,0xbd2323bd841a1a84, 0x39a7a739009e9e00,0xbd2323bd841a1a84, - 0xd20f9f42904ddd00,0xb76afa27f528b865, 0xd20f9f42904ddd00,0xb76afa27f528b865, - 0xd02336c515e6f300,0x5ba8bd4e9e6d788b, 0xd02336c515e6f300,0x5ba8bd4e9e6d788b, - 0x6322632241004100,0x92d392d3b0f1b0f1, 0x6322632241004100,0x92d392d3b0f1b0f1, - 0xcd4035b875f88d00,0xea67129f52dfaa27, 0xcd4035b875f88d00,0xea67129f52dfaa27, - 0xf4f21a1ce8ee0600,0xadab4345b1b75f59, 0xf4f21a1ce8ee0600,0xadab4345b1b75f59, - 0x8d80010c818c0d00,0xb6bb3a37bab7363b, 0x8d80010c818c0d00,0xb6bb3a37bab7363b, - }; - - -} -#endif diff --git a/libOTe/TwoChooseOne/IknpDotExtReceiver.cpp b/libOTe/TwoChooseOne/IknpDotExtReceiver.cpp deleted file mode 100644 index 274a08c1..00000000 --- a/libOTe/TwoChooseOne/IknpDotExtReceiver.cpp +++ /dev/null @@ -1,251 +0,0 @@ -#include "IknpDotExtReceiver.h" -#ifdef ENABLE_DELTA_IKNP -#include "libOTe/Tools/Tools.h" - -#include -#include -#include -#include -#include -#include - -#include "TcoOtDefines.h" -#include - - -namespace osuCrypto -{ - void IknpDotExtReceiver::setBaseOts(gsl::span> baseOTs) - { - mGens.resize(baseOTs.size()); - for (u64 i = 0; i >baseRecvOts(mGens.size()); - - for (u64 i = 0; i < mGens.size(); ++i) - { - baseRecvOts[i][0] = mGens[i][0].get(); - baseRecvOts[i][1] = mGens[i][1].get(); - } - - return IknpDotExtReceiver(baseRecvOts); - } - - std::unique_ptr IknpDotExtReceiver::split() - { - std::vector>baseRecvOts(mGens.size()); - - for (u64 i = 0; i < mGens.size(); ++i) - { - baseRecvOts[i][0] = mGens[i][0].get(); - baseRecvOts[i][1] = mGens[i][1].get(); - } - - return std::make_unique(baseRecvOts); - } - - - void IknpDotExtReceiver::receive( - const BitVector& choices, - gsl::span messages, - PRNG& prng, - Channel& chl) - { - if (hasBaseOts() == false) - genBaseOts(prng, chl); - - setTimePoint("IknpDot.recv.transposeDone"); - - // we are going to process OTs in blocks of 128 * superBlkSize messages. - u64 numOtExt = roundUpTo(choices.size(), 128 * superBlkSize); - u64 numSuperBlocks = numOtExt / 128 / superBlkSize; - u64 numBlocks = numSuperBlocks * superBlkSize; - - // turn the choice vbitVector into an array of blocks. - BitVector choices2(numBlocks * 128); - choices2 = choices; - choices2.resize(numBlocks * 128); - - auto choiceBlocks = choices2.getSpan(); - // this will be used as temporary buffers of 128 columns, - // each containing 1024 bits. Once transposed, they will be copied - // into the T1, T0 buffers for long term storage. - Matrix t0(mGens.size(), superBlkSize * sizeof(block)); - - Matrix messageTemp(messages.size(), sizeof(block) * 2); - auto mIter = messageTemp.begin(); - - - u64 step = std::min(numSuperBlocks, (u64)commStepSize); - std::vector uBuff(step * mGens.size() * superBlkSize); - - // get an array of blocks that we will fill. - auto uIter = (block*)uBuff.data(); - auto uEnd = uIter + uBuff.size(); - - - - // NOTE: We do not transpose a bit-matrix of size numCol * numCol. - // Instead we break it down into smaller chunks. We do 128 columns - // times 8 * 128 rows at a time, where 8 = superBlkSize. This is done for - // performance reasons. The reason for 8 is that most CPUs have 8 AES vector - // lanes, and so its more efficient to encrypt (aka prng) 8 blocks at a time. - // So that's what we do. - for (u64 superBlkIdx = 0; superBlkIdx < numSuperBlocks; ++superBlkIdx) - { - - // the users next 128 choice bits. This will select what message is receiver. - block* cIter = choiceBlocks.data() + superBlkSize * superBlkIdx; - - - - block* tIter = (block*)t0.data(); - memset(t0.data(), 0, superBlkSize * 128 * sizeof(block)); - - - - // transpose 128 columns at at time. Each column will be 128 * superBlkSize = 1024 bits long. - for (u64 colIdx = 0; colIdx < mGens.size(); ++colIdx) - { - // generate the column indexed by colIdx. This is done with - // AES in counter mode acting as a PRNG. We don't use the normal - // PRNG interface because that would result in a data copy when - // we move it into the T0,T1 matrices. Instead we do it directly. - mGens[colIdx][0].mAes.ecbEncCounterMode(mGens[colIdx][0].mBlockIdx, superBlkSize, tIter); - mGens[colIdx][1].mAes.ecbEncCounterMode(mGens[colIdx][1].mBlockIdx, superBlkSize, uIter); - - - // increment the counter mode idx. - mGens[colIdx][0].mBlockIdx += superBlkSize; - mGens[colIdx][1].mBlockIdx += superBlkSize; - - uIter[0] = uIter[0] ^ cIter[0]; - uIter[1] = uIter[1] ^ cIter[1]; - uIter[2] = uIter[2] ^ cIter[2]; - uIter[3] = uIter[3] ^ cIter[3]; - uIter[4] = uIter[4] ^ cIter[4]; - uIter[5] = uIter[5] ^ cIter[5]; - uIter[6] = uIter[6] ^ cIter[6]; - uIter[7] = uIter[7] ^ cIter[7]; - - uIter[0] = uIter[0] ^ tIter[0]; - uIter[1] = uIter[1] ^ tIter[1]; - uIter[2] = uIter[2] ^ tIter[2]; - uIter[3] = uIter[3] ^ tIter[3]; - uIter[4] = uIter[4] ^ tIter[4]; - uIter[5] = uIter[5] ^ tIter[5]; - uIter[6] = uIter[6] ^ tIter[6]; - uIter[7] = uIter[7] ^ tIter[7]; - - uIter += 8; - tIter += 8; - } - - - if (uIter == uEnd) - { - // send over u buffer - chl.asyncSend(std::move(uBuff)); - - u64 step = std::min(numSuperBlocks - superBlkIdx - 1, (u64)commStepSize); - - if (step) - { - uBuff.resize(step * mGens.size() * superBlkSize); - uIter = (block*)uBuff.data(); - uEnd = uIter + uBuff.size(); - } - } - - - - auto mCount = std::min((messageTemp.end() - mIter) / messageTemp.stride(), 128 * superBlkSize); - - MatrixView tOut( - (u8*)&*mIter, - mCount, - messageTemp.stride()); - - mIter += mCount * messageTemp.stride(); - - // transpose our 128 columns of 1024 bits. We will have 1024 rows, - // each 128 bits wide. - transpose(t0, tOut); - } - - - setTimePoint("IknpDot.recv.transposeDone"); - - // do correlation check and hashing - // For the malicious secure OTs, we need a random PRNG that is chosen random - // for both parties. So that is what this is. - PRNG commonPrng; - block theirSeed; - chl.recv((u8*)&theirSeed, sizeof(block)); - - block offset; - chl.recv(offset); - - - setTimePoint("IknpDot.recv.cncSeed"); - - PRNG codePrng(theirSeed); - LinearCode code; - code.random(codePrng, mGens.size(), 128); - - u64 doneIdx = (0); - - std::array zeroOneBlk{ ZeroBlock, AllOneBlock }; - - std::array expendedChoiceBlk; - std::array, 8>& expendedChoice = *reinterpret_cast, 8>*>(&expendedChoiceBlk); - - block mask = block(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); - - //std::cout << IoStream::lock; - - auto msg = (std::array*)messageTemp.data(); - - u64 bb = (messageTemp.bounds()[0] + 127) / 128; - for (u64 blockIdx = 0; blockIdx < bb; ++blockIdx) - { - u64 stop0 = std::min(messages.size(), doneIdx + 128); - - expendedChoiceBlk[0] = mask & choiceBlocks[blockIdx].srai_epi16(0); - expendedChoiceBlk[1] = mask & choiceBlocks[blockIdx].srai_epi16(1); - expendedChoiceBlk[2] = mask & choiceBlocks[blockIdx].srai_epi16(2); - expendedChoiceBlk[3] = mask & choiceBlocks[blockIdx].srai_epi16(3); - expendedChoiceBlk[4] = mask & choiceBlocks[blockIdx].srai_epi16(4); - expendedChoiceBlk[5] = mask & choiceBlocks[blockIdx].srai_epi16(5); - expendedChoiceBlk[6] = mask & choiceBlocks[blockIdx].srai_epi16(6); - expendedChoiceBlk[7] = mask & choiceBlocks[blockIdx].srai_epi16(7); - - u64 i = 0, dd = doneIdx; - for (; dd < stop0; ++dd, ++i) - { - auto maskBlock = zeroOneBlk[expendedChoice[i % 8][i / 8]]; - - code.encode((u8*)msg[dd].data(),(u8*)&messages[dd]); - - messages[dd] = messages[dd] ^ (maskBlock & offset); - } - - doneIdx = stop0; - } - - setTimePoint("IknpDot.recv.done"); - - static_assert(gOtExtBaseOtCount == 128, "expecting 128"); - } - -} -#endif \ No newline at end of file diff --git a/libOTe/TwoChooseOne/IknpDotExtReceiver.h b/libOTe/TwoChooseOne/IknpDotExtReceiver.h deleted file mode 100644 index 96b7d361..00000000 --- a/libOTe/TwoChooseOne/IknpDotExtReceiver.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once -// This file and the associated implementation has been placed in the public domain, waiving all copyright. No restrictions are placed on its use. -#include "libOTe/config.h" -#ifdef ENABLE_DELTA_IKNP - -#include "libOTe/TwoChooseOne/OTExtInterface.h" -#include -#include -#include -#include "libOTe/Tools/LinearCode.h" - -namespace osuCrypto -{ - - class IknpDotExtReceiver : - public OtExtReceiver, public TimerAdapter - { - public: - bool mHasBase = false; - std::vector> mGens; - - IknpDotExtReceiver() = default; - IknpDotExtReceiver(const IknpDotExtReceiver&) = delete; - IknpDotExtReceiver(IknpDotExtReceiver&&) = default; - - IknpDotExtReceiver(span> baseSendOts) - { - setBaseOts(baseSendOts); - } - - void operator=(IknpDotExtReceiver&& v) - { - mHasBase = std::move(v.mHasBase); - mGens = std::move(v.mGens); - v.mHasBase = false; - } - - - // defaults to requiring 40 more base OTs. This gives 40 bits - // of statistical secuirty. - u64 baseOtCount() const override { return gOtExtBaseOtCount + 40; } - - // returns whether the base OTs have been set. They must be set before - // split or receive is called. - bool hasBaseOts() const override - { - return mHasBase; - } - - // sets the base OTs. - void setBaseOts(span> baseSendOts); - - // sets the base OTs. - void setBaseOts( - span> baseSendOts, - PRNG& prng, - Channel& chl)override { - setBaseOts(baseSendOts); - }; - - // returns an independent instance of this extender which can securely be - // used concurrently to this current one. The base OTs for the new instance - // are derived from the orginial base OTs. - IknpDotExtReceiver splitBase(); - - // returns an independent (type eased) instance of this extender which can securely be - // used concurrently to this current one. The base OTs for the new instance - // are derived from the orginial base OTs. - std::unique_ptr split() override; - - // Performed the specicifed number of random OT extensions where the messages - // receivers are indexed by the choices vector that is passed in. The received - // values written to the messages parameter. - void receive( - const BitVector& choices, - span messages, - PRNG& prng, - Channel& chl)override; - - - }; - -} -#endif \ No newline at end of file diff --git a/libOTe/TwoChooseOne/IknpDotExtSender.cpp b/libOTe/TwoChooseOne/IknpDotExtSender.cpp deleted file mode 100644 index 6f899067..00000000 --- a/libOTe/TwoChooseOne/IknpDotExtSender.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include "IknpDotExtSender.h" -#ifdef ENABLE_DELTA_IKNP -#include "libOTe/Tools/Tools.h" -#include -#include -#include -#include -#include "TcoOtDefines.h" - - -namespace osuCrypto -{ - - - IknpDotExtSender IknpDotExtSender::splitBase() - { - std::vector baseRecvOts(mGens.size()); - for (u64 i = 0; i < mGens.size(); ++i) - baseRecvOts[i] = mGens[i].get(); - - return IknpDotExtSender(baseRecvOts, mBaseChoiceBits); - } - - std::unique_ptr IknpDotExtSender::split() - { - std::vector baseRecvOts(mGens.size()); - for (u64 i = 0; i < mGens.size(); ++i) - baseRecvOts[i] = mGens[i].get(); - - return std::make_unique(baseRecvOts, mBaseChoiceBits); - } - - void IknpDotExtSender::setBaseOts(span baseRecvOts, const BitVector & choices) - { - mBaseChoiceBits = choices; - mGens.resize(choices.size()); - mBaseChoiceBits.resize(roundUpTo(mBaseChoiceBits.size(), 8)); - for (u64 i = mBaseChoiceBits.size() - 1; i >= choices.size(); --i) - mBaseChoiceBits[i] = 0; - - mBaseChoiceBits.resize(choices.size()); - for (u64 i = 0; i < mGens.size(); i++) - mGens[i].SetSeed(baseRecvOts[i]); - } - - void IknpDotExtSender::setDelta(const block & delta) - { - mDelta = delta; - } - - void IknpDotExtSender::send( - span> messages, - PRNG& prng, - Channel& chl) - { - setTimePoint("IknpDot.send.transposeDone"); - - // round up - u64 numOtExt = roundUpTo(messages.size(), 128 * superBlkSize); - u64 numSuperBlocks = numOtExt / 128 / superBlkSize; - - // a temp that will be used to transpose the sender's matrix - Matrix t(mGens.size(), superBlkSize * sizeof(block)); - std::vector> u(mGens.size() * commStepSize); - - std::vector choiceMask(mBaseChoiceBits.size()); - std::array delta{ ZeroBlock, ZeroBlock }; - - memcpy(delta.data(), mBaseChoiceBits.data(), mBaseChoiceBits.sizeBytes()); - - - for (u64 i = 0; i < choiceMask.size(); ++i) - { - if (mBaseChoiceBits[i]) choiceMask[i] = AllOneBlock; - else choiceMask[i] = ZeroBlock; - } - - - std::array, 128> extraBlocks; - std::array* xIter = extraBlocks.data(); - - auto mIter = messages.begin(); - auto mIterPartial = messages.end() - std::min(128 * superBlkSize, messages.size()); - - - // set uIter = to the end so that it gets loaded on the first loop. - block * uIter = (block*)u.data() + superBlkSize * mGens.size() * commStepSize; - block * uEnd = uIter; - - for (u64 superBlkIdx = 0; superBlkIdx < numSuperBlocks; ++superBlkIdx) - { - - if (uIter == uEnd) - { - u64 step = std::min(numSuperBlocks - superBlkIdx, (u64)commStepSize); - chl.recv((u8*)u.data(), step * superBlkSize * mGens.size() * sizeof(block)); - uIter = (block*)u.data(); - } - - block * cIter = choiceMask.data(); - block * tIter = (block*)t.data(); - - // transpose 128 columns at at time. Each column will be 128 * superBlkSize = 1024 bits long. - for (u64 colIdx = 0; colIdx < mGens.size(); ++colIdx) - { - // generate the columns using AES-NI in counter mode. - mGens[colIdx].mAes.ecbEncCounterMode(mGens[colIdx].mBlockIdx, superBlkSize, tIter); - mGens[colIdx].mBlockIdx += superBlkSize; - - uIter[0] = uIter[0] & *cIter; - uIter[1] = uIter[1] & *cIter; - uIter[2] = uIter[2] & *cIter; - uIter[3] = uIter[3] & *cIter; - uIter[4] = uIter[4] & *cIter; - uIter[5] = uIter[5] & *cIter; - uIter[6] = uIter[6] & *cIter; - uIter[7] = uIter[7] & *cIter; - - tIter[0] = tIter[0] ^ uIter[0]; - tIter[1] = tIter[1] ^ uIter[1]; - tIter[2] = tIter[2] ^ uIter[2]; - tIter[3] = tIter[3] ^ uIter[3]; - tIter[4] = tIter[4] ^ uIter[4]; - tIter[5] = tIter[5] ^ uIter[5]; - tIter[6] = tIter[6] ^ uIter[6]; - tIter[7] = tIter[7] ^ uIter[7]; - - ++cIter; - uIter += 8; - tIter += 8; - } - - - - if (mIter >= mIterPartial) - { - Matrix tOut(128 * superBlkSize, sizeof(block) * 2); - - // transpose our 128 columns of 1024 bits. We will have 1024 rows, - // each 128 bits wide. - transpose(t, tOut); - - auto mCount = std::min(128 * superBlkSize, messages.end() - mIter); - auto xCount = std::min(128 * superBlkSize - mCount, extraBlocks.data() + extraBlocks.size() - xIter); - - - //std::copy(mIter, mIter + mCount, tOut.begin()); - if(mCount) memcpy(&*mIter, tOut.data(), mCount * sizeof(block) * 2); - mIter += mCount; - - - memcpy(xIter, tOut.data() + mCount * sizeof(block) * 2, xCount * sizeof(block) * 2); - xIter += xCount; - } - else - { - MatrixView tOut( - (u8*)&*mIter, - 128 * superBlkSize, - sizeof(block) * 2); - - mIter += std::min(128 * superBlkSize, messages.end() - mIter); - - // transpose our 128 columns of 1024 bits. We will have 1024 rows, - // each 128 bits wide. - transpose(t, tOut); - } - - } - - setTimePoint("IknpDot.send.transposeDone"); - - block seed = prng.get(); - chl.asyncSend((u8*)&seed, sizeof(block)); - - PRNG codePrng(seed); - LinearCode code; - code.random(codePrng, mBaseChoiceBits.size(), 128); - block curDelta; - code.encode((u8*)delta.data(), (u8*)&curDelta); - - if (eq(mDelta, ZeroBlock)) - mDelta = prng.get(); - - block offset = curDelta ^ mDelta; - chl.asyncSend(offset); - - u64 doneIdx = 0; - - setTimePoint("IknpDot.send.checkStart"); - - - - u64 bb = (messages.size() + 127) / 128; - for (u64 blockIdx = 0; blockIdx < bb; ++blockIdx) - { - - u64 stop0 = std::min(messages.size(), doneIdx + 128); - - u64 i = 0, dd = doneIdx; - for (; dd < stop0; ++dd, ++i) - { - code.encode((u8*)messages[dd].data(), (u8*)&messages[dd][0]); - messages[dd][1] = messages[dd][0] ^ mDelta; - } - - doneIdx = stop0; - } - - setTimePoint("IknpDot.send.done"); - - static_assert(gOtExtBaseOtCount == 128, "expecting 128"); - } - - -} -#endif \ No newline at end of file diff --git a/libOTe/TwoChooseOne/IknpDotExtSender.h b/libOTe/TwoChooseOne/IknpDotExtSender.h deleted file mode 100644 index 931d41ae..00000000 --- a/libOTe/TwoChooseOne/IknpDotExtSender.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once -// This file and the associated implementation has been placed in the public domain, waiving all copyright. No restrictions are placed on its use. - -#include "libOTe/config.h" -#ifdef ENABLE_DELTA_IKNP -#include "libOTe/TwoChooseOne/OTExtInterface.h" -#include -#include -#include -#include "libOTe/Tools/LinearCode.h" -#include - -namespace osuCrypto { - - class IknpDotExtSender : - public OtExtSender, public TimerAdapter - { - public: - block mDelta = ZeroBlock; - std::vector mGens; - BitVector mBaseChoiceBits; - - IknpDotExtSender() = default; - IknpDotExtSender(const IknpDotExtSender&) = delete; - IknpDotExtSender(IknpDotExtSender&&) = default; - - IknpDotExtSender( - span baseRecvOts, - const BitVector& choices) - { - setBaseOts(baseRecvOts, choices); - } - - void operator=(IknpDotExtSender&& v) - { - mGens = std::move(v.mGens); - mBaseChoiceBits = std::move(v.mBaseChoiceBits); - mDelta = v.mDelta; - v.mDelta = ZeroBlock; - } - - // defaults to requiring 40 more base OTs. This gives 40 bits - // of statistical secuirty. - u64 baseOtCount() const override { return gOtExtBaseOtCount + 40; } - - // return true if this instance has valid base OTs. - bool hasBaseOts() const override - { - return mBaseChoiceBits.size() > 0; - } - - - // sets the base OTs. - void setBaseOts( - span baseRecvOts, - const BitVector& choices); - - // sets the base OTs. - void setBaseOts( - span baseRecvOts, - const BitVector& choices, - Channel& chl) override {setBaseOts(baseRecvOts, choices);} - - // Returns a independent instance of this extender which can - // be executed concurrently. The base OTs are derived from the - // original base OTs. - IknpDotExtSender splitBase(); - - // Returns a independent (type eased) instance of this extender which can - // be executed concurrently. The base OTs are derived from the - // original base OTs. - std::unique_ptr split() override; - - // Takes a destination span of two blocks and performs OT extension - // where the destination span is populated (written to) with the random - // OT messages that then extension generates. User data is not transmitted. - void send( - span> messages, - PRNG& prng, - Channel& chl) override; - - // allows the sender to choose the desired difference between the two messaages. If not set - // a random delta is chosen when send(...) is called. - void setDelta(const block& delta); - }; -} - -#endif \ No newline at end of file diff --git a/libOTe/TwoChooseOne/IknpOtExtReceiver.cpp b/libOTe/TwoChooseOne/IknpOtExtReceiver.cpp index 8a7c8858..bbbdcec1 100644 --- a/libOTe/TwoChooseOne/IknpOtExtReceiver.cpp +++ b/libOTe/TwoChooseOne/IknpOtExtReceiver.cpp @@ -18,13 +18,14 @@ namespace osuCrypto if (baseOTs.size() != gOtExtBaseOtCount) throw std::runtime_error(LOCATION); + + mGens.resize(gOtExtBaseOtCount); for (u64 i = 0; i < gOtExtBaseOtCount; i++) { mGens[i][0].SetSeed(baseOTs[i][0]); mGens[i][1].SetSeed(baseOTs[i][1]); } - mHasBase = true; } @@ -197,61 +198,63 @@ namespace osuCrypto //doneIdx = stopIdx; } + if (mHash) + { #ifdef IKNP_SHA_HASH - RandomOracle sha; - u8 hashBuff[20]; + RandomOracle sha; + u8 hashBuff[20]; #else - std::array aesHashTemp; + std::array aesHashTemp; #endif - u64 doneIdx = (0); + u64 doneIdx = (0); - u64 bb = (messages.size() + 127) / 128; - for (u64 blockIdx = 0; blockIdx < bb; ++blockIdx) - { - u64 stop = std::min(messages.size(), doneIdx + 128); + u64 bb = (messages.size() + 127) / 128; + for (u64 blockIdx = 0; blockIdx < bb; ++blockIdx) + { + u64 stop = std::min(messages.size(), doneIdx + 128); #ifdef IKNP_SHA_HASH - for (u64 i = 0; doneIdx < stop; ++doneIdx, ++i) - { - // hash it - sha.Reset(); - sha.Update((u8*)&messages[doneIdx], sizeof(block)); - sha.Final(hashBuff); - messages[doneIdx] = *(block*)hashBuff; - } + for (u64 i = 0; doneIdx < stop; ++doneIdx, ++i) + { + // hash it + sha.Reset(); + sha.Update((u8*)&messages[doneIdx], sizeof(block)); + sha.Final(hashBuff); + messages[doneIdx] = *(block*)hashBuff; + } #else - auto length = stop - doneIdx; - auto steps = length / 8; - block* mIter = messages.data() + doneIdx; - for (u64 i = 0; i < steps; ++i) - { - mAesFixedKey.ecbEncBlocks(mIter, 8, aesHashTemp.data()); - mIter[0] = mIter[0] ^ aesHashTemp[0]; - mIter[1] = mIter[1] ^ aesHashTemp[1]; - mIter[2] = mIter[2] ^ aesHashTemp[2]; - mIter[3] = mIter[3] ^ aesHashTemp[3]; - mIter[4] = mIter[4] ^ aesHashTemp[4]; - mIter[5] = mIter[5] ^ aesHashTemp[5]; - mIter[6] = mIter[6] ^ aesHashTemp[6]; - mIter[7] = mIter[7] ^ aesHashTemp[7]; - - mIter += 8; - } + auto length = stop - doneIdx; + auto steps = length / 8; + block* mIter = messages.data() + doneIdx; + for (u64 i = 0; i < steps; ++i) + { + mAesFixedKey.ecbEncBlocks(mIter, 8, aesHashTemp.data()); + mIter[0] = mIter[0] ^ aesHashTemp[0]; + mIter[1] = mIter[1] ^ aesHashTemp[1]; + mIter[2] = mIter[2] ^ aesHashTemp[2]; + mIter[3] = mIter[3] ^ aesHashTemp[3]; + mIter[4] = mIter[4] ^ aesHashTemp[4]; + mIter[5] = mIter[5] ^ aesHashTemp[5]; + mIter[6] = mIter[6] ^ aesHashTemp[6]; + mIter[7] = mIter[7] ^ aesHashTemp[7]; + + mIter += 8; + } - auto rem = length - steps * 8; - mAesFixedKey.ecbEncBlocks(mIter, rem, aesHashTemp.data()); - for (u64 i = 0; i < rem; ++i) - { - mIter[i] = mIter[i] ^ aesHashTemp[i]; - } + auto rem = length - steps * 8; + mAesFixedKey.ecbEncBlocks(mIter, rem, aesHashTemp.data()); + for (u64 i = 0; i < rem; ++i) + { + mIter[i] = mIter[i] ^ aesHashTemp[i]; + } - doneIdx = stop; + doneIdx = stop; #endif + } } - static_assert(gOtExtBaseOtCount == 128, "expecting 128"); } diff --git a/libOTe/TwoChooseOne/IknpOtExtReceiver.h b/libOTe/TwoChooseOne/IknpOtExtReceiver.h index 1ea1d7b0..9e7f4bd5 100644 --- a/libOTe/TwoChooseOne/IknpOtExtReceiver.h +++ b/libOTe/TwoChooseOne/IknpOtExtReceiver.h @@ -1,6 +1,7 @@ #pragma once // This file and the associated implementation has been placed in the public domain, waiving all copyright. No restrictions are placed on its use. #include "libOTe/config.h" + #ifdef ENABLE_IKNP #include "libOTe/TwoChooseOne/OTExtInterface.h" #include @@ -15,8 +16,8 @@ namespace osuCrypto public OtExtReceiver, public TimerAdapter { public: - bool mHasBase = false; - std::array, gOtExtBaseOtCount> mGens; + bool mHasBase = false, mHash = true; + std::vector> mGens; IknpOtExtReceiver() = default; @@ -28,6 +29,8 @@ namespace osuCrypto setBaseOts(baseSendOts); } + virtual ~IknpOtExtReceiver() = default; + void operator=(IknpOtExtReceiver&& v) { mHasBase = std::move(v.mHasBase); diff --git a/libOTe/TwoChooseOne/IknpOtExtSender.cpp b/libOTe/TwoChooseOne/IknpOtExtSender.cpp index 0bf39f21..2c9d96f0 100644 --- a/libOTe/TwoChooseOne/IknpOtExtSender.cpp +++ b/libOTe/TwoChooseOne/IknpOtExtSender.cpp @@ -40,6 +40,8 @@ namespace osuCrypto if (baseRecvOts.size() != gOtExtBaseOtCount || choices.size() != gOtExtBaseOtCount) throw std::runtime_error("not supported/implemented"); + mGens.resize(gOtExtBaseOtCount); + mBaseChoiceBits = choices; for (u64 i = 0; i < gOtExtBaseOtCount; i++) { @@ -168,71 +170,75 @@ namespace osuCrypto #endif } -#ifdef IKNP_SHA_HASH - RandomOracle sha; - u8 hashBuff[20]; - u64 doneIdx = 0; - - u64 bb = (messages.size() + 127) / 128; - for (u64 blockIdx = 0; blockIdx < bb; ++blockIdx) + if (mHash) { - u64 stop = std::min(messages.size(), doneIdx + 128); - for (u64 i = 0; doneIdx < stop; ++doneIdx, ++i) +#ifdef IKNP_SHA_HASH + RandomOracle sha; + u8 hashBuff[20]; + u64 doneIdx = 0; + + + u64 bb = (messages.size() + 127) / 128; + for (u64 blockIdx = 0; blockIdx < bb; ++blockIdx) { - // hash the message without delta - sha.Reset(); - sha.Update((u8*)&messages[doneIdx][0], sizeof(block)); - sha.Final(hashBuff); - messages[doneIdx][0] = *(block*)hashBuff; - - // hash the message with delta - sha.Reset(); - sha.Update((u8*)&messages[doneIdx][1], sizeof(block)); - sha.Final(hashBuff); - messages[doneIdx][1] = *(block*)hashBuff; + u64 stop = std::min(messages.size(), doneIdx + 128); + + for (u64 i = 0; doneIdx < stop; ++doneIdx, ++i) + { + // hash the message without delta + sha.Reset(); + sha.Update((u8*)&messages[doneIdx][0], sizeof(block)); + sha.Final(hashBuff); + messages[doneIdx][0] = *(block*)hashBuff; + + // hash the message with delta + sha.Reset(); + sha.Update((u8*)&messages[doneIdx][1], sizeof(block)); + sha.Final(hashBuff); + messages[doneIdx][1] = *(block*)hashBuff; + } } - } #else - std::array aesHashTemp; - - u64 doneIdx = 0; - u64 bb = (messages.size() + 127) / 128; - for (u64 blockIdx = 0; blockIdx < bb; ++blockIdx) - { - u64 stop = std::min(messages.size(), doneIdx + 128); + std::array aesHashTemp; - auto length = 2 * (stop - doneIdx); - auto steps = length / 8; - block* mIter = messages[doneIdx].data(); - for (u64 i = 0; i < steps; ++i) + u64 doneIdx = 0; + u64 bb = (messages.size() + 127) / 128; + for (u64 blockIdx = 0; blockIdx < bb; ++blockIdx) { - mAesFixedKey.ecbEncBlocks(mIter, 8, aesHashTemp.data()); - mIter[0] = mIter[0] ^ aesHashTemp[0]; - mIter[1] = mIter[1] ^ aesHashTemp[1]; - mIter[2] = mIter[2] ^ aesHashTemp[2]; - mIter[3] = mIter[3] ^ aesHashTemp[3]; - mIter[4] = mIter[4] ^ aesHashTemp[4]; - mIter[5] = mIter[5] ^ aesHashTemp[5]; - mIter[6] = mIter[6] ^ aesHashTemp[6]; - mIter[7] = mIter[7] ^ aesHashTemp[7]; - - mIter += 8; - } + u64 stop = std::min(messages.size(), doneIdx + 128); - auto rem = length - steps * 8; - mAesFixedKey.ecbEncBlocks(mIter, rem, aesHashTemp.data()); - for (u64 i = 0; i < rem; ++i) - { - mIter[i] = mIter[i] ^ aesHashTemp[i]; - } + auto length = 2 * (stop - doneIdx); + auto steps = length / 8; + block* mIter = messages[doneIdx].data(); + for (u64 i = 0; i < steps; ++i) + { + mAesFixedKey.ecbEncBlocks(mIter, 8, aesHashTemp.data()); + mIter[0] = mIter[0] ^ aesHashTemp[0]; + mIter[1] = mIter[1] ^ aesHashTemp[1]; + mIter[2] = mIter[2] ^ aesHashTemp[2]; + mIter[3] = mIter[3] ^ aesHashTemp[3]; + mIter[4] = mIter[4] ^ aesHashTemp[4]; + mIter[5] = mIter[5] ^ aesHashTemp[5]; + mIter[6] = mIter[6] ^ aesHashTemp[6]; + mIter[7] = mIter[7] ^ aesHashTemp[7]; + + mIter += 8; + } - doneIdx = stop; - } + auto rem = length - steps * 8; + mAesFixedKey.ecbEncBlocks(mIter, rem, aesHashTemp.data()); + for (u64 i = 0; i < rem; ++i) + { + mIter[i] = mIter[i] ^ aesHashTemp[i]; + } + doneIdx = stop; + } + } #endif static_assert(gOtExtBaseOtCount == 128, "expecting 128"); diff --git a/libOTe/TwoChooseOne/IknpOtExtSender.h b/libOTe/TwoChooseOne/IknpOtExtSender.h index 6d74fbc1..d6c2fcee 100644 --- a/libOTe/TwoChooseOne/IknpOtExtSender.h +++ b/libOTe/TwoChooseOne/IknpOtExtSender.h @@ -17,8 +17,9 @@ namespace osuCrypto { public OtExtSender, public TimerAdapter { public: - std::array mGens; + std::vector mGens; BitVector mBaseChoiceBits; + bool mHash = true; IknpOtExtSender() = default; IknpOtExtSender(const IknpOtExtSender&) = delete; @@ -30,6 +31,7 @@ namespace osuCrypto { { setBaseOts(baseRecvOts, choices); } + virtual ~IknpOtExtSender() = default; void operator=(IknpOtExtSender&&v) { diff --git a/libOTe/TwoChooseOne/KosDotExtReceiver.h b/libOTe/TwoChooseOne/KosDotExtReceiver.h index 1e68a5dc..32053694 100644 --- a/libOTe/TwoChooseOne/KosDotExtReceiver.h +++ b/libOTe/TwoChooseOne/KosDotExtReceiver.h @@ -28,6 +28,8 @@ namespace osuCrypto setBaseOts(baseSendOts); } + virtual ~KosDotExtReceiver() = default; + void operator=(KosDotExtReceiver&& v) { mHasBase = std::move(v.mHasBase); diff --git a/libOTe/TwoChooseOne/KosDotExtSender.h b/libOTe/TwoChooseOne/KosDotExtSender.h index a36ff48d..7e4afb22 100644 --- a/libOTe/TwoChooseOne/KosDotExtSender.h +++ b/libOTe/TwoChooseOne/KosDotExtSender.h @@ -29,6 +29,7 @@ namespace osuCrypto { { setBaseOts(baseRecvOts, choices); } + virtual ~KosDotExtSender() = default; void operator=(KosDotExtSender&& v) { diff --git a/libOTe/TwoChooseOne/KosOtExtReceiver.cpp b/libOTe/TwoChooseOne/KosOtExtReceiver.cpp index 8d43dac9..095f63fb 100644 --- a/libOTe/TwoChooseOne/KosOtExtReceiver.cpp +++ b/libOTe/TwoChooseOne/KosOtExtReceiver.cpp @@ -23,6 +23,7 @@ namespace osuCrypto void KosOtExtReceiver::setUniformBaseOts(span> baseOTs) { + mGens.resize(gOtExtBaseOtCount); for (u64 i = 0; i < gOtExtBaseOtCount; i++) { mGens[i][0].SetSeed(baseOTs[i][0]); @@ -41,6 +42,7 @@ namespace osuCrypto chl.asyncSendCopy(rand); BitIterator iter((u8*)&rand, 0); + mGens.resize(gOtExtBaseOtCount); for (u64 i = 0; i < gOtExtBaseOtCount; i++) { mGens[i][0].SetSeed(baseOTs[i][0 ^ *iter]); @@ -94,22 +96,23 @@ namespace osuCrypto genBaseOts(prng, chl); setTimePoint("Kos.recv.start"); - + // we are going to process OTs in blocks of 128 * superBlkSize messages. - u64 numOtExt = roundUpTo(choices.size()+128, 128); - u64 numSuperBlocks = (numOtExt / 128 + superBlkSize-1) / superBlkSize; + u64 numOtExt = roundUpTo(choices.size() + 128, 128); + u64 numSuperBlocks = (numOtExt / 128 + superBlkSize - 1) / superBlkSize; u64 numBlocks = numSuperBlocks * superBlkSize; - -#ifdef OTE_KOS_FIAT_SHAMIR RandomOracle fs(sizeof(block)); -#else - // commit to as seed which will be used to - block seed = prng.get(); - Commit myComm(seed); - chl.asyncSend(myComm.data(), myComm.size()); -#endif + block seed; + + Commit myComm; + if (mFiatShamir == false) + { + seed = prng.get(); + myComm = Commit(seed); + chl.asyncSend(myComm.data(), myComm.size()); + } // turn the choice vbitVector into an array of blocks. BitVector choices2(numBlocks * 128); @@ -191,9 +194,11 @@ namespace osuCrypto if (uIter == uEnd) { -#ifdef OTE_KOS_FIAT_SHAMIR - fs.Update(uBuff.data(), uBuff.size()); -#endif + + if (mFiatShamir) + { + fs.Update(uBuff.data(), uBuff.size()); + } //std::cout << "send u " << std::endl; // send over u buffer @@ -252,44 +257,51 @@ namespace osuCrypto #ifdef KOS_DEBUG chl.send((u8*)extraBlocks.data(), sizeof(block) * 128); BitVector cc; - cc.copy(choices2, choices2.size()-128, 128); + cc.copy(choices2, choices2.size() - 128, 128); chl.send(cc); #endif //std::cout << "uBuff " << (bool)uBuff << " " << (uEnd - uIter) << std::endl; setTimePoint("Kos.recv.transposeDone"); -#ifdef OTE_KOS_FIAT_SHAMIR - block seed; - fs.Final(seed); - PRNG commonPrng(seed); -#else - - // do correlation check and hashing - // For the malicious secure OTs, we need a random PRNG that is chosen random - // for both parties. So that is what this is. - //random_seed_commit(ByteArray(seed), chl, SEED_SIZE, prng.get()); - block theirSeed; - chl.recv((u8*)&theirSeed, sizeof(block)); - chl.asyncSendCopy((u8*)&seed, sizeof(block)); - PRNG commonPrng(seed ^ theirSeed); -#endif + if (mFiatShamir) + { + fs.Final(seed); + } + else + { + block theirSeed; + chl.recv((u8*)&theirSeed, sizeof(block)); + chl.asyncSendCopy((u8*)&seed, sizeof(block)); + seed = seed ^ theirSeed; + } + setTimePoint("Kos.recv.cncSeed"); + + hash(messages, choiceBlocks, chl, seed, extraBlocks); + + } + + void KosOtExtReceiver::hash( + span messages, + span choiceBlocks, + Channel& chl, + block seed, + std::array& extraBlocks) + { + PRNG commonPrng(seed); + // this buffer will be sent to the other party to prove we used the // same value of r in all of the column vectors... - std::vector correlationData(3); + std::vector correlationData(2); block& x = correlationData[0]; block& t = correlationData[1]; - block& t2 = correlationData[2]; + block t2; + //block& t2 = correlationData[2]; x = t = t2 = ZeroBlock; block ti, ti2; -#if (OTE_KOS_HASH == OTE_RANDOM_ORACLE) - RandomOracle sha; - u8 hashBuff[20]; -#elif (OTE_KOS_HASH != OTE_DAVIE_MEYER_AES) -#error "OTE_KOS_HASH" must be defined -#endif + RandomOracle sha(sizeof(block)); u64 doneIdx = (0); //std::cout << IoStream::lock; @@ -320,63 +332,45 @@ namespace osuCrypto for (u64 i = 0, dd = doneIdx; dd < stop; ++dd, ++i) { - - x = x ^ (challenges[i] & zeroOneBlk[expendedChoice[i % 8][i / 8]]); // multiply over polynomial ring to avoid reduction mul128(messages[dd], challenges[i], ti, ti2); - t = t ^ ti; t2 = t2 ^ ti2; -#if (OTE_KOS_HASH == OTE_RANDOM_ORACLE) - // hash it - sha.Reset(); - sha.Update(dd); - sha.Update((u8*)&messages[dd], sizeof(block)); - sha.Final(hashBuff); - messages[dd] = *(block*)hashBuff; -#endif } -#if (OTE_KOS_HASH == OTE_DAVIE_MEYER_AES) - auto& aesHashTemp = expendedChoiceBlk; - auto length = stop - doneIdx; - auto steps = length / 8; - block* mIter = messages.data() + doneIdx; - for (u64 i = 0; i < steps; ++i) + + + if (mHashType == HashType::RandomOracle) { - mAesFixedKey.ecbEncBlocks(mIter, 8, aesHashTemp.data()); - mIter[0] = mIter[0] ^ aesHashTemp[0]; - mIter[1] = mIter[1] ^ aesHashTemp[1]; - mIter[2] = mIter[2] ^ aesHashTemp[2]; - mIter[3] = mIter[3] ^ aesHashTemp[3]; - mIter[4] = mIter[4] ^ aesHashTemp[4]; - mIter[5] = mIter[5] ^ aesHashTemp[5]; - mIter[6] = mIter[6] ^ aesHashTemp[6]; - mIter[7] = mIter[7] ^ aesHashTemp[7]; - - mIter += 8; + for (u64 i = 0, dd = doneIdx; dd < stop; ++dd, ++i) + { + // hash it + sha.Reset(); + sha.Update(dd); + sha.Update((u8*)&messages[dd], sizeof(block)); + sha.Final(messages[dd]); + } } - - auto rem = length - steps * 8; - mAesFixedKey.ecbEncBlocks(mIter, rem, aesHashTemp.data()); - for (u64 i = 0; i < rem; ++i) + else { - mIter[i] = mIter[i] ^ aesHashTemp[i]; + span hh(messages.data() + doneIdx, stop - doneIdx); + mAesFixedKey.hashBlocks(hh, hh); } -#endif doneIdx = stop; } - doneIdx = choices2.size() - 128; + doneIdx = choiceBlocks.size() * 128 - 128; + auto iter = BitIterator((u8*)&choiceBlocks[choiceBlocks.size() - 1]); for (block& blk : extraBlocks) { // and check for correlation block chij = commonPrng.get(); - if (choices2[doneIdx++]) x = x ^ chij; + if (*iter) x = x ^ chij; + ++iter; // multiply over polynomial ring to avoid reduction mul128(blk, chij, ti, ti2); @@ -385,7 +379,7 @@ namespace osuCrypto t2 = t2 ^ ti2; } - + t = t.gf128Reduce(t2); chl.asyncSend(std::move(correlationData)); setTimePoint("Kos.recv.done"); diff --git a/libOTe/TwoChooseOne/KosOtExtReceiver.h b/libOTe/TwoChooseOne/KosOtExtReceiver.h index 9bcc1ad2..af461257 100644 --- a/libOTe/TwoChooseOne/KosOtExtReceiver.h +++ b/libOTe/TwoChooseOne/KosOtExtReceiver.h @@ -16,10 +16,19 @@ namespace osuCrypto { public: bool mHasBase = false; - std::array, gOtExtBaseOtCount> mGens; + std::vector> mGens; struct SetUniformOts {}; + enum class HashType + { + RandomOracle, + AesHash + }; + HashType mHashType = HashType::AesHash; + bool mFiatShamir = false; + + KosOtExtReceiver() = default; KosOtExtReceiver(const KosOtExtReceiver&) = delete; KosOtExtReceiver(KosOtExtReceiver&&) = default; @@ -32,6 +41,8 @@ namespace osuCrypto v.mHasBase = false; } + virtual ~KosOtExtReceiver() = default; + // returns whether the base OTs have been set. They must be set before // split or receive is called. bool hasBaseOts() const override @@ -63,6 +74,9 @@ namespace osuCrypto span messages, PRNG& prng, Channel& chl)override; + + void hash(span messages, span choiceBlocks, Channel& chl, block seed, std::array& extraBlocks); + }; } diff --git a/libOTe/TwoChooseOne/KosOtExtSender.cpp b/libOTe/TwoChooseOne/KosOtExtSender.cpp index 48b2bc08..24996307 100644 --- a/libOTe/TwoChooseOne/KosOtExtSender.cpp +++ b/libOTe/TwoChooseOne/KosOtExtSender.cpp @@ -10,15 +10,16 @@ namespace osuCrypto { - KosOtExtSender::KosOtExtSender(SetUniformOts, span baseRecvOts, const BitVector & choices) + KosOtExtSender::KosOtExtSender(SetUniformOts, span baseRecvOts, const BitVector& choices) { setUniformBaseOts(baseRecvOts, choices); } - void KosOtExtSender::setUniformBaseOts(span baseRecvOts, const BitVector & choices) + void KosOtExtSender::setUniformBaseOts(span baseRecvOts, const BitVector& choices) { mBaseChoiceBits = choices; + mGens.resize(gOtExtBaseOtCount); for (u64 i = 0; i < gOtExtBaseOtCount; i++) { mGens[i].SetSeed(baseRecvOts[i]); @@ -46,7 +47,7 @@ namespace osuCrypto return std::make_unique(SetUniformOts{}, baseRecvOts, mBaseChoiceBits); } - void KosOtExtSender::setBaseOts(span baseRecvOts, const BitVector & choices, Channel& chl) + void KosOtExtSender::setBaseOts(span baseRecvOts, const BitVector& choices, Channel& chl) { if (baseRecvOts.size() != gOtExtBaseOtCount || choices.size() != gOtExtBaseOtCount) throw std::runtime_error("not supported/implemented"); @@ -57,6 +58,7 @@ namespace osuCrypto mBaseChoiceBits = choices; mBaseChoiceBits ^= delta; + mGens.resize(gOtExtBaseOtCount); for (u64 i = 0; i < gOtExtBaseOtCount; i++) { mGens[i].SetSeed(baseRecvOts[i]); @@ -102,19 +104,19 @@ namespace osuCrypto // Our current location of u. // The end iter of u. When uIter == uEnd, we need to // receive the next part of the OT matrix. - block * uIter = (block*)u.data() + superBlkSize * 128 * commStepSize; - block * uEnd = uIter; + block* uIter = (block*)u.data() + superBlkSize * 128 * commStepSize; + block* uEnd = uIter; // The other party either need to commit // to a random value or we will generate // it via Fiat Shamir. -#ifdef OTE_KOS_FIAT_SHAMIR RandomOracle fs(sizeof(block)); -#else + Commit theirSeedComm; - chl.recv(theirSeedComm.data(), theirSeedComm.size()); -#endif + if(mFiatShamir == false) + chl.recv(theirSeedComm.data(), theirSeedComm.size()); + #ifdef KOS_DEBUG auto mStart = mIter; @@ -124,24 +126,24 @@ namespace osuCrypto { // We will generate of the matrix to fill // up t. Then we will transpose t. - block * tIter = (block*)t.data(); + block* tIter = (block*)t.data(); // cIter is the current choice bit, expanded out to be 128 bits. - block * cIter = choiceMask.data(); + block* cIter = choiceMask.data(); // check if we have run out of the u matrix // to consume. If so, receive some more. if (uIter == uEnd) { - u64 step = std::min(numSuperBlocks - superBlkIdx,(u64) commStepSize); + u64 step = std::min(numSuperBlocks - superBlkIdx, (u64)commStepSize); u64 size = step * superBlkSize * 128 * sizeof(block); //std::cout << "recv u " << std::endl; chl.recv((u8*)u.data(), size); uIter = (block*)u.data(); -#ifdef OTE_KOS_FIAT_SHAMIR - fs.Update((u8*)u.data(), size); -#endif + + if (mFiatShamir) + fs.Update((u8*)u.data(), size); } // transpose 128 columns at at time. Each column will be 128 * superBlkSize = 1024 bits long. @@ -180,7 +182,7 @@ namespace osuCrypto //std::array* mStart = mIter; - auto mEnd = mIter + std::min(128 * superBlkSize, messages.end() - mIter); + auto mEnd = mIter + std::min(128 * superBlkSize, messages.end() - mIter); // compute how many rows are unused. //u64 unusedCount = (mIter - mEnd + 128 * superBlkSize); @@ -248,7 +250,7 @@ namespace osuCrypto bool failed = false; for (u64 i = 0; i < 128; ++i) { - if (neq(xtraBlk[i] , choices[i] ? extraBlocks[i] ^ delta : extraBlocks[i] )) + if (neq(xtraBlk[i], choices[i] ? extraBlocks[i] ^ delta : extraBlocks[i])) { std::cout << "extra " << i << std::endl; std::cout << xtraBlk[i] << " " << (u32)choices[i] << std::endl; @@ -257,39 +259,54 @@ namespace osuCrypto failed = true; } } - if(failed) + if (failed) throw std::runtime_error(""); #endif setTimePoint("Kos.send.transposeDone"); -#ifdef OTE_KOS_FIAT_SHAMIR + block seed; - fs.Final(seed); - PRNG commonPrng(seed); -#else - block seed = prng.get(); - chl.asyncSend((u8*)&seed, sizeof(block)); - block theirSeed; - chl.recv((u8*)&theirSeed, sizeof(block)); - setTimePoint("Kos.send.cncSeed"); - if (Commit(theirSeed) != theirSeedComm) - throw std::runtime_error("bad commit " LOCATION); - PRNG commonPrng(seed ^ theirSeed); -#endif + if (mFiatShamir) + { + fs.Final(seed); + } + else + { + seed = prng.get(); + chl.asyncSend((u8*)&seed, sizeof(block)); + block theirSeed; + chl.recv((u8*)&theirSeed, sizeof(block)); + setTimePoint("Kos.send.cncSeed"); + if (Commit(theirSeed) != theirSeedComm) + throw std::runtime_error("bad commit " LOCATION); + seed = seed ^ theirSeed; + //PRNG commonPrng(seed ^ theirSeed); + } + + + hash(messages, chl, seed, extraBlocks, delta); + } + + + void KosOtExtSender::hash( + span> messages, + Channel& chl, + block seed, + std::array& extraBlocks, + block delta) + { + + PRNG commonPrng(seed); block qi, qi2; block q2 = ZeroBlock; block q1 = ZeroBlock; -#if (OTE_KOS_HASH == OTE_RANDOM_ORACLE) RandomOracle sha; u8 hashBuff[20]; -#elif (OTE_KOS_HASH == OTE_DAVIE_MEYER_AES) - std::array aesHashTemp; -#else -#error "OTE_KOS_HASH" must be defined -#endif + + u64 doneIdx = 0; std::array challenges; @@ -300,58 +317,38 @@ namespace osuCrypto { commonPrng.mAes.ecbEncCounterMode(doneIdx, 128, challenges.data()); u64 stop = std::min(messages.size(), doneIdx + 128); - for (u64 i = 0, dd = doneIdx; dd < stop; ++dd, ++i) { - //chii = commonPrng.get(); - //std::cout << "sendIdx' " << dd << " " << messages[dd][0] << " " << chii << std::endl; - mul128(messages[dd][0], challenges[i], qi, qi2); - q1 = q1 ^ qi; + q1 = q1 ^ qi; q2 = q2 ^ qi2; -#if (OTE_KOS_HASH == OTE_RANDOM_ORACLE) - // hash the message without delta - sha.Reset(); - sha.Update(dd); - sha.Update((u8*)&messages[dd][0], sizeof(block)); - sha.Final(hashBuff); - messages[dd][0] = *(block*)hashBuff; - - // hash the message with delta - sha.Reset(); - sha.Update(dd); - sha.Update((u8*)&messages[dd][1], sizeof(block)); - sha.Final(hashBuff); - messages[dd][1] = *(block*)hashBuff; -#endif } -#if (OTE_KOS_HASH == OTE_DAVIE_MEYER_AES) - auto length = 2 *(stop - doneIdx); - auto steps = length / 8; - block* mIter = messages[doneIdx].data(); - for (u64 i = 0; i < steps; ++i) + + if (mHashType == HashType::RandomOracle) { - mAesFixedKey.ecbEncBlocks(mIter, 8, aesHashTemp.data()); - mIter[0] = mIter[0] ^ aesHashTemp[0]; - mIter[1] = mIter[1] ^ aesHashTemp[1]; - mIter[2] = mIter[2] ^ aesHashTemp[2]; - mIter[3] = mIter[3] ^ aesHashTemp[3]; - mIter[4] = mIter[4] ^ aesHashTemp[4]; - mIter[5] = mIter[5] ^ aesHashTemp[5]; - mIter[6] = mIter[6] ^ aesHashTemp[6]; - mIter[7] = mIter[7] ^ aesHashTemp[7]; - - mIter += 8; + for (u64 i = 0, dd = doneIdx; dd < stop; ++dd, ++i) + { + // hash the message without delta + sha.Reset(); + sha.Update(dd); + sha.Update((u8*)&messages[dd][0], sizeof(block)); + sha.Final(hashBuff); + messages[dd][0] = *(block*)hashBuff; + + // hash the message with delta + sha.Reset(); + sha.Update(dd); + sha.Update((u8*)&messages[dd][1], sizeof(block)); + sha.Final(hashBuff); + messages[dd][1] = *(block*)hashBuff; + } } - - auto rem = length - steps * 8; - mAesFixedKey.ecbEncBlocks(mIter, rem, aesHashTemp.data()); - for (u64 i = 0; i < rem; ++i) + else { - mIter[i] = mIter[i] ^ aesHashTemp[i]; + span hh(messages[doneIdx].data(), 2 * (stop - doneIdx)); + mAesFixedKey.hashBlocks(hh, hh); } -#endif doneIdx = stop; } @@ -360,9 +357,8 @@ namespace osuCrypto { block chii = commonPrng.get(); - mul128(blk, chii, qi, qi2); - q1 = q1 ^ qi; + q1 = q1 ^ qi; q2 = q2 ^ qi2; } @@ -371,38 +367,38 @@ namespace osuCrypto //std::cout << IoStream::unlock; - block t1, t2; - std::vector data(sizeof(block) * 3); + std::vector data(sizeof(block) * 2); chl.recv(data.data(), data.size()); setTimePoint("Kos.send.proofReceived"); block& received_x = ((block*)data.data())[0]; block& received_t = ((block*)data.data())[1]; - block& received_t2 = ((block*)data.data())[2]; + //block& received_t2 = ((block*)data.data())[2]; + + auto q = q1.gf128Reduce(q2); // check t = x * Delta + q - mul128(received_x, delta, t1, t2); - t1 = t1 ^ q1; - t2 = t2 ^ q2; + auto t = received_x.gf128Mul(delta) ^ q; - if (eq(t1, received_t) && eq(t2, received_t2)) + if (eq(t, received_t)) { //std::cout << "\tCheck passed\n"; } else { std::cout << "OT Ext Failed Correlation check failed" << std::endl; - std::cout << "rec t = " << received_t << std::endl; - std::cout << "tmp1 = " << t1 << std::endl; - std::cout << "q = " << q1 << std::endl; + //std::cout << "rec t = " << received_t << std::endl; + //std::cout << "tmp1 = " << t1 << std::endl; + //std::cout << "q = " << q1 << std::endl; throw std::runtime_error("Exit");; } setTimePoint("Kos.send.done"); static_assert(gOtExtBaseOtCount == 128, "expecting 128"); - } + } - } +} + #endif diff --git a/libOTe/TwoChooseOne/KosOtExtSender.h b/libOTe/TwoChooseOne/KosOtExtSender.h index c1f1c6fe..e1798f1c 100644 --- a/libOTe/TwoChooseOne/KosOtExtSender.h +++ b/libOTe/TwoChooseOne/KosOtExtSender.h @@ -17,9 +17,18 @@ namespace osuCrypto { struct SetUniformOts {}; - std::array mGens; + std::vector mGens; BitVector mBaseChoiceBits; + enum class HashType + { + RandomOracle, + AesHash + }; + HashType mHashType = HashType::AesHash; + bool mFiatShamir = false; + + KosOtExtSender() = default; KosOtExtSender(const KosOtExtSender&) = delete; KosOtExtSender(KosOtExtSender&&) = default; @@ -29,6 +38,8 @@ namespace osuCrypto { span baseRecvOts, const BitVector& choices); + virtual ~KosOtExtSender() = default; + void operator=(KosOtExtSender&& v) { mGens = std::move(v.mGens); @@ -68,6 +79,10 @@ namespace osuCrypto { span> messages, PRNG& prng, Channel& chl) override; + + + + void hash(span> messages, Channel& chl, block seed, std::array& extraBlocks, block delta); }; } diff --git a/libOTe/TwoChooseOne/OTExtInterface.cpp b/libOTe/TwoChooseOne/OTExtInterface.cpp index 3cca781e..9333ec50 100644 --- a/libOTe/TwoChooseOne/OTExtInterface.cpp +++ b/libOTe/TwoChooseOne/OTExtInterface.cpp @@ -6,36 +6,44 @@ void osuCrypto::OtExtReceiver::genBaseOts(PRNG & prng, Channel & chl) { - #ifdef LIBOTE_HAS_BASE_OT DefaultBaseOT base; + genBaseOts(base, prng, chl); +#else + throw std::runtime_error("The libOTe library does not have base OTs. Enable them to call this. " LOCATION); +#endif +} + +void osuCrypto::OtExtReceiver::genBaseOts(OtSender& base, PRNG& prng, Channel& chl) +{ auto count = baseOtCount(); std::vector> msgs(count); base.send(msgs, prng, chl); - setBaseOts(msgs, prng, chl); -#else - throw std::runtime_error("The libOTe library does not have base OTs. Enable them to call this. " LOCATION); -#endif } void osuCrypto::OtExtSender::genBaseOts(PRNG & prng, Channel & chl) { #ifdef LIBOTE_HAS_BASE_OT DefaultBaseOT base; + genBaseOts(base, prng, chl); +#else + throw std::runtime_error("The libOTe library does not have base OTs. Enable them to call this. " LOCATION); +#endif + +} + +void osuCrypto::OtExtSender::genBaseOts(OtReceiver& base, PRNG& prng, Channel& chl) +{ auto count = baseOtCount(); std::vector msgs(count); BitVector bv(count); bv.randomize(prng); - base.receive(bv, msgs, prng, chl); setBaseOts(msgs, bv, chl); -#else - throw std::runtime_error("The libOTe library does not have base OTs. Enable them to call this. " LOCATION); -#endif - } + void osuCrypto::OtReceiver::receiveChosen( const BitVector & choices, span recvMessages, diff --git a/libOTe/TwoChooseOne/OTExtInterface.h b/libOTe/TwoChooseOne/OTExtInterface.h index b2872ce6..7011c981 100644 --- a/libOTe/TwoChooseOne/OTExtInterface.h +++ b/libOTe/TwoChooseOne/OTExtInterface.h @@ -20,8 +20,8 @@ namespace osuCrypto class OtReceiver { public: - OtReceiver() {} - + OtReceiver() = default; + virtual ~OtReceiver() = default; // Receive random strings indexed by choices. The random strings will be written to // messages. @@ -52,6 +52,7 @@ namespace osuCrypto { public: OtSender() {} + virtual ~OtSender() = default; // send random strings. The random strings will be written to // messages. @@ -85,12 +86,12 @@ namespace osuCrypto }; - + class OtExtSender; class OtExtReceiver : public OtReceiver { public: OtExtReceiver() {} - + // sets the base OTs that are then used to extend virtual void setBaseOts( span> baseSendOts, @@ -109,6 +110,8 @@ namespace osuCrypto // use the default base OT class to generate the // base OTs that are required. virtual void genBaseOts(PRNG& prng, Channel& chl); + + virtual void genBaseOts(OtSender& sender, PRNG& prng, Channel& chl); }; class OtExtSender : public OtSender @@ -134,6 +137,7 @@ namespace osuCrypto // use the default base OT class to generate the // base OTs that are required. virtual void genBaseOts(PRNG& prng, Channel& chl); + virtual void genBaseOts(OtReceiver& recver, PRNG& prng, Channel& chl); }; diff --git a/libOTe/TwoChooseOne/SilentOtExtReceiver.cpp b/libOTe/TwoChooseOne/SilentOtExtReceiver.cpp index 5427fc8a..36353366 100644 --- a/libOTe/TwoChooseOne/SilentOtExtReceiver.cpp +++ b/libOTe/TwoChooseOne/SilentOtExtReceiver.cpp @@ -6,105 +6,58 @@ #include #include #include -#include #include + +#include //#include namespace osuCrypto { - //bool gUseBgicksPprf(true); - //using namespace std; - // Utility function to do modular exponentiation. - // It returns (x^y) % p - u64 power(u64 x, u64 y, u64 p) - { - u64 res = 1; // Initialize result - x = x % p; // Update x if it is more than or - // equal to p - while (y > 0) - { - // If y is odd, multiply x with result - if (y & 1) - res = (res * x) % p; + u64 getPartitions(u64 scaler, u64 p, u64 secParam); - // y must be even now - y = y >> 1; // y = y/2 - x = (x * x) % p; - } - return res; - } - // This function is called for all k trials. It returns - // false if n is composite and returns false if n is - // probably prime. - // d is an odd number such that d*2r = n-1 - // for some r >= 1 - bool millerTest(u64 d, PRNG& prng, u64 n) - { - // Pick a random number in [2..n-2] - // Corner cases make sure that n > 4 - u64 a = 2 + prng.get() % (n - 4); - - // Compute a^d % n - u64 x = power(a, d, n); - - if (x == 1 || x == n - 1) - return true; - - // Keep squaring x while one of the following doesn't - // happen - // (i) d does not reach n-1 - // (ii) (x^2) % n is not 1 - // (iii) (x^2) % n is not n-1 - while (d != n - 1) - { - x = (x * x) % n; - d *= 2; - if (x == 1) return false; - if (x == n - 1) return true; - } + // sets the Iknp base OTs that are then used to extend + void SilentOtExtReceiver::setBaseOts( + span> baseSendOts, + PRNG& prng, + Channel& chl) { - // Return composite - return false; + setBaseOts(baseSendOts); } - // It returns false if n is composite and returns true if n - // is probably prime. k is an input parameter that determines - // accuracy level. Higher value of k indicates more accuracy. - bool isPrime(u64 n, PRNG& prng, u64 k = 20) - { - // Corner cases - if (n <= 1 || n == 4) return false; - if (n <= 3) return true; - - // Find r such that n = 2^d * r + 1 for some r >= 1 - u64 d = n - 1; - while (d % 2 == 0) - d /= 2; - - // Iterate given nber of 'k' times - for (u64 i = 0; i < k; i++) - if (!millerTest(d, prng, n)) - return false; - - return true; + // sets the Iknp base OTs that are then used to extend + void SilentOtExtReceiver::setBaseOts( + span> baseSendOts) { +#ifdef ENABLE_KOS + mKosRecver.setUniformBaseOts(baseSendOts); +#else + throw std::runtime_error("KOS must be enabled"); +#endif } - u64 nextPrime(u64 n) - { - PRNG prng(ZeroBlock); - while (isPrime(n, prng) == false) - ++n; - return n; + // return the number of base OTs IKNP needs + u64 SilentOtExtReceiver::baseOtCount() const { +#ifdef ENABLE_KOS + return mKosRecver.baseOtCount(); +#else + throw std::runtime_error("KOS must be enabled"); +#endif } - u64 getPartitions(u64 scaler, u64 p, u64 secParam); + // returns true if the IKNP base OTs are currently set. + bool SilentOtExtReceiver::hasBaseOts() const { +#ifdef ENABLE_KOS + return mKosRecver.hasBaseOts(); +#else + throw std::runtime_error("IKNP must be enabled"); +#endif + }; - void SilentOtExtReceiver::setSlientBaseOts(span recvBaseOts) + void SilentOtExtReceiver::setSilentBaseOts(span recvBaseOts) { if (isConfigured() == false) throw std::runtime_error("configure(...) must be called first."); @@ -112,8 +65,12 @@ namespace osuCrypto if (static_cast(recvBaseOts.size()) != silentBaseOtCount()) throw std::runtime_error("wrong number of silent base OTs"); - mGen.setBase(recvBaseOts); - mGen.getTransposedPoints(mS); + auto genOts = recvBaseOts.subspan(0, mGen.baseOtCount()); + auto malOts = recvBaseOts.subspan(genOts.size()); + + mGen.setBase(genOts); + std::copy(malOts.begin(), malOts.end(), mMalCheckOts.begin()); + } void SilentOtExtReceiver::genBaseOts( @@ -121,7 +78,52 @@ namespace osuCrypto Channel& chl) { setTimePoint("recver.gen.start"); - mIknpRecver.genBaseOts(prng, chl); +#ifdef ENABLE_KOS + mKosRecver.mFiatShamir = true; + mKosRecver.genBaseOts(prng, chl); +#else + throw std::runtime_error("KOS must be enabled"); +#endif + + } + // Returns an indpendent copy of this extender. + std::unique_ptr SilentOtExtReceiver::split() { + + auto ptr = new SilentOtExtReceiver; + auto ret = std::unique_ptr(ptr); + ptr->mKosRecver = mKosRecver.splitBase(); + return ret; + }; + + + BitVector SilentOtExtReceiver::sampleBaseChoiceBits(PRNG& prng) { + if (isConfigured() == false) + throw std::runtime_error("configure(...) must be called first"); + + auto choice = mGen.sampleChoiceBits(mN2, getPprfFormat(), prng); + + mS.resize(mNumPartitions); + mGen.getPoints(mS, getPprfFormat()); + + if (mMalType == SilentSecType::Malicious) + { + mMalCheckSeed = prng.get(); + mMalCheckX = ZeroBlock; + + for (auto s : mS) + { + auto xs = mMalCheckSeed.gf128Pow(s + 1); + mMalCheckX = mMalCheckX ^ xs; + } + + mMalCheckChoice.resize(0); + mMalCheckChoice.append((u8*)&mMalCheckX, 128); + + mMalCheckOts.resize(128); + choice.append(mMalCheckChoice); + } + + return choice; } @@ -137,115 +139,72 @@ namespace osuCrypto // If we have IKNP base OTs, use them // to extend to get the silent base OTs. - if (mIknpRecver.hasBaseOts()) - { - mIknpRecver.receive(choice, msg, prng, chl); - } - else - { - // otherwise just generate the silent - // base OTs directly. - DefaultBaseOT base; - base.receive(choice, msg, prng, chl, mNumThreads); - setTimePoint("recver.gen.baseOT"); - } - - mGen.setBase(msg); - mGen.getTransposedPoints(mS); - for (u64 i = 0; i < mS.size(); ++i) - { - if (mS[i] >= mN2) - { - for (u64 j = i; j < mS.size(); ++j) - { - std::cout << Color::Red << "bad " << j << " " << mS[j] << " / " << mN2 << std::endl << Color::Default; - std::terminate(); - } - } - } +#if defined(ENABLE_KOS) || defined(LIBOTE_HAS_BASE_OT) + +#ifdef ENABLE_KOS + mKosRecver.mFiatShamir = true; + mKosRecver.receive(choice, msg, prng, chl); +#else + // otherwise just generate the silent + // base OTs directly. + DefaultBaseOT base; + base.receive(choice, msg, prng, chl, mNumThreads); + setTimePoint("recver.gen.baseOT"); +#endif +#else + throw std::runtime_error("IKNP or base OTs must be enabled"); +#endif + setSilentBaseOts(msg); setTimePoint("recver.gen.done"); }; - void SilentOtExtReceiver::genBase( - u64 n, - Channel& chl, - PRNG& prng, - u64 scaler, - u64 secParam, - SilentBaseType basetype, - u64 threads) - { - switch (basetype) - { - //case SilentBaseType::None: - //{ - // std::cout << Color::Red << "warning, insecure " LOCATION << std::endl << Color::Default; - // configure(n, scaler, secParam, threads); - // BitVector choices = sampleBaseChoiceBits(prng); - // std::vector msg(choices.size()); - // //PRNG prngz(ZeroBlock); - // //auto ss = lout << "recver:\n"; - // for (u64 i = 0; i < msg.size(); ++i) - // { - // //std::array tt = prngz.get(); - // msg[i] = toBlock(i, choices[i]); - // // //ss << "msg[" << i << "]["<< int(choices[i])<<"] " - // // // << msg[i] << std::endl; - // } - - // setSlientBaseOts(msg); - // break; - //} - case SilentBaseType::BaseExtend: - // perform 128 normal base OTs - genBaseOts(prng, chl); - case SilentBaseType::Base: - configure(n, scaler, secParam, threads); - // do the silent specific OTs, either by extending - // the exising base OTs or using a base OT protocol. - genSilentBaseOts(prng, chl); - break; - //case SilentBaseType::Extend: - //{ - // std::cout << Color::Red << "warning, insecure " LOCATION << std::endl << Color::Default; - // std::vector> msg(gOtExtBaseOtCount); - // setBaseOts(msg, prng, chl); - // configure(n, scaler, secParam, threads); - // genSilentBaseOts(prng, chl); - // break; - //} - default: - std::cout << "known switch " LOCATION << std::endl; - std::terminate(); - break; - } - } - u64 SilentOtExtReceiver::silentBaseOtCount() const { if (isConfigured() == false) throw std::runtime_error("configure must be called first"); - return mGen.baseOtCount(); + return + mGen.baseOtCount() + + (mMalType == SilentSecType::Malicious) * 128; } + + void QuasiCyclicConfigure( + u64 numOTs, u64 secParam, + u64 scaler, + MultType mMultType, + u64& mRequestedNumOTs, + u64& mNumPartitions, + u64& mSizePer, + u64& mN2, + u64& mN, + u64& mP, + u64& mScaler); + void SilentOtExtReceiver::configure( - u64 n, + u64 numOTs, u64 scaler, - u64 secParam, - u64 numThreads) + u64 numThreads, + SilentSecType malType) { - mP = nextPrime(n); - mN = roundUpTo(mP, 128); - mScaler = scaler; - mN2 = scaler * mN; + mMalType = malType; mNumThreads = numThreads; - auto numPartitions = getPartitions(scaler, mP, secParam); - mS.resize(numPartitions); - mSizePer = (mN2 + numPartitions - 1) / numPartitions; + { + QuasiCyclicConfigure(numOTs, 128, scaler, + mMultType, + mRequestedNumOts, + mNumPartitions, + mSizePer, + mN2, + mN, + mP, + mScaler); + } + + mS.resize(mNumPartitions); mGen.configure(mSizePer, mS.size()); } @@ -279,24 +238,29 @@ namespace osuCrypto // w = r * H - void SilentOtExtReceiver::checkRT(span chls, Matrix& rT1) + void SilentOtExtReceiver::checkRT(Channel& chl, MatrixView rT1) { - if (rT1.rows() != 128) - throw RTE_LOC; Matrix rT2(rT1.rows(), rT1.cols(), AllocType::Uninitialized); - chls[0].recv(rT2.data(), rT2.size()); + chl.recv(rT2.data(), rT2.size()); block delta; - chls[0].recv(delta); + chl.recv(delta); for (u64 i = 0; i < rT1.size(); ++i) rT2(i) = rT2(i) ^ rT1(i); - Matrix R(rT1.cols() * 128, 1); - MatrixView Rv(R); - MatrixView rT2v(rT2); - transpose(rT2v, Rv); + Matrix R; + + { + if (rT1.rows() != 128) + throw RTE_LOC; + + R.resize(rT1.cols() * 128, 1); + MatrixView Rv(R); + MatrixView rT2v(rT2); + transpose(rT2v, Rv); + } Matrix exp(R.rows(), R.cols(), AllocType::Zeroed); for (u64 i = 0; i < mS.size(); ++i) @@ -304,23 +268,23 @@ namespace osuCrypto exp(mS[i]) = delta; } + bool failed = false; for (u64 i = 0; i < R.rows(); ++i) { if (neq(R(i), exp(i))) { std::cout << i << " / " << R.rows() << " R= " << R(i) << " exp= " << exp(i) << std::endl; - throw RTE_LOC; + failed = true; } } + + if (failed) + throw RTE_LOC; + std::cout << "debug check ok" << std::endl; - //for (u64 x = 0; x < rT.rows(); ++x) - //{ - // for (u64 y = 0; y < rT.cols(); ++y) - // { - // std::cout << rT(x, y) << " " << rT2(x, y) << " " << (rT(x,y) ^ rT2(x,y))<< std::endl; - // } - // std::cout << std::endl; - //} + + setTimePoint("recver.expand.checkRT"); + } void SilentOtExtReceiver::receive( @@ -330,7 +294,7 @@ namespace osuCrypto Channel& chl) { BitVector randChoice; - silentReceive(randChoice, messages, prng, { &chl,1 }); + silentReceive(randChoice, messages, prng, chl, OTType::Random); randChoice ^= choices; chl.asyncSend(std::move(randChoice)); } @@ -339,158 +303,288 @@ namespace osuCrypto BitVector& choices, span messages, PRNG& prng, - Channel& chl) + Channel& chl, + OTType type) { - silentReceive(choices, messages, prng, { &chl,1 }); + if (choices.size() != (u64)messages.size()) + throw RTE_LOC; + + auto packing = type == OTType::Random ? + ChoiceBitPacking::True : + ChoiceBitPacking::False; + + silentReceiveInplace(messages.size(), prng, chl, packing); + + if (type == OTType::Random) + { + hash(choices, messages, packing); + } + else + { + std::memcpy(messages.data(), mA.data(), messages.size() * sizeof(block)); + setTimePoint("recver.expand.ldpc.copy"); + + auto cIter = choices.begin(); + for (u64 i = 0; i < choices.size(); ++i) + { + *cIter = mC[i]; + ++cIter; + } + setTimePoint("recver.expand.ldpc.copyBits"); + } + + + clear(); } - void SilentOtExtReceiver::silentReceive( - BitVector& choices, - span messages, + void SilentOtExtReceiver::silentReceiveInplace( + u64 n, PRNG& prng, - span chls) + Channel& chl, + ChoiceBitPacking type) { + + gTimer.setTimePoint("recver.ot.enter"); + if (isConfigured() == false) { // first generate 128 normal base OTs - configure(messages.size(), 2, 128, chls.size()); + configure(n, mScaler, mNumThreads, mMalType); } - if (static_cast(messages.size()) > mN) + if (n != mRequestedNumOts) throw std::invalid_argument("messages.size() > n"); if (mGen.hasBaseOts() == false) { - // make sure we have IKNP base OTs. - if(mIknpRecver.hasBaseOts() == false) - genBaseOts(prng, chls[0]); - - genSilentBaseOts(prng, chls[0]); + // recvs data + genSilentBaseOts(prng, chl); } setTimePoint("recver.expand.start"); + gTimer.setTimePoint("recver.expand.start"); - // column major matrix. mN2 columns and 1 row of 128 bits (128 bit rows) - Matrix rT; - rT.resize(128, mN2 / 128, AllocType::Uninitialized); - - // locally expand the seeds. - mSum = mGen.expand(chls, prng, rT, true, false); - setTimePoint("sender.expand.pprf_transpose"); - if (mDebug) + if (mBackingSize < mN2) { - checkRT(chls, rT); + mBackingSize = mN2; + mBacking.reset(new block[mBackingSize]); } + mA = span(mBacking.get(), mN2); + mC = {}; // do the compression to get the final OTs. - auto type = MultType::QuasiCyclic; - switch (type) + switch (mMultType) { - case MultType::Naive: - randMulNaive(rT, messages); - break; case MultType::QuasiCyclic: - randMulQuasiCyclic(rT, messages, choices, mNumThreads); + { + MatrixView rT(mA.data(), 128, mN2 / 128); + + // locally expand the seeds. + mGen.expand(chl, prng, rT, PprfOutputFormat::InterleavedTransposed, mNumThreads); + setTimePoint("recver.expand.pprf_transpose"); + + if (mDebug) + { + checkRT(chl, rT); + } + + randMulQuasiCyclic(type); + + break; + } default: break; } - clear(); + mA = span(mBacking.get(), mRequestedNumOts); + + if (mC.size()) + { + mC = span(mChoicePtr.get(), mRequestedNumOts); + } } - void SilentOtExtReceiver::randMulNaive(Matrix& rT, span& messages) + void SilentOtExtReceiver::ferretMalCheck(Channel& chl, PRNG& prng) { - std::vector mtxColumn(rT.cols()); - PRNG pubPrng(ZeroBlock); + chl.asyncSendCopy(mMalCheckSeed); + + block xx = mMalCheckSeed; + block sum0 = ZeroBlock; + block sum1 = ZeroBlock; - for (i64 i = 0; i < messages.size(); ++i) + for (u64 i = 0; i < (u64)mA.size(); ++i) { - block& m = messages[i]; - BitIterator iter((u8*)&m, 0); - mulRand(pubPrng, mtxColumn, rT, iter); + 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); } - setTimePoint("recver.expand.mul"); - } + block mySum = sum0.gf128Reduce(sum1); + block deltaShare; + NoisyVoleSender sender; + sender.send(mMalCheckX, { &deltaShare,1 }, prng, mMalCheckOts, chl); - void SilentOtExtReceiver::randMulQuasiCyclic(Matrix& rT, span& messages, BitVector& choices, u64 threads) - { - setTimePoint("recver.expand.QuasiCyclic"); - auto nBlocks = mN / 128; - auto n2Blocks = mN2 / 128; - auto n64 = i64(nBlocks * 2); + std::array theirHash, myHash; + RandomOracle ro(32); + ro.Update(mySum ^ deltaShare); + ro.Final(myHash); - const u64 rows(128); - if (rT.rows() != rows) + chl.recv(theirHash); + + if (theirHash != myHash) throw RTE_LOC; - if (rT.cols() != n2Blocks) + } + + void SilentOtExtReceiver::hash( + BitVector& choices, + span messages, + ChoiceBitPacking type) + { + if (choices.size() != mRequestedNumOts) + throw RTE_LOC; + if ((u64)messages.size() != mRequestedNumOts) throw RTE_LOC; - using namespace bpm; - //std::cout << (a64.data()) << " " << (a.data()) << std::endl; - //u64 * a64ptr = (u64*)a.data(); + auto cIter = choices.begin(); + std::array hashBuffer; - BitVector sb(mN2); - for (u64 i = 0; i < mS.size(); ++i) + auto n8 = mRequestedNumOts / 8 * 8; + auto m = &messages[0]; + auto r = &mA[0]; + + if (type == ChoiceBitPacking::True) { - sb[mS[i]] = 1; - } - //std::vector c(rows); - std::vector a(mScaler - 1); - MatrixcModP1(128, nBlocks, AllocType::Uninitialized); + block mask = OneBlock ^ AllOneBlock; + + for (u64 i = 0; i < n8; i += 8) + { + // mask of the choice bit which is stored in the LSB + m[0] = r[0] & mask; + m[1] = r[1] & mask; + m[2] = r[2] & mask; + m[3] = r[3] & mask; + m[4] = r[4] & mask; + m[5] = r[5] & mask; + m[6] = r[6] & mask; + m[7] = r[7] & mask; + + mAesFixedKey.ecbEnc8Blocks(m, hashBuffer.data()); + m[0] = m[0] ^ hashBuffer[0]; + m[1] = m[1] ^ hashBuffer[1]; + m[2] = m[2] ^ hashBuffer[2]; + m[3] = m[3] ^ hashBuffer[3]; + m[4] = m[4] ^ hashBuffer[4]; + m[5] = m[5] ^ hashBuffer[5]; + m[6] = m[6] ^ hashBuffer[6]; + m[7] = m[7] ^ hashBuffer[7]; + + + // extract the choice bit from the LSB of r + u32 b0 = r[0].testc(OneBlock); + u32 b1 = r[1].testc(OneBlock); + u32 b2 = r[2].testc(OneBlock); + u32 b3 = r[3].testc(OneBlock); + u32 b4 = r[4].testc(OneBlock); + u32 b5 = r[5].testc(OneBlock); + u32 b6 = r[6].testc(OneBlock); + u32 b7 = r[7].testc(OneBlock); + + // pack the choice bits. + choices.data()[i / 8] = + b0 ^ + (b1 << 1) ^ + (b2 << 2) ^ + (b3 << 3) ^ + (b4 << 4) ^ + (b5 << 5) ^ + (b6 << 6) ^ + (b7 << 7); + + m += 8; + r += 8; + } + + cIter = cIter + n8; + for (u64 i = n8; i < (u64)messages.size(); ++i) + { + auto m = &messages[i]; + auto r = &mA[i]; + m[0] = r[0] & mask; + + auto h = mAesFixedKey.ecbEncBlock(m[0]); + m[0] = m[0] ^ h; - if (static_cast(messages.size()) > mN) + *cIter = r[0].testc(OneBlock); + ++cIter; + } + } + else + { + // not implemented. throw RTE_LOC; + } + setTimePoint("recver.expand.ldpc.mCopyHash"); + + } + + void bitShiftXor(span dest, span in, u8 bitShift); + void modp(span dest, span in, u64 p); + + void SilentOtExtReceiver::randMulQuasiCyclic(ChoiceBitPacking packing) + { +#ifdef ENABLE_BITPOLYMUL + setTimePoint("recver.expand.QuasiCyclic"); + const u64 rows(128); + auto nBlocks = mN / rows; + auto n2Blocks = mN2 / rows; + auto n64 = i64(nBlocks * 2); + MatrixView rT(mA.data(), rows, n2Blocks); - choices.resize(mN); + std::vector a(mScaler - 1); + MatrixcModP1(128, nBlocks, AllocType::Uninitialized); std::array brs; for (u64 i = 0; i < brs.size(); ++i) - brs[i].reset(threads); + brs[i].reset(mNumThreads); - //std::vector> counts(threads); - - setTimePoint("recver.expand.QuasiCyclicSetup"); + setTimePoint("recver.expand.qc.Setup"); auto routine = [&](u64 index) { - if (index == 0) - setTimePoint("recver.expand.routine"); + setTimePoint("recver.expand.qc.routine"); - //auto& count = counts[index]; FFTPoly cPoly; FFTPoly bPoly; Matrixtt(1, 2 * nBlocks, AllocType::Uninitialized); - //std::vector temp128(2 * nBlocks); auto temp128 = tt[0]; FFTPoly::DecodeCache cache; - - for (u64 s = index + 1; s < mScaler; s += threads) + for (u64 s = index + 1; s < mScaler; s += mNumThreads) { auto a64 = spanCast(temp128).subspan(n64); PRNG pubPrng(toBlock(s)); - - //pubPrng.mAes.ecbEncCounterMode(0, nBlocks, temp128.data()); pubPrng.get(a64.data(), a64.size()); - //mAesFixedKey.ecbEncCounterMode(s * nBlocks, nBlocks, temp128.data()); + if (index == 0) - setTimePoint("recver.expand.rand"); + setTimePoint("recver.expand.qc.rand"); a[s - 1].encode(a64); } - - brs[0].decrementWait(); if (index == 0) - setTimePoint("recver.expand.randGen"); + setTimePoint("recver.expand.qc.randGen"); auto multAddReduce = [this, nBlocks, n64, &a, &bPoly, &cPoly, &temp128, &cache](span b128, span dest) { @@ -498,7 +592,6 @@ namespace osuCrypto { auto& aPoly = a[s - 1]; auto b64 = spanCast(b128).subspan(s * n64, n64); - bPoly.encode(b64); if (s == 1) @@ -520,73 +613,80 @@ namespace osuCrypto // reduce s[i] mod (x^p - 1) and store it at cModP1[i] modp(dest, temp128, mP); - }; - for (u64 i = index; i < rows + 1; i += threads) + auto stop = packing == ChoiceBitPacking::True ? + rows : + rows + 1; + + for (u64 i = index; i < stop; i += mNumThreads) { - if (i < rows) + + bool computeCVec = + (i == 0 && packing == ChoiceBitPacking::True) || + (i == rows); + + if (computeCVec) { - multAddReduce(rT[i], cModP1[i]); + // the choice vector + BitVector sb(mN2); + for (u64 i = 0; i < mS.size(); ++i) + sb[mS[i]] = 1; + + if (packing == ChoiceBitPacking::True) + { + // make the LSB of mA be the choice bit. + multAddReduce(sb.getSpan(), cModP1[i]); + } + else + { + std::vector c128(nBlocks); + multAddReduce(sb.getSpan(), c128); + + if (mChoiceSpanSize < mRequestedNumOts) + { + mChoiceSpanSize = mRequestedNumOts; + mChoicePtr.reset(new u8[mChoiceSpanSize]); + } + + BitIterator iter((u8*)c128.data()); + mC = span(mChoicePtr.get(), mRequestedNumOts); + for (u64 j = 0; j < mRequestedNumOts; ++j) + { + mC[j] = *iter; + ++iter; + } + } + } else { - span c128 = choices.getSpan(); - multAddReduce(sb.getSpan(), c128); - choices.resize(messages.size()); + multAddReduce(rT[i], cModP1[i]); } } - if (index == 0) - setTimePoint("recver.expand.mulAddReduce"); - + setTimePoint("recver.expand.qc.mulAddReduce"); brs[1].decrementWait(); + // transpose and copy into the mA vector. - - - //MatrixView view(messages.begin(), messages.end(), 1); - //transpose(cModP1, view); - //#define NO_HASH - std::array hashBuffer; - auto numBlocks = messages.size() / 128; - auto begin = index * numBlocks / threads; - auto end = (index + 1) * numBlocks / threads; + auto numBlocks = mRequestedNumOts / 128; + auto begin = index * numBlocks / mNumThreads; + auto end = (index + 1) * numBlocks / mNumThreads; for (u64 i = begin; i < end; ++i) - - //for (u64 i = index; i < numBlocks; i += threads) { u64 j = i * 128; - auto& tpBuffer = *(std::array*)(messages.data() + j); - - //for (u64 j = 0, k = i; j < tpBuffer.size(); ++j, k += cModP1.cols()) - // tpBuffer[j] = cModP1(k); + auto& tpBuffer = *(std::array*)(mA.data() + j); for (u64 k = 0; k < 128; ++k) tpBuffer[k] = cModP1(k, i); transpose128(tpBuffer); - -#ifndef NO_HASH - for (u64 k = 0; k < 128; k += 8) - { - mAesFixedKey.ecbEncBlocks(tpBuffer.data() + k, hashBuffer.size(), hashBuffer.data()); - - tpBuffer[k + 0] = tpBuffer[k + 0] ^ hashBuffer[0]; - tpBuffer[k + 1] = tpBuffer[k + 1] ^ hashBuffer[1]; - tpBuffer[k + 2] = tpBuffer[k + 2] ^ hashBuffer[2]; - tpBuffer[k + 3] = tpBuffer[k + 3] ^ hashBuffer[3]; - tpBuffer[k + 4] = tpBuffer[k + 4] ^ hashBuffer[4]; - tpBuffer[k + 5] = tpBuffer[k + 5] ^ hashBuffer[5]; - tpBuffer[k + 6] = tpBuffer[k + 6] ^ hashBuffer[6]; - tpBuffer[k + 7] = tpBuffer[k + 7] ^ hashBuffer[7]; - } -#endif } - auto rem = messages.size() % 128; + auto rem = mRequestedNumOts % 128; if (rem && index == 0) { std::array tpBuffer; @@ -596,48 +696,47 @@ namespace osuCrypto transpose128(tpBuffer); -#ifndef NO_HASH - for (i64 k = 0; k < rem; ++k) - { - tpBuffer[k] = tpBuffer[k] ^ mAesFixedKey.ecbEncBlock(tpBuffer[k]); - } -#endif - - memcpy(messages.data() + numBlocks * 128, tpBuffer.data(), rem * sizeof(block)); + memcpy(mA.data() + numBlocks * 128, tpBuffer.data(), rem * sizeof(block)); } if (index == 0) - setTimePoint("recver.expand.transposeXor"); - + setTimePoint("recver.expand.qc.transposeXor"); }; - std::vector thrds(threads - 1); + std::vector thrds(mNumThreads - 1); for (u64 i = 0; i < thrds.size(); ++i) thrds[i] = std::thread(routine, i); routine(thrds.size()); - //auto totals = counts.back(); for (u64 i = 0; i < thrds.size(); ++i) - { thrds[i].join(); - //for (u64 j = 0; j < totals.size(); ++j) - //{ +#else - // totals[j] += counts[i][j]; - //} - } - // for (u64 i = 0; i < counts.size(); ++i) - // lout << "count[" << i << "] " << counts[i][0] << " " << counts[i][1] << " " << counts[i][2] << " " << counts[i][3] << std::endl; - - // lout << "total " << totals[0] << " " << totals[1] << " " << totals[2] << " " << totals[3] << std::endl; + std::cout << "bit poly mul is not enabled. Please recompile with ENABLE_BITPOLYMUL defined. " LOCATION << std::endl; + throw RTE_LOC; +#endif } void SilentOtExtReceiver::clear() { mN = 0; + mN2 = 0; + mRequestedNumOts = 0; + mSizePer = 0; + + mC = {}; + mChoicePtr = {}; + mChoiceSpanSize = 0; + + mA = {}; + mBacking = {}; + mBackingSize = {}; + mGen.clear(); + + mS = {}; } diff --git a/libOTe/TwoChooseOne/SilentOtExtReceiver.h b/libOTe/TwoChooseOne/SilentOtExtReceiver.h index 09350b49..bca17305 100644 --- a/libOTe/TwoChooseOne/SilentOtExtReceiver.h +++ b/libOTe/TwoChooseOne/SilentOtExtReceiver.h @@ -8,55 +8,143 @@ #include #include #include -#include +#include +#include +#include namespace osuCrypto { - enum class MultType - { - Naive, - QuasiCyclic - }; + // For more documentation see SilentOtExtSender. class SilentOtExtReceiver : public OtExtReceiver, public TimerAdapter { public: + // The prime for QuasiCycic encoding + u64 mP = 0; + + // the number of OTs being requested. + u64 mRequestedNumOts = 0; + + // The dense vector size, this will be at least as big as mRequestedNumOts. + u64 mN = 0; + + // The sparse vector size, this will be mN * mScaler. + u64 mN2 = 0; + + // The scaling factor that the sparse vector will be compressed by. + u64 mScaler = 2; - u64 mP, mN = 0, mN2, mScaler, mSizePer; + // The size of each regular section of the sparse vector. + u64 mSizePer = 0; + + u64 mNumPartitions = 0; + + // The indices of the noisy locations in the sparse vector. std::vector mS; - block mDelta, mSum; - SilentBaseType mBaseType; - bool mDebug = false; - u64 mNumThreads; - IknpOtExtReceiver mIknpRecver; + + // The A vector in the relation A + B = C * delta + span mA; + + // The C vector in the relation A + B = C * delta + span mC; + + // The number of threads that should be used (when applicable). + u64 mNumThreads = 1; + + // The memory backing mC + std::unique_ptr mChoicePtr; + + // The size of the memory backing mC + u64 mChoiceSpanSize = 0; + + // The memory backing mA + std::unique_ptr mBacking; + + // The size of the memory backing mA + u64 mBackingSize = 0; + +#ifdef ENABLE_KOS + // Kos instance used to generate the base OTs. + KosOtExtReceiver mKosRecver; +#endif + + // The OTs recv msgs which will be used to create the + // secret share of xa * delta as described in ferret. + std::vector mMalCheckOts; + + // The OTs choice bits which will be used to create the + // secret share of xa * delta as described in ferret. + BitVector mMalCheckChoice; + + // The seed used to generate the malicious check coefficients + // for the ferret protocol. + block mMalCheckSeed = ZeroBlock; + + // The summation of the malicious check coefficients which + // correspond to the mS indicces. + block mMalCheckX = ZeroBlock; + + // The ggm tree thats used to generate the sparse vectors. SilentMultiPprfReceiver mGen; - // sets the Iknp base OTs that are then used to extend + // The type of compress we will use to generate the + // dense vectors from the sparse vectors. + MultType mMultType = MultType::QuasiCyclic; + + // The flag which controls whether the malicious check is performed. + SilentSecType mMalType = SilentSecType::SemiHonest; + + // A flag that helps debug + bool mDebug = false; + + virtual ~SilentOtExtReceiver() = default; + + ///////////////////////////////////////////////////// + // The standard OT extension interface + ///////////////////////////////////////////////////// + + // sets the Kos base OTs that are then used to extend void setBaseOts( span> baseSendOts, PRNG& prng, - Channel& chl) override { - mIknpRecver.setBaseOts(baseSendOts, prng, chl); - } + Channel& chl) override; + + // sets the Kos base OTs that are then used to extend + void setBaseOts( + span> baseSendOts); // return the number of base OTs IKNP needs - u64 baseOtCount() const override { - return mIknpRecver.baseOtCount(); - } + u64 baseOtCount() const override; // returns true if the IKNP base OTs are currently set. - bool hasBaseOts() const override { - return mIknpRecver.hasBaseOts(); - }; - - // Returns an indpendent copy of this extender. - virtual std::unique_ptr split() { - throw std::runtime_error("not implemented"); }; + bool hasBaseOts() const override; // Generate the IKNP base OTs void genBaseOts(PRNG& prng, Channel& chl) override; + // Returns an indpendent copy of this extender. + std::unique_ptr split() override; + + + // The default API for OT ext allows the + // caller to choose the choice bits. But + // silent OT picks the choice bits at random. + // To meet the original API we add communication + // and correct the random choice bits to the + // provided ones... Use silentReceive(...) for + // the silent OT API. + void receive( + const BitVector& choices, + span messages, + PRNG& prng, + Channel& chl) override; + + ///////////////////////////////////////////////////// + // The native silent OT extension interface + ///////////////////////////////////////////////////// + + // 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 @@ -67,11 +155,15 @@ namespace osuCrypto // the parameters and figures out how many base OT // will be needed. These can then be ganerated for // a different OT extension or using a base OT protocol. + // @n [in] - the number of OTs. + // @scaler [in] - the compression factor. + // @nThreads [in] - the number of threads. + // @mal [in] - whether the malicious check is performed. void configure( u64 n, u64 scaler = 2, - u64 secParam = 128, - u64 numThreads = 1); + u64 nThreads = 1, + SilentSecType mal = SilentSecType::SemiHonest); // return true if this instance has been configured. bool isConfigured() const { return mN > 0; } @@ -83,66 +175,85 @@ namespace osuCrypto // The silent base OTs must have specially set base OTs. // This returns the choice bits that should be used. // Call this is you want to use a specific base OT protocol - // and then pass the OT messages back using setSlientBaseOts(...). - BitVector sampleBaseChoiceBits(PRNG& prng) { - if (isConfigured() == false) - throw std::runtime_error("configure(...) must be called first"); - return mGen.sampleChoiceBits(mN2, true, prng); - } + // and then pass the OT messages back using setSilentBaseOts(...). + BitVector sampleBaseChoiceBits(PRNG& prng); // Set the externally generated base OTs. This choice // bits must be the one return by sampleBaseChoiceBits(...). - void setSlientBaseOts(span recvBaseOts); - - // An "all-in-one" function that generates the silent - // base OTs under various parameters. - void genBase(u64 n, Channel& chl, PRNG& prng, - u64 scaler = 2, u64 secParam = 80, - SilentBaseType base = SilentBaseType::BaseExtend, - u64 threads = 1); - - // The default API for OT ext allows the - // caller to choose the choice bits. But - // silent OT picks the choice bits at random. - // To meet the original API we add communicatio - // and correct the random choice bits to the - // provided ones... Use silentReceive(...) for - // the silent OT API. - void receive( - const BitVector& choices, - span messages, + void setSilentBaseOts(span recvBaseOts); + + + // Runs the silent OT protocol and outputs c, a. + // If type == OTType::random, then this will generate + // random OTs, where c is a random bit vector + // and a[i] = H(b[i] + c[i] * delta). + // If type ==OTType::Correlated, then + // a[i] = b[i] + c[i] * delta. + // @ c [out] - the random choice bits. + // @ a [out] - the correlated/random ot message. + // @prng [in] - randomness source. + // @chl [in] - the comm channel + // @type [in] - whether random or correlated OTs are produced. + void silentReceive( + BitVector& c, + span a, PRNG& prng, - Channel& chl) override; + Channel& chl, + OTType type = OTType::Random); + + // Runs the silent OT protocol and store the a,c + // vectors internally as mA, mC. Hashing is not applied + // and therefore we have mA + mB = mC * delta. + // If type = ChoiceBitPacking::True, then mC will not + // be generated. Instead the least significant bit of mA + // will hold the choice bits. + // @n [in] - the number of OTs. + // @prng [in] - randomness source. + // @chl [in] - the comm channel + // @type [in] - whether the choice bit should be the lsb. + void silentReceiveInplace( + u64 n, + PRNG& prng, + Channel& chls, + ChoiceBitPacking type = ChoiceBitPacking::False); - // Perform the actual OT extension. If silent - // base OTs have been generated or set, then - // this function is non-interactive. Otherwise - // the silent base OTs will automaticly be performed. - void silentReceive( - BitVector& choices, - span messages, - PRNG & prng, - Channel & chl); - // A parallel version of the other silentReceive(...) - // function. - void silentReceive( + // hash the internal vectors and store the results + // in choices, messages. + void hash( BitVector& choices, - span messages, - PRNG& prng, - span chls); + span messages, + ChoiceBitPacking type); // internal. - void checkRT(span chls, Matrix &rT); - void randMulNaive(Matrix &rT, span &messages); - void randMulQuasiCyclic(Matrix &rT, span &messages, BitVector& choices, u64 threads); - - void clear(); - }; + // Runs the malicious consistency check as described + // by the ferret paper. We only run the batch check and + // not the cuckoo hashing part. + void ferretMalCheck(Channel& chl, PRNG& prng); - //Matrix expandTranspose(BgiEvaluator::MultiKey & gen, u64 n); + // a debugging check on the sparse vector. Insecure to use. + void checkRT(Channel& chl, MatrixView rT); + + // the QuasiCyclic compression routine. + void randMulQuasiCyclic(ChoiceBitPacking packing); + + PprfOutputFormat getPprfFormat() + { + switch (mMultType) + { + case osuCrypto::MultType::QuasiCyclic: + return PprfOutputFormat::InterleavedTransposed; + break; + default: + throw RTE_LOC; + break; + } + } + // clears the internal buffers. + void clear(); + }; inline u8 parity(block b) { @@ -162,77 +273,6 @@ namespace osuCrypto return (bb[0] ^ bb[1]) & 1; } - inline void mulRand(PRNG &pubPrng, span mtxColumn, Matrix &rT, BitIterator iter) - { - pubPrng.get(mtxColumn.data(), mtxColumn.size()); - - //convertCol(mtx, i, mtxColumn); - std::array sum, t; - auto end = (rT.cols() / 8) * 8; - - for (u64 j = 0; j < 128; ++j) - { - auto row = rT[j]; - - sum[0] = sum[0] ^ sum[0]; - sum[1] = sum[1] ^ sum[1]; - sum[2] = sum[2] ^ sum[2]; - sum[3] = sum[3] ^ sum[3]; - sum[4] = sum[4] ^ sum[4]; - sum[5] = sum[5] ^ sum[5]; - sum[6] = sum[6] ^ sum[6]; - sum[7] = sum[7] ^ sum[7]; - - if (true) - { - - for (u64 k = 0; k < end; k += 8) - { - t[0] = row[k + 0] & mtxColumn[k + 0]; - t[1] = row[k + 1] & mtxColumn[k + 1]; - t[2] = row[k + 2] & mtxColumn[k + 2]; - t[3] = row[k + 3] & mtxColumn[k + 3]; - t[4] = row[k + 4] & mtxColumn[k + 4]; - t[5] = row[k + 5] & mtxColumn[k + 5]; - t[6] = row[k + 6] & mtxColumn[k + 6]; - t[7] = row[k + 7] & mtxColumn[k + 7]; - - - sum[0] = sum[0] ^ t[0]; - sum[1] = sum[1] ^ t[1]; - sum[2] = sum[2] ^ t[2]; - sum[3] = sum[3] ^ t[3]; - sum[4] = sum[4] ^ t[4]; - sum[5] = sum[5] ^ t[5]; - sum[6] = sum[6] ^ t[6]; - sum[7] = sum[7] ^ t[7]; - - } - - for (i64 k = end; k < row.size(); ++k) - sum[0] = sum[0] ^ (row[k] & mtxColumn[k]); - - sum[0] = sum[0] ^ sum[1]; - sum[2] = sum[2] ^ sum[3]; - sum[4] = sum[4] ^ sum[5]; - sum[6] = sum[6] ^ sum[7]; - - sum[0] = sum[0] ^ sum[2]; - sum[4] = sum[4] ^ sum[6]; - - sum[0] = sum[0] ^ sum[4]; - } - else - { - for (i64 k = 0; k < row.size(); ++k) - sum[0] = sum[0] ^ (row[k] & mtxColumn[k]); - } - - *iter = parity(sum[0]); - ++iter; - } - } - inline void transpose(span s, MatrixView r) { MatrixView ss((u8*)s.data(), s.size(), sizeof(block)); diff --git a/libOTe/TwoChooseOne/SilentOtExtSender.cpp b/libOTe/TwoChooseOne/SilentOtExtSender.cpp index 88835343..5d868477 100644 --- a/libOTe/TwoChooseOne/SilentOtExtSender.cpp +++ b/libOTe/TwoChooseOne/SilentOtExtSender.cpp @@ -1,4 +1,36 @@ #include "libOTe/TwoChooseOne/SilentOtExtSender.h" + +#if defined(ENABLE_SILENTOT) || defined(ENABLE_SILENT_VOLE) + +namespace osuCrypto +{ + u64 secLevel(u64 scale, u64 p, u64 points) + { + auto x1 = std::log2(scale * p / double(p)); + auto x2 = std::log2(scale * p) / 2; + return static_cast(points * x1 + x2); + } + + u64 getPartitions(u64 scaler, u64 p, u64 secParam) + { + if (scaler < 2) + throw std::runtime_error("scaler must be 2 or greater"); + + u64 ret = 1; + auto ss = secLevel(scaler, p, ret); + while (ss < secParam) + { + ++ret; + ss = secLevel(scaler, p, ret); + if (ret > 1000) + throw std::runtime_error("failed to find silent OT parameters"); + } + return roundUpTo(ret, 8); + } + +} +#endif + #ifdef ENABLE_SILENTOT #include "libOTe/Tools/Tools.h" @@ -9,704 +41,689 @@ #include "libOTe/Base/BaseOT.h" #include #include +#include "libOTe/Vole/NoisyVoleReceiver.h" namespace osuCrypto { - //extern u64 numPartitions; - //extern u64 nScaler; - u64 nextPrime(u64 n); - - u64 secLevel(u64 scale, u64 p, u64 points) - { - auto x1 = std::log2(scale * p / double(p)); - auto x2 = std::log2(scale * p) / 2; - return static_cast(points * x1 + x2); - //return std::log2(std::pow(scale * p / (p - 1.0), points) * (scale * p - points + 1)); - } - u64 getPartitions(u64 scaler, u64 p, u64 secParam) - { - if (scaler < 2) - throw std::runtime_error("scaler must be 2 or greater"); - - u64 ret = 1; - auto ss = secLevel(scaler, p, ret); - while (ss < secParam) - { - ++ret; - ss = secLevel(scaler, p, ret); - if (ret > 1000) - throw std::runtime_error("failed to find silent OT parameters"); - } - return roundUpTo(ret, 8); - } - - u64 SilentOtExtSender::baseOtCount() const - { - return mIknpSender.baseOtCount(); - } - - bool SilentOtExtSender::hasBaseOts() const - { - return mIknpSender.hasBaseOts(); - } - - void SilentOtExtSender::genSilentBaseOts(PRNG& prng, Channel& chl) - { - if (isConfigured() == false) - throw std::runtime_error("configure must be called first"); - - std::vector> msg(silentBaseOtCount()); - - // If we have IKNP base OTs, use them - // to extend to get the silent base OTs. - if (mIknpSender.hasBaseOts()) - { - mIknpSender.send(msg, prng, chl); - } - else - { - // otherwise just generate the silent - // base OTs directly. - DefaultBaseOT base; - base.send(msg, prng, chl, mNumThreads); - setTimePoint("recver.gen.baseOT"); - } - - mGen.setBase(msg); - - - for (u64 i = 0; i < mNumPartitions; ++i) - { - u64 mSi; - do - { - auto si = prng.get() % mSizePer; - mSi = si * mNumPartitions + i; - } while (mSi >= mN2); - } - - setTimePoint("sender.gen.done"); - } - - u64 SilentOtExtSender::silentBaseOtCount() const - { - if (isConfigured() == false) - throw std::runtime_error("configure must be called first"); - - return mGen.baseOtCount(); - } - - void SilentOtExtSender::setSlientBaseOts( - span> sendBaseOts) - { - mGen.setBase(sendBaseOts); - } - - void SilentOtExtSender::genBase( - u64 n, Channel& chl, PRNG& prng, - u64 scaler, u64 secParam, - SilentBaseType basetype, u64 threads ) - { - switch (basetype) - { - //case SilentBaseType::None: - //{ - // std::cout << Color::Red << "warning, insecure " LOCATION << std::endl << Color::Default; - // configure(n, scaler, secParam, threads); - // auto count = silentBaseOtCount(); - // std::vector> msg(count); - // PRNG prngz(ZeroBlock); - // for (u64 i = 0; i < msg.size(); ++i) - // { - // msg[i][0] = toBlock(i, 0); - // msg[i][1] = toBlock(i, 1); - // } - // setSlientBaseOts(msg); - // break; - //} - case SilentBaseType::BaseExtend: - // perform 128 normal base OTs - genBaseOts(prng, chl); - case SilentBaseType::Base: - configure(n, scaler, secParam, threads); - // do the silent specific OTs, either by extending - // the exising base OTs or using a base OT protocol. - genSilentBaseOts(prng, chl); - break; - //case SilentBaseType::Extend: - //{ - // std::cout << Color::Red << "warning, insecure " LOCATION << std::endl << Color::Default; - // std::vector msg(gOtExtBaseOtCount); - // BitVector choice(gOtExtBaseOtCount); - // setBaseOts(msg, choice, chl); - // configure(n, scaler, secParam, threads); - // genSilentBaseOts(prng, chl); - // break; - //} - default: - std::cout << "known switch " LOCATION << std::endl; - std::terminate(); - break; - } - } - - void SilentOtExtSender::configure( - u64 n, u64 scaler, u64 secParam, u64 numThreads) - { - mP = nextPrime(n); - mN = roundUpTo(mP, 128); - mScaler = scaler; - mNumPartitions = getPartitions(scaler, mP, secParam); - mN2 = scaler * mN; - mNumThreads = numThreads; - - mSizePer = (mN2 + mNumPartitions - 1) / mNumPartitions; - - mGen.configure(mSizePer, mNumPartitions); - } - - //sigma = 0 Receiver - // - // u_i is the choice bit - // v_i = w_i + u_i * x - // - // ------------------------ - - // u' = 0000001000000000001000000000100000...00000, u_i = 1 iff i \in S - // - // v' = r + (x . u') = DPF(k0) - // = r + (000000x00000000000x000000000x00000...00000) - // - // u = u' * H bit-vector * H. Mapping n'->n bits - // v = v' * H block-vector * H. Mapping n'->n block - // - //sigma = 1 Sender - // - // x is the delta - // w_i is the zero message - // - // m_i0 = w_i - // m_i1 = w_i + x - // - // ------------------------ - // x - // r = DPF(k1) - // - // w = r * H - - - void SilentOtExtSender::checkRT(span chls, Matrix& rT) + + // sets the IKNP base OTs that are then used to extend + void SilentOtExtSender::setBaseOts( + span baseRecvOts, + const BitVector& choices, + Channel& chl) { - chls[0].send(rT.data(), rT.size()); - chls[0].send(mGen.mValue); + setBaseOts(baseRecvOts, choices); } - void SilentOtExtSender::clear() - { - mN = 0; - mGen.clear(); - } - - void SilentOtExtSender::send( - span> messages, - PRNG& prng, - Channel& chl) - { - silentSend(messages, prng, chl); - BitVector correction(messages.size()); - chl.recv(correction); - auto iter = correction.begin(); - - for (u64 i = 0; i < static_cast(messages.size()); ++i) - { - u8 bit = *iter; ++iter; - auto temp = messages[i][bit]; - messages[i][bit] = messages[i][bit ^ 1]; - messages[i][bit^1] = temp; - } - } - - void SilentOtExtSender::silentSend( - span> messages, - PRNG & prng, - Channel & chl) - { - silentSend(messages, prng, { &chl,1 }); - } + // sets the IKNP base OTs that are then used to extend + void SilentOtExtSender::setBaseOts( + span baseRecvOts, + const BitVector& choices) + { +#ifdef ENABLE_KOS + mKosSender.setUniformBaseOts(baseRecvOts, choices); +#else + throw std::runtime_error("IKNP must be enabled"); +#endif + } - void SilentOtExtSender::silentSend( - span> messages, - PRNG& prng, - span chls) + // Returns an independent copy of this extender. + std::unique_ptr SilentOtExtSender::split() { - if (isConfigured() == false) - { - // first generate 128 normal base OTs - configure(messages.size(), 2, 128, chls.size()); - } + auto ptr = new SilentOtExtSender; + auto ret = std::unique_ptr(ptr); + ptr->mKosSender = mKosSender.splitBase(); + return ret; + } - if (static_cast(messages.size()) > mN) - throw std::invalid_argument("messages.size() > n"); + // use the default base OT class to generate the + // IKNP base OTs that are required. + void SilentOtExtSender::genBaseOts(PRNG& prng, Channel& chl) + { +#ifdef ENABLE_KOS + mKosSender.genBaseOts(prng, chl); +#else + throw std::runtime_error("IKNP must be enabled"); +#endif + } - if (mGen.hasBaseOts() == false) - { - // make sure we have IKNP base OTs. - if (mIknpSender.hasBaseOts() == false) - genBaseOts(prng, chls[0]); - genSilentBaseOts(prng, chls[0]); - } + u64 SilentOtExtSender::baseOtCount() const + { +#ifdef ENABLE_KOS + return mKosSender.baseOtCount(); +#else + throw std::runtime_error("IKNP must be enabled"); +#endif + } - setTimePoint("sender.expand.start"); + bool SilentOtExtSender::hasBaseOts() const + { +#ifdef ENABLE_KOS + return mKosSender.hasBaseOts(); +#else + throw std::runtime_error("IKNP must be enabled"); +#endif + + } + + void SilentOtExtSender::genSilentBaseOts(PRNG& prng, Channel& chl) + { + if (isConfigured() == false) + throw std::runtime_error("configure must be called first"); + + std::vector> msg(silentBaseOtCount()); + + + // If we have IKNP base OTs, use them + // to extend to get the silent base OTs. +#if defined(ENABLE_KOS) || defined(LIBOTE_HAS_BASE_OT) - Matrix rT; - rT.resize(128, mN2 / 128, AllocType::Uninitialized); - - block delta = prng.get(); - mGen.expand(chls, delta, prng, rT, true, false); - setTimePoint("sender.expand.pprf_transpose"); +#ifdef ENABLE_KOS + mKosSender.mFiatShamir = true; + mKosSender.send(msg, prng, chl); +#else + // otherwise just generate the silent + // base OTs directly. + DefaultBaseOT base; + base.send(msg, prng, chl, mNumThreads); + setTimePoint("sender.gen.baseOT"); +#endif +#else + throw std::runtime_error("IKNP or base OTs must be enabled"); +#endif + + setSilentBaseOts(msg); + + setTimePoint("sender.gen.done"); + } + + u64 SilentOtExtSender::silentBaseOtCount() const + { + if (isConfigured() == false) + throw std::runtime_error("configure must be called first"); + auto n = mGen.baseOtCount(); + + if (mMalType == SilentSecType::Malicious) + n += 128; + + return n; + } + + void SilentOtExtSender::setSilentBaseOts( + span> sendBaseOts) + { + + if ((u64)sendBaseOts.size() != silentBaseOtCount()) + throw RTE_LOC; + + auto genOt = sendBaseOts.subspan(0, mGen.baseOtCount()); + auto malOt = sendBaseOts.subspan(genOt.size()); + mMalCheckOts.resize((mMalType == SilentSecType::Malicious) * 128); + + mGen.setBase(genOt); + std::copy(malOt.begin(), malOt.end(), mMalCheckOts.begin()); + } + void QuasiCyclicConfigure( + u64 numOTs, u64 secParam, + u64 scaler, + MultType mMultType, + u64& mRequestedNumOTs, + u64& mNumPartitions, + u64& mSizePer, + u64& mN2, + u64& mN, + u64& mP, + u64& mScaler) + + { + mRequestedNumOTs = numOTs; + mP = nextPrime(std::max(numOTs, 128 * 128)); + mNumPartitions = getPartitions(scaler, mP, secParam); + auto ss = (mP * scaler + mNumPartitions - 1) / mNumPartitions; + mSizePer = roundUpTo(ss, 8); + mN2 = mSizePer * mNumPartitions; + mN = mN2 / scaler; + mScaler = scaler; + } + + void SilentOtExtSender::configure( + u64 numOTs, u64 scaler, u64 numThreads, SilentSecType malType) + { + mMalType = malType; + mNumThreads = numThreads; - if (mDebug) { - checkRT(chls, rT); + QuasiCyclicConfigure(numOTs, 128, scaler, + mMultType, + mRequestNumOts, + mNumPartitions, + mSizePer, + mN2, + mN, + mP, + mScaler); } - auto type = MultType::QuasiCyclic; - switch (type) - { - case MultType::Naive: - randMulNaive(rT, messages); - break; - case MultType::QuasiCyclic: - randMulQuasiCyclic(rT, messages, chls.size()); - break; - default: - break; - } - //randMulNaive(rT, messages); - - clear(); - } - void SilentOtExtSender::randMulNaive(Matrix & rT, span> & messages) - { - - std::vector mtxColumn(rT.cols()); - - PRNG pubPrng(ZeroBlock); - - for (i64 i = 0; i < messages.size(); ++i) - { - block& m0 = messages[i][0]; - block& m1 = messages[i][1]; - - BitIterator iter((u8*)& m0, 0); - - mulRand(pubPrng, mtxColumn, rT, iter); - - m1 = m0 ^ mGen.mValue; - } - - setTimePoint("sender.expand.mul"); - } - //namespace - //{ - // struct format - // { - // BitVector& bv; - // u64 shift; - // format(BitVector& v0, u64 v1) : bv(v0), shift(v1) {} - // }; - - // std::ostream& operator<<(std::ostream& o, format& f) - // { - // auto cur = f.bv.begin(); - // for (u64 i = 0; i < f.bv.size(); ++i, ++cur) - // { - // if (i % 64 == f.shift) - // o << std::flush << Color::Blue; - // if (i % 64 == 0) - // o << std::flush << Color::Default; + mGen.configure(mSizePer, mNumPartitions); + } + + void SilentOtExtSender::checkRT(Channel& chl) + { + chl.asyncSendCopy(mB.data(), mB.size()); + chl.asyncSendCopy(mDelta); + + setTimePoint("sender.expand.checkRT"); - // o << int(*cur) << std::flush; - // } + } - // o << Color::Default; + void SilentOtExtSender::clear() + { + mN = 0; + mN2 = 0; + mRequestNumOts = 0; + mSizePer = 0; + mNumPartitions = 0; + mP = 0; - // return o; - // } - //} + mBacking = {}; + mBackingSize = 0; + mB = {}; - void bitShiftXor(span dest, span in, u8 bitShift) - { + mDelta = block(0,0); + mGen.clear(); + } + void SilentOtExtSender::send( + span> messages, + PRNG& prng, + Channel& chl) + { + silentSend(messages, prng, chl); + BitVector correction(messages.size()); + chl.recv(correction); + auto iter = correction.begin(); - if (bitShift > 127) - throw RTE_LOC; - if (u64(in.data()) % 16) - throw RTE_LOC; - - //BitVector bv0, bv1, inv; - if (bitShift >= 64) - { - bitShift -= 64; - const int bitShift2 = 64 - bitShift; - u8* inPtr = ((u8*)in.data()) + sizeof(u64); - //inv.append((u8*)inPtr, in.size() * 128 - 64); - - auto end = std::min(dest.size(), in.size() - 1); - for (u64 i = 0; i < end; ++i, inPtr += sizeof(block)) - { - block - b0 = toBlock(inPtr), - b1 = toBlock(inPtr + sizeof(u64)); + for (u64 i = 0; i < static_cast(messages.size()); ++i) + { + u8 bit = *iter; ++iter; + auto temp = messages[i][bit]; + messages[i][bit] = messages[i][bit ^ 1]; + messages[i][bit ^ 1] = temp; + } + } - b0 = (b0 >> bitShift); - b1 = (b1 << bitShift2); + void SilentOtExtSender::silentSend( + span> messages, + PRNG& prng, + Channel& chl) + { + silentSendInplace(prng.get(), messages.size(), prng, chl); - //bv0.append((u8*)&b0, 128); - //bv1.append((u8*)&b1, 128); + auto type = ChoiceBitPacking::True; + hash(messages, type); + clear(); + } - dest[i] = dest[i] ^ b0 ^ b1; - } + void SilentOtExtSender::hash( + span> messages, ChoiceBitPacking type) + { + if (type == ChoiceBitPacking::True) + { - if (end != static_cast(dest.size())) - { - u64 b0 = *(u64*)inPtr; - b0 = (b0 >> bitShift); - //bv0.append((u8*)&b0, 64); - //bv1.append((u8*)&b1, 64); + block mask = OneBlock ^ AllOneBlock; + auto d = mDelta & mask; + + auto n8 = (u64)messages.size() / 8 * 8; + block hashBuffer[8]; + + std::array* m = messages.data(); + auto r = mB.data(); + + for (u64 i = 0; i < n8; i += 8) + { + + r[0] = r[0] & mask; + r[1] = r[1] & mask; + r[2] = r[2] & mask; + r[3] = r[3] & mask; + r[4] = r[4] & mask; + r[5] = r[5] & mask; + r[6] = r[6] & mask; + r[7] = r[7] & mask; + + m[0][0] = r[0]; + m[1][0] = r[1]; + m[2][0] = r[2]; + m[3][0] = r[3]; + m[4][0] = r[4]; + m[5][0] = r[5]; + m[6][0] = r[6]; + m[7][0] = r[7]; + + m[0][1] = r[0] ^ d; + m[1][1] = r[1] ^ d; + m[2][1] = r[2] ^ d; + m[3][1] = r[3] ^ d; + m[4][1] = r[4] ^ d; + m[5][1] = r[5] ^ d; + m[6][1] = r[6] ^ d; + m[7][1] = r[7] ^ d; + + auto iter = (block*)m; + mAesFixedKey.ecbEnc8Blocks(iter, hashBuffer); + + iter[0] = iter[0] ^ hashBuffer[0]; + iter[1] = iter[1] ^ hashBuffer[1]; + iter[2] = iter[2] ^ hashBuffer[2]; + iter[3] = iter[3] ^ hashBuffer[3]; + iter[4] = iter[4] ^ hashBuffer[4]; + iter[5] = iter[5] ^ hashBuffer[5]; + iter[6] = iter[6] ^ hashBuffer[6]; + iter[7] = iter[7] ^ hashBuffer[7]; + + iter += 8; + mAesFixedKey.ecbEnc8Blocks(iter, hashBuffer); + + iter[0] = iter[0] ^ hashBuffer[0]; + iter[1] = iter[1] ^ hashBuffer[1]; + iter[2] = iter[2] ^ hashBuffer[2]; + iter[3] = iter[3] ^ hashBuffer[3]; + iter[4] = iter[4] ^ hashBuffer[4]; + iter[5] = iter[5] ^ hashBuffer[5]; + iter[6] = iter[6] ^ hashBuffer[6]; + iter[7] = iter[7] ^ hashBuffer[7]; + + m += 8; + r += 8; + } + for (u64 i = n8; i < (u64)messages.size(); ++i) + { + messages[i][0] = (mB[i]) & mask; + messages[i][1] = (mB[i] ^ d) & mask; + + auto h = mAesFixedKey.ecbEncBlock(messages[i][0]); + messages[i][0] = messages[i][0] ^ h; + h = mAesFixedKey.ecbEncBlock(messages[i][1]); + messages[i][1] = messages[i][1] ^ h; + + } + } + else + { + throw RTE_LOC; + } + setTimePoint("sender.expand.ldpc.mHash"); + } - *(u64*)(&dest[end]) ^= b0; - } - //std::cout << " in " << format(inv, bitShift) << std::endl; - //std::cout << " a0 " << format(bv0, 64 - bitShift) << std::endl; - //std::cout << " a1 " << format(bv1, 64 - bitShift) << std::endl; - } - else if (bitShift) - { - const int bitShift2 = 64 - bitShift; - u8* inPtr = (u8*)in.data(); + void SilentOtExtSender::silentSend( + block d, + span b, + PRNG& prng, + Channel& chl) + { + silentSendInplace(d, b.size(), prng, chl); + + std::memcpy(b.data(), mB.data(), b.size() * sizeof(block)); + setTimePoint("sender.expand.ldpc.copy"); + clear(); + } - auto end = std::min(dest.size(), in.size() - 1); - for (u64 i = 0; i < end; ++i, inPtr += sizeof(block)) - { - block - b0 = toBlock(inPtr), - b1 = toBlock(inPtr + sizeof(u64)); + void SilentOtExtSender::silentSendInplace( + block d, + u64 n, + PRNG& prng, + Channel& chl) + { + gTimer.setTimePoint("sender.ot.enter"); + setTimePoint("sender.expand.enter"); + + if (isConfigured() == false) + { + configure(n, mScaler, mNumThreads, mMalType); + } + + if (n != mRequestNumOts) + throw std::invalid_argument("n != mRequestNumOts " LOCATION); + + if (hasSilentBaseOts() == false) + { + genSilentBaseOts(prng, chl); + } - b0 = (b0 >> bitShift); - b1 = (b1 << bitShift2); + setTimePoint("sender.expand.start"); + gTimer.setTimePoint("sender.expand.start"); - //bv0.append((u8*)&b0, 128); - //bv1.append((u8*)&b1, 128); + mDelta = d; - dest[i] = dest[i] ^ b0 ^ b1; - } + // allocate b + if (mBackingSize < mN2) + { + mBackingSize = mN2; + mBacking.reset(new block[mBackingSize]); + } + mB = span(mBacking.get(), mN2); - if (end != static_cast(dest.size())) - { - block b0 = toBlock(inPtr); - b0 = (b0 >> bitShift); + switch (mMultType) + { + case MultType::QuasiCyclic: + { + MatrixView rT(mB.data(), 128, mN2 / 128); - //bv0.append((u8*)&b0, 128); + mGen.expand(chl, mDelta, prng, rT, PprfOutputFormat::InterleavedTransposed, mNumThreads); + setTimePoint("sender.expand.pprf_transpose"); + gTimer.setTimePoint("sender.expand.pprf_transpose"); - dest[end] = dest[end] ^ b0; + if (mDebug) + checkRT(chl); - u64 b1 = *(u64*)(inPtr + sizeof(u64)); - b1 = (b1 << bitShift2); + randMulQuasiCyclic(); - //bv1.append((u8*)&b1, 64); + break; + } + default: + throw RTE_LOC; + break; + } - *(u64*)& dest[end] ^= b1; - } + mB = span(mBacking.get(), mRequestNumOts); + } + void SilentOtExtSender::ferretMalCheck(Channel& chl, PRNG& prng) + { + block X; + chl.recv(X); - //std::cout << " b0 " << bv0 << std::endl; - //std::cout << " b1 " << bv1 << std::endl; - } - else - { - auto end = std::min(dest.size(), in.size()); - for (u64 i = 0; i < end; ++i) - { - dest[i] = dest[i] ^ in[i]; - } - } - } + 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; + //mySum = mySum ^ xx.gf128Mul(mB[i]); - void modp(span dest, span in, u64 p) - { - auto pBlocks = (p + 127) / 128; - auto pBytes = (p + 7) / 8; + xx = xx.gf128Mul(X); + } - if (static_cast(dest.size()) < pBlocks) - throw RTE_LOC; + block mySum = sum0.gf128Reduce(sum1); + block deltaShare; - if (static_cast(in.size()) < pBlocks) - throw RTE_LOC; + NoisyVoleReceiver recver; + recver.receive({ &mDelta,1 }, { &deltaShare,1 }, prng, mMalCheckOts, chl); - auto count = (in.size() * 128 + p - 1) / p; + std::array myHash; + RandomOracle ro(32); + ro.Update(mySum ^ deltaShare); + ro.Final(myHash); - //BitVector bv; - //bv.append((u8*)in.data(), p); - //std::cout << Color::Green << bv << std::endl << Color::Default; + chl.send(myHash); - memcpy(dest.data(), in.data(), pBytes); + } + void bitShiftXor(span dest, span in, u8 bitShift) + { + if (bitShift > 127) + throw RTE_LOC; + if (u64(in.data()) % 16) + throw RTE_LOC; - for (u64 i = 1; i < count; ++i) - { - auto begin = i * p; - auto end = std::min(i * p + p, in.size() * 128); + if (bitShift >= 64) + { + bitShift -= 64; + const int bitShift2 = 64 - bitShift; + u8* inPtr = ((u8*)in.data()) + sizeof(u64); + + auto end = std::min(dest.size(), in.size() - 1); + for (u64 i = 0; i < end; ++i, inPtr += sizeof(block)) + { + block + b0 = toBlock(inPtr), + b1 = toBlock(inPtr + sizeof(u64)); + + b0 = (b0 >> bitShift); + b1 = (b1 << bitShift2); + + dest[i] = dest[i] ^ b0 ^ b1; + } + + if (end != static_cast(dest.size())) + { + u64 b0 = *(u64*)inPtr; + b0 = (b0 >> bitShift); + + *(u64*)(&dest[end]) ^= b0; + } + } + else if (bitShift) + { + const int bitShift2 = 64 - bitShift; + u8* inPtr = (u8*)in.data(); - auto shift = begin & 127; - auto beginBlock = in.data() + (begin / 128); - auto endBlock = in.data() + ((end + 127) / 128); + auto end = std::min(dest.size(), in.size() - 1); + for (u64 i = 0; i < end; ++i, inPtr += sizeof(block)) + { + block + b0 = toBlock(inPtr), + b1 = toBlock(inPtr + sizeof(u64)); - if (endBlock > in.data() + in.size()) - throw RTE_LOC; + b0 = (b0 >> bitShift); + b1 = (b1 << bitShift2); + //bv0.append((u8*)&b0, 128); + //bv1.append((u8*)&b1, 128); - auto in_i = span(beginBlock, endBlock); + dest[i] = dest[i] ^ b0 ^ b1; + } - bitShiftXor(dest, in_i, static_cast(shift)); + if (end != static_cast(dest.size())) + { + block b0 = toBlock(inPtr); + b0 = (b0 >> bitShift); - //bv.resize(0); - //bv.append((u8*)dest.data(), p); - //std::cout << Color::Green << bv << std::endl << Color::Default; - } + //bv0.append((u8*)&b0, 128); + dest[end] = dest[end] ^ b0; - auto offset = (p & 7); - if (offset) - { - u8 mask = (1 << offset) - 1; - auto idx = p / 8; - ((u8*)dest.data())[idx] &= mask; - } + u64 b1 = *(u64*)(inPtr + sizeof(u64)); + b1 = (b1 << bitShift2); - auto rem = dest.size() * 16 - pBytes; - if (rem) - memset(((u8*)dest.data()) + pBytes, 0, rem); - } - + //bv1.append((u8*)&b1, 64); + *(u64*)&dest[end] ^= b1; + } - void SilentOtExtSender::randMulQuasiCyclic(Matrix & rT, span> & messages, u64 threads) - { - auto nBlocks = mN / 128; - auto n2Blocks = mN2 / 128; - auto n64 = i64(nBlocks * 2); + //std::cout << " b0 " << bv0 << std::endl; + //std::cout << " b1 " << bv1 << std::endl; + } + else + { + auto end = std::min(dest.size(), in.size()); + for (u64 i = 0; i < end; ++i) + { + dest[i] = dest[i] ^ in[i]; + } + } + } - const u64 rows(128); - if (rT.rows() != rows) - throw RTE_LOC; + void modp(span dest, span in, u64 p) + { + auto pBlocks = (p + 127) / 128; + auto pBytes = (p + 7) / 8; - if (rT.cols() != n2Blocks) - throw RTE_LOC; + if (static_cast(dest.size()) < pBlocks) + throw RTE_LOC; + if (static_cast(in.size()) < pBlocks) + throw RTE_LOC; - using namespace bpm; - //std::vector a(nBlocks); - //span a64 = spanCast(a); + auto count = (in.size() * 128 + p - 1) / p; - std::vector a(mScaler-1); - MatrixcModP1(128, nBlocks, AllocType::Uninitialized); + memcpy(dest.data(), in.data(), pBytes); - std::unique_ptr brs(new ThreadBarrier[mScaler]); - for (u64 i = 0; i < mScaler; ++i) - brs[i].reset(threads); + for (u64 i = 1; i < count; ++i) + { + auto begin = i * p; + auto end = std::min(i * p + p, in.size() * 128); -#ifdef DEBUG - Matrix cc(mScaler, rows); -#endif - auto routine = [&](u64 index) - { - u64 j = 0; - FFTPoly bPoly; - FFTPoly cPoly; + auto shift = begin & 127; + auto beginBlock = in.data() + (begin / 128); + auto endBlock = in.data() + ((end + 127) / 128); - Matrixtt(1, 2 * nBlocks, AllocType::Uninitialized); - auto temp128 = tt[0]; - FFTPoly::DecodeCache cache; + if (endBlock > in.data() + in.size()) + throw RTE_LOC; - for (u64 s = index + 1; s < mScaler; s += threads) - { - auto a64 = spanCast(temp128).subspan(n64); - //mAesFixedKey.ecbEncCounterMode(s * nBlocks, nBlocks, temp128.data()); + auto in_i = span(beginBlock, endBlock); - PRNG pubPrng(toBlock(s)); - //pubPrng.mAes.ecbEncCounterMode(0, nBlocks, temp128.data()); - pubPrng.get(a64.data(), a64.size()); - a[s - 1].encode(a64); - } + bitShiftXor(dest, in_i, static_cast(shift)); + } - if (index == 0) - setTimePoint("recver.expand.randGen"); - brs[j++].decrementWait(); + auto offset = (p & 7); + if (offset) + { + u8 mask = (1 << offset) - 1; + auto idx = p / 8; + ((u8*)dest.data())[idx] &= mask; + } - if (index == 0) - setTimePoint("recver.expand.randGenWait"); + auto rem = dest.size() * 16 - pBytes; + if (rem) + memset(((u8*)dest.data()) + pBytes, 0, rem); + } + void SilentOtExtSender::randMulQuasiCyclic() + { +#ifdef ENABLE_BITPOLYMUL + const u64 rows(128); + auto nBlocks = mN / rows; + auto n2Blocks = mN2 / rows; + MatrixView rT(mB.data(), rows, n2Blocks); + auto n64 = i64(nBlocks * 2); + std::vector a(mScaler - 1); + MatrixcModP1(128, nBlocks, AllocType::Uninitialized); - auto multAddReduce = [this, nBlocks, n64, &a, &bPoly, &cPoly, &temp128, &cache](span b128, span dest) - { - for (u64 s = 1; s < mScaler; ++s) - { - auto& aPoly = a[s - 1]; - auto b64 = spanCast(b128).subspan(s * n64, n64); + std::unique_ptr brs(new ThreadBarrier[mScaler]); + for (u64 i = 0; i < mScaler; ++i) + brs[i].reset(mNumThreads); - bPoly.encode(b64); + auto routine = [&](u64 index) + { + u64 j = 0; + FFTPoly bPoly; + FFTPoly cPoly; - if (s == 1) - { - cPoly.mult(aPoly, bPoly); - } - else - { - bPoly.multEq(aPoly); - cPoly.addEq(bPoly); - } - } + Matrixtt(1, 2 * nBlocks, AllocType::Uninitialized); + auto temp128 = tt[0]; - // decode c[i] and store it at t64Ptr - cPoly.decode(spanCast(temp128), cache, true); + FFTPoly::DecodeCache cache; + for (u64 s = index + 1; s < mScaler; s += mNumThreads) + { + auto a64 = spanCast(temp128).subspan(n64); + PRNG pubPrng(toBlock(s)); + pubPrng.get(a64.data(), a64.size()); + a[s - 1].encode(a64); + } - for (u64 j = 0; j < nBlocks; ++j) - temp128[j] = temp128[j] ^ b128[j]; + if (index == 0) + setTimePoint("sender.expand.qc.randGen"); - // reduce s[i] mod (x^p - 1) and store it at cModP1[i] - modp(dest, temp128, mP); + brs[j++].decrementWait(); - }; + if (index == 0) + setTimePoint("sender.expand.qc.randGenWait"); - for (u64 i = index; i < rows; i += threads) - { - multAddReduce(rT[i], cModP1[i]); - } + auto multAddReduce = [this, nBlocks, n64, &a, &bPoly, &cPoly, &temp128, &cache](span b128, span dest) + { + for (u64 s = 1; s < mScaler; ++s) + { + auto& aPoly = a[s - 1]; + auto b64 = spanCast(b128).subspan(s * n64, n64); + bPoly.encode(b64); - if (index == 0) - setTimePoint("sender.expand.mulAddReduce"); + if (s == 1) + { + cPoly.mult(aPoly, bPoly); + } + else + { + bPoly.multEq(aPoly); + cPoly.addEq(bPoly); + } + } - brs[j++].decrementWait(); + // decode c[i] and store it at t64Ptr + cPoly.decode(spanCast(temp128), cache, true); -#ifdef DEBUG - if (index == 0) - { - RandomOracle ro(16); - ro.Update(cc.data(), cc.size()); - block b; - ro.Final(b); - std::cout << "cc " << b << std::endl; - } -#endif + for (u64 j = 0; j < nBlocks; ++j) + temp128[j] = temp128[j] ^ b128[j]; - std::array hashBuffer; - std::array tpBuffer; - auto numBlocks = (messages.size() + 127) / 128; - auto begin = index * numBlocks / threads; - auto end = (index + 1) * numBlocks / threads; - for (u64 i = begin; i < end; ++i) - //for (u64 i = index; i < numBlocks; i += threads) - { - u64 j = i * tpBuffer.size(); + // reduce s[i] mod (x^p - 1) and store it at cModP1[i] + modp(dest, temp128, mP); - auto min = std::min(tpBuffer.size(), messages.size() - j); + }; - for (u64 j = 0; j < tpBuffer.size(); ++j) - tpBuffer[j] = cModP1(j, i); + for (u64 i = index; i < rows; i += mNumThreads) + multAddReduce(rT[i], cModP1[i]); - //for (u64 j = 0, k = i; j < tpBuffer.size(); ++j, k += cModP1.cols()) - // tpBuffer[j] = cModP1(k); + if (index == 0) + setTimePoint("sender.expand.qc.mulAddReduce"); - transpose128(tpBuffer); + brs[j++].decrementWait(); - //#define NO_HASH + std::array tpBuffer; + auto numBlocks = (mRequestNumOts + 127) / 128; + auto begin = index * numBlocks / mNumThreads; + auto end = (index + 1) * numBlocks / mNumThreads; + for (u64 i = begin; i < end; ++i) + { + u64 j = i * tpBuffer.size(); + auto min = std::min(tpBuffer.size(), mN - j); + for (u64 k = 0; k < tpBuffer.size(); ++k) + tpBuffer[k] = cModP1(k, i); -#ifdef NO_HASH - auto end = i * tpBuffer.size() + min; - for (u64 k = 0; j < end; ++j, ++k) - { - messages[j][0] = tpBuffer[k]; - messages[j][1] = tpBuffer[k] ^ mGen.mValue; - } -#else - u64 k = 0; - auto min2 = min & ~7; - for (; k < min2; k += 8) - { - mAesFixedKey.ecbEncBlocks(tpBuffer.data() + k, hashBuffer.size(), hashBuffer.data()); - - messages[j + k + 0][0] = tpBuffer[k + 0] ^ hashBuffer[0]; - messages[j + k + 1][0] = tpBuffer[k + 1] ^ hashBuffer[1]; - messages[j + k + 2][0] = tpBuffer[k + 2] ^ hashBuffer[2]; - messages[j + k + 3][0] = tpBuffer[k + 3] ^ hashBuffer[3]; - messages[j + k + 4][0] = tpBuffer[k + 4] ^ hashBuffer[4]; - messages[j + k + 5][0] = tpBuffer[k + 5] ^ hashBuffer[5]; - messages[j + k + 6][0] = tpBuffer[k + 6] ^ hashBuffer[6]; - messages[j + k + 7][0] = tpBuffer[k + 7] ^ hashBuffer[7]; - - tpBuffer[k + 0] = tpBuffer[k + 0] ^ mGen.mValue; - tpBuffer[k + 1] = tpBuffer[k + 1] ^ mGen.mValue; - tpBuffer[k + 2] = tpBuffer[k + 2] ^ mGen.mValue; - tpBuffer[k + 3] = tpBuffer[k + 3] ^ mGen.mValue; - tpBuffer[k + 4] = tpBuffer[k + 4] ^ mGen.mValue; - tpBuffer[k + 5] = tpBuffer[k + 5] ^ mGen.mValue; - tpBuffer[k + 6] = tpBuffer[k + 6] ^ mGen.mValue; - tpBuffer[k + 7] = tpBuffer[k + 7] ^ mGen.mValue; - - mAesFixedKey.ecbEncBlocks(tpBuffer.data() + k, hashBuffer.size(), hashBuffer.data()); - - messages[j + k + 0][1] = tpBuffer[k + 0] ^ hashBuffer[0]; - messages[j + k + 1][1] = tpBuffer[k + 1] ^ hashBuffer[1]; - messages[j + k + 2][1] = tpBuffer[k + 2] ^ hashBuffer[2]; - messages[j + k + 3][1] = tpBuffer[k + 3] ^ hashBuffer[3]; - messages[j + k + 4][1] = tpBuffer[k + 4] ^ hashBuffer[4]; - messages[j + k + 5][1] = tpBuffer[k + 5] ^ hashBuffer[5]; - messages[j + k + 6][1] = tpBuffer[k + 6] ^ hashBuffer[6]; - messages[j + k + 7][1] = tpBuffer[k + 7] ^ hashBuffer[7]; - } - - for (; k < min; ++k) - { - messages[j + k][0] = mAesFixedKey.ecbEncBlock(tpBuffer[k]) ^ tpBuffer[k]; - messages[j + k][1] = mAesFixedKey.ecbEncBlock(tpBuffer[k] ^ mGen.mValue) ^ tpBuffer[k] ^ mGen.mValue; - } + transpose128(tpBuffer); -#endif - //messages[i][0] = view(i, 0); - //messages[i][1] = view(i, 0) ^ mGen.mValue; - } + auto end = i * tpBuffer.size() + min; + for (u64 k = 0; j < end; ++j, ++k) + mB[j] = tpBuffer[k]; + } - if(index==0) - setTimePoint("sender.expand.transposeXor"); - }; + if (index == 0) + setTimePoint("sender.expand.qc.transposeXor"); + }; + std::vector thrds(mNumThreads - 1); + for (u64 i = 0; i < thrds.size(); ++i) + thrds[i] = std::thread(routine, i); - std::vector thrds(threads - 1); - for (u64 i = 0; i < thrds.size(); ++i) - thrds[i] = std::thread(routine, i); + routine(thrds.size()); - routine(thrds.size()); + for (u64 i = 0; i < thrds.size(); ++i) + thrds[i].join(); - for (u64 i = 0; i < thrds.size(); ++i) - thrds[i].join(); +#else + std::cout << "bit poly mul is not enabled. Please recompile with ENABLE_BITPOLYMUL defined. " LOCATION << std::endl; + throw RTE_LOC; +#endif - } + } } #endif \ No newline at end of file diff --git a/libOTe/TwoChooseOne/SilentOtExtSender.h b/libOTe/TwoChooseOne/SilentOtExtSender.h index 04a98b54..a920e18b 100644 --- a/libOTe/TwoChooseOne/SilentOtExtSender.h +++ b/libOTe/TwoChooseOne/SilentOtExtSender.h @@ -9,22 +9,25 @@ #include #include #include +#include +#include +#include namespace osuCrypto { // Silent OT works a bit different than normal OT extension // This stems from that fact that is needs many base OTs which are - // of chosen message and choosen choice. Normal OT extension + // of chosen message and chosen choice. Normal OT extension // requires about 128 random OTs. // - // This is further complicated by the fact that that silent OT + // This is further complicated by the fact that silent OT // naturally samples the choice bits at random while normal OT // lets you choose them. Due to this we give two interfaces. // // The first satisfies the original OT extension interface. That is // you can call genBaseOts(...) or setBaseOts(...) just as before - // and interanlly the implementation will transform these into + // and internally the implementation will transform these into // the required base OTs. You can also directly call send(...) or receive(...) // just as before and the receiver can specify the OT messages // that they wish to receive. However, using this interface results @@ -59,9 +62,67 @@ namespace osuCrypto { public: + + // the number of OTs being requested. + u64 mRequestNumOts = 0; + + // The prime for QuasiCycic encoding + u64 mP = 0; + + // The sparse vector size, this will be mN * mScaler. + u64 mN2 = 0; + + // The dense vector size, this will be at least as big as mRequestedNumOts. + u64 mN = 0; + + // The number of regular section of the sparse vector. + u64 mNumPartitions = 0; + + // The size of each regular section of the sparse vector. + u64 mSizePer = 0; + + // The scaling factor that the sparse vector will be compressed by. + u64 mScaler = 2; + + // The B vector in the relation A + B = C * delta + span mB; + + // The delta scaler in the relation A + B = C * delta + block mDelta; + + // The number of threads that should be used (when applicable). + u64 mNumThreads = 1; + +#ifdef ENABLE_KOS + // Kos instance used to generate the base OTs. + KosOtExtSender mKosSender; +#endif + + // The ggm tree thats used to generate the sparse vectors. SilentMultiPprfSender mGen; - u64 mP, mN2, mN = 0, mNumPartitions, mScaler, mSizePer, mNumThreads; - IknpOtExtSender mIknpSender; + + // The type of compress we will use to generate the + // dense vectors from the sparse vectors. + MultType mMultType = MultType::QuasiCyclic; + + // The flag which controls whether the malicious check is performed. + SilentSecType mMalType = SilentSecType::SemiHonest; + + // The OTs send msgs which will be used to create the + // secret share of xa * delta as described in ferret. + std::vector> mMalCheckOts; + + // The memory backing mB + std::unique_ptr mBacking; + + // The size of the memory backing mB + u64 mBackingSize = 0; + + // A flag that helps debug + bool mDebug = false; + + + virtual ~SilentOtExtSender() = default; ///////////////////////////////////////////////////// // The standard OT extension interface @@ -73,27 +134,22 @@ namespace osuCrypto // returns true if the IKNP base OTs are currently set. bool hasBaseOts() const override; + void setBaseOts( + span baseRecvOts, + const BitVector& choices); + // sets the IKNP base OTs that are then used to extend void setBaseOts( span baseRecvOts, const BitVector& choices, - Channel& chl) override - { - mIknpSender.setBaseOts(baseRecvOts, choices, chl); - } + Channel& chl) override; - // Returns an indpendent copy of this extender. - std::unique_ptr split() override - { - throw std::runtime_error("not impl"); - } + // Returns an independent copy of this extender. + std::unique_ptr split() override; // use the default base OT class to generate the // IKNP base OTs that are required. - void genBaseOts(PRNG& prng, Channel& chl) override - { - mIknpSender.genBaseOts(prng, chl); - } + void genBaseOts(PRNG& prng, Channel& chl) override; // Perform OT extension of random OT messages but // allow the receiver to specify the choice bits. @@ -107,6 +163,12 @@ namespace osuCrypto // The native silent OT extension interface ///////////////////////////////////////////////////// + + bool hasSilentBaseOts() const + { + return mGen.hasBaseOts(); + } + // 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 @@ -117,11 +179,15 @@ namespace osuCrypto // the parameters and figures out how many base OT // will be needed. These can then be ganerated for // a different OT extension or using a base OT protocol. + // @n [in] - the number of OTs. + // @scaler [in] - the compression factor. + // @nThreads [in] - the number of threads. + // @mal [in] - whether the malicious check is performed. void configure( u64 n, u64 scaler = 2, - u64 secParam = 128, - u64 numThreads = 1); + u64 numThreads = 1, + SilentSecType malType = SilentSecType::SemiHonest); // return true if this instance has been configured. bool isConfigured() const { return mN > 0; } @@ -132,47 +198,69 @@ namespace osuCrypto // Set the externally generated base OTs. This choice // bits must be the one return by sampleBaseChoiceBits(...). - void setSlientBaseOts(span> sendBaseOts); - - // This is an "all-in-one" function that generates the base - // OTs in various ways. - void genBase( - u64 n, Channel& chl, PRNG& prng, - u64 scaler = 2, u64 secParam = 128, - SilentBaseType base = SilentBaseType::BaseExtend, - u64 threads = 1); - - // The native OT extension interface of silent - // OT. The receiver does not get to specify - // which OT message they receiver. Instead - // the protocol picks them at random. Use the - // send(...) interface for the normal behavior. + void setSilentBaseOts(span> sendBaseOts); + + + // Runs the silent random OT protocol and outputs b. + // Then this will generate random OTs, where c is a random + // bit vector and a[i] = b[i][c[i]]. + // @ b [out] - the random ot message. + // @prng [in] - randomness source. + // @chl [in] - the comm channel void silentSend( - span> messages, + span> b, PRNG& prng, Channel& chl); - // A parallel exection version of the other - // silentSend(...) function. + // Runs the silent correlated OT protocol and outputs b. + // The protocol takes as input the desired delta value. + // The outputs will have the relation: + // a[i] = b[i] + c[i] * delta. + // @ d [in] - the delta used in the correlated OT + // @ b [out] - the correlated ot message. + // @prng [in] - randomness source. + // @chl [in] - the comm channel void silentSend( - span> messages, + block d, + span b, PRNG& prng, - span chls); + Channel& chl); + + // Runs the silent correlated OT protocol and store + // the b vector internally as mB. The protocol takes + // as input the desired delta value. The outputs will + // have the relation: + // a[i] = b[i] + c[i] * delta. + // @ d [in] - the delta used in the correlated OT + // @ n [in] - the number of correlated ot message. + // @prng [in] - randomness source. + // @chl [in] - the comm channel + void silentSendInplace( + block d, + u64 n, + PRNG& prng, + Channel& chl); + // internal functions - // interal functions - void randMulNaive(Matrix& rT, span>& messages); - void randMulQuasiCyclic(Matrix& rT, span>& messages, u64 threads); + // Runs the malicious consistency check as described + // by the ferret paper. We only run the batch check and + // not the cuckoo hashing part. + void ferretMalCheck(Channel& chl, PRNG& prng); - bool mDebug = false; - void checkRT(span chls, Matrix& rT); + // the QuasiCyclic compression routine. + void randMulQuasiCyclic(); + + void hash(span> messages, ChoiceBitPacking type); + + // a debugging check on the sparse vector. Insecure to use. + void checkRT(Channel& chls); + // clears the internal buffers. void clear(); }; - void bitShiftXor(span dest, span in, u8 bitShift); - void modp(span dest, span in, u64 p); } diff --git a/libOTe/TwoChooseOne/TcoOtDefines.h b/libOTe/TwoChooseOne/TcoOtDefines.h index 76464bc3..ae41fb45 100644 --- a/libOTe/TwoChooseOne/TcoOtDefines.h +++ b/libOTe/TwoChooseOne/TcoOtDefines.h @@ -12,6 +12,11 @@ namespace osuCrypto enum class SilentBaseType {Base, BaseExtend}; + enum class MultType + { + QuasiCyclic = 1 + }; + template y, span z, PRNG& prng, OtSender& ot, Channel& chl) + { + setTimePoint("recvOT"); + + std::array, 128> otMsg; + ot.send(otMsg, prng, chl); + + return receive(y, z, prng, otMsg, chl); + } + void NoisyVoleReceiver::receive(span y, span z, PRNG& prng, span> otMsg, Channel& chl) + { + if (otMsg.size() != 128) + throw RTE_LOC; + if (y.size() != z.size()) + throw RTE_LOC; + + memset(z.data(), 0, sizeof(block) * z.size()); + setTimePoint("recvMain"); + Matrix msg(otMsg.size(), y.size()); + + std::vector buffer(z.size()); + + for (u64 ii = 0; ii < (u64)otMsg.size(); ++ii) + { + PRNG p0(otMsg[ii][0]); + PRNG p1(otMsg[ii][1]); + + p0.get(buffer); + //if (ii < 2) + // std::cout << "zero" << ii << " "; + for (u64 j = 0; j < (u64)y.size(); ++j) + { + // zj -= m0[i][j] + z[j] = z[j] ^ buffer[j]; + + //if (ii < 2 && j < 2) + // std::cout << buffer[j] << " "; + + block twoPowI = ZeroBlock; + *BitIterator((u8*)&twoPowI, ii) = 1; + + auto yy = y[j].gf128Mul(twoPowI); + + // mij = yj * 2^i + m0[i][j] + msg(ii, j) = yy ^ buffer[j]; + } + + p1.get(buffer); + + + //if (ii < 2) + // std::cout << std::endl; + //if (ii < 2) + // std::cout << "one" << ii << " "; + + for (u64 j = 0; j < (u64)y.size(); ++j) + { + //if (ii < 2 && j < 2) + // std::cout << buffer[j] << " "; + + // enc one message under the OT msg. + msg(ii, j) = msg(ii, j) ^ buffer[j]; + } + //if (ii < 2) + // std::cout << std::endl; + + } + setTimePoint("recvSendMsg"); + + chl.asyncSend(std::move(msg)); + } +} +#endif \ No newline at end of file diff --git a/libOTe/Vole/NoisyVoleReceiver.h b/libOTe/Vole/NoisyVoleReceiver.h new file mode 100644 index 00000000..dc46b699 --- /dev/null +++ b/libOTe/Vole/NoisyVoleReceiver.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#if defined(ENABLE_SILENT_VOLE) || defined(ENABLE_SILENTOT) + +#include "cryptoTools/Common/Defines.h" +#include "cryptoTools/Common/Timer.h" +#include "cryptoTools/Network/Channel.h" +#include "cryptoTools/Crypto/PRNG.h" +#include "libOTe/TwoChooseOne/OTExtInterface.h" +namespace osuCrypto +{ + + + class NoisyVoleReceiver : public TimerAdapter + { + public: + NoisyVoleReceiver() = default; + ~NoisyVoleReceiver() = default; + + + void receive(span y, span z, PRNG& prng, OtSender& ot, Channel& chl); + void receive(span y, span z, PRNG& prng, span> otMsg, Channel& chl); + + }; + + +} +#endif diff --git a/libOTe/Vole/NoisyVoleSender.cpp b/libOTe/Vole/NoisyVoleSender.cpp new file mode 100644 index 00000000..89f2c684 --- /dev/null +++ b/libOTe/Vole/NoisyVoleSender.cpp @@ -0,0 +1,84 @@ +#include "NoisyVoleSender.h" + +#if defined(ENABLE_SILENT_VOLE) || defined(ENABLE_SILENTOT) +#include "cryptoTools/Common/BitVector.h" +#include "cryptoTools/Common/Matrix.h" + +namespace osuCrypto +{ + void NoisyVoleSender::send(block x, span z, PRNG& prng, OtReceiver& ot, Channel& chl) + { + setTimePoint("recvOT"); + + BitVector bv((u8*)&x, 128); + std::array otMsg; + ot.receive(bv, otMsg, prng, chl); + + return send(x, z, prng, otMsg, chl); + } + + void NoisyVoleSender::send(block x, span z, PRNG& prng, span otMsg, Channel& chl) + { + if (otMsg.size() != 128) + throw RTE_LOC; + setTimePoint("recvMain"); + + Matrix msg(otMsg.size(), z.size()); + memset(z.data(), 0, sizeof(block) * z.size()); + chl.recv(msg.data(), msg.size()); + setTimePoint("recvMsg"); + std::vector buffer(z.size()); + + auto xIter = BitIterator((u8*)&x); + + for (u64 i = 0; i < otMsg.usize(); ++i, ++xIter) + { + PRNG pi(otMsg[i]); + pi.get(buffer); + + + if (*xIter) + { + + //if (i < 2) + // std::cout << "One" << i << " "; + + for (u64 j = 0; j < z.usize(); ++j) + { + + //if (i < 2 && j < 2) + // std::cout << buffer[j] << " "; + + buffer[j] = msg(i, j) ^ buffer[j]; + } + } + //else + //{ + // if (i < 2) + // std::cout << "Zero" << i << " "; + + // for (u64 j = 0; j < z.size(); ++j) + // { + + // if (i < 2 && j < 2) + // std::cout << buffer[j] << " "; + // } + //} + // + + //if (i < 2) + // std::cout << std::endl; + + for (u64 j = 0; j < (u64)z.size(); ++j) + { + + + z[j] = z[j] ^ buffer[j]; + } + } + setTimePoint("recvDone"); + + } + +} +#endif diff --git a/libOTe/Vole/NoisyVoleSender.h b/libOTe/Vole/NoisyVoleSender.h new file mode 100644 index 00000000..32d08a76 --- /dev/null +++ b/libOTe/Vole/NoisyVoleSender.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#if defined(ENABLE_SILENT_VOLE) || defined(ENABLE_SILENTOT) + +#include "cryptoTools/Common/Defines.h" +#include "cryptoTools/Common/Timer.h" +#include "cryptoTools/Network/Channel.h" +#include "cryptoTools/Crypto/PRNG.h" +#include "libOTe/TwoChooseOne/OTExtInterface.h" + +namespace osuCrypto +{ + + + class NoisyVoleSender : public TimerAdapter + { + public: + + + void send(block x, span z, PRNG& prng, OtReceiver& ot, Channel& chl); + void send(block x, span z, PRNG& prng, span otMsg, Channel& chl); + + + + }; + + +} + +#endif \ No newline at end of file diff --git a/libOTe/config.h b/libOTe/config.h deleted file mode 100644 index c2251604..00000000 --- a/libOTe/config.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once -#include "libOTe/version.h" - -#define LIBOTE_VERSION (LIBOTE_VERSION_MAJOR * 10000 + LIBOTE_VERSION_MINOR * 100 + LIBOTE_VERSION_PATCH) - -// build the library with "simplest" Base OT enabled -#define ENABLE_SIMPLESTOT ON - -// build the library with the ASM "simplest" Base OT enabled -#define ENABLE_SIMPLESTOT_ASM ON - -// build the library with Masney Rindal Base OT enabled -#define ENABLE_MR ON - -// build the library with Masney Rindal Kyber Base OT enabled -#define ENABLE_MR_KYBER ON - -// build the library with Naor Pinkas Base OT enabled -#define ENABLE_NP ON - - - -// build the library with Keller Orse Scholl OT-Ext enabled -#define ENABLE_KOS ON - -// build the library with IKNP OT-Ext enabled -#define ENABLE_IKNP ON - -// build the library with Silent OT Extension enabled -#define ENABLE_SILENTOT ON - - - -// build the library with KOS Delta-OT-ext enabled -#define ENABLE_DELTA_KOS ON - -// build the library with IKNP Delta-OT-ext enabled -#define ENABLE_DELTA_IKNP ON - - - -// build the library with OOS 1-oo-N OT-Ext enabled -#define ENABLE_OOS ON - -// build the library with KKRT 1-oo-N OT-Ext enabled -#define ENABLE_KKRT ON - -// build the library with RR 1-oo-N OT-Ext OT-ext enabled -#define ENABLE_RR ON - -// build the library with RR approx k-oo-N OT-ext enabled -#define ENABLE_AKN ON - - -#define OTE_RANDOM_ORACLE 1 -#define OTE_DAVIE_MEYER_AES 2 - -#define OTE_KOS_HASH OTE_DAVIE_MEYER_AES - -// build the library where KOS is round optimized. -/* #undef OTE_KOS_FIAT_SHAMIR */ - - -#if defined(ENABLE_SIMPLESTOT_ASM) && defined(_MSC_VER) - #undef ENABLE_SIMPLESTOT_ASM - #pragma message("ENABLE_SIMPLESTOT_ASM should not be defined on windows.") -#endif -#if defined(ENABLE_MR_KYBER) && defined(_MSC_VER) - #undef ENABLE_MR_KYBER - #pragma message("ENABLE_MR_KYBER should not be defined on windows.") -#endif - diff --git a/libOTe/config.h.in b/libOTe/config.h.in index 71a8e5ee..f09deedd 100644 --- a/libOTe/config.h.in +++ b/libOTe/config.h.in @@ -3,12 +3,21 @@ #define LIBOTE_VERSION (LIBOTE_VERSION_MAJOR * 10000 + LIBOTE_VERSION_MINOR * 100 + LIBOTE_VERSION_PATCH) +// build the library bit poly mul integration +#cmakedefine ENABLE_BITPOLYMUL @ENABLE_BITPOLYMUL@ + // build the library with "simplest" Base OT enabled #cmakedefine ENABLE_SIMPLESTOT @ENABLE_SIMPLESTOT@ // build the library with the ASM "simplest" Base OT enabled #cmakedefine ENABLE_SIMPLESTOT_ASM @ENABLE_SIMPLESTOT_ASM@ +// build the library with POPF Base OT using Ristretto KA enabled +#cmakedefine ENABLE_MRR @ENABLE_MRR@ + +// build the library with POPF Base OT using Moeller KA enabled +#cmakedefine ENABLE_MRR_TWIST @ENABLE_MRR_TWIST@ + // build the library with Masney Rindal Base OT enabled #cmakedefine ENABLE_MR @ENABLE_MR@ @@ -52,15 +61,6 @@ #cmakedefine ENABLE_AKN @ENABLE_AKN@ -#define OTE_RANDOM_ORACLE 1 -#define OTE_DAVIE_MEYER_AES 2 - -#cmakedefine OTE_KOS_HASH @OTE_KOS_HASH@ - -// build the library where KOS is round optimized. -#cmakedefine OTE_KOS_FIAT_SHAMIR @OTE_KOS_FIAT_SHAMIR@ - - #if defined(ENABLE_SIMPLESTOT_ASM) && defined(_MSC_VER) #undef ENABLE_SIMPLESTOT_ASM #pragma message("ENABLE_SIMPLESTOT_ASM should not be defined on windows.") diff --git a/libOTe/libOTe.vcxproj.filters b/libOTe/libOTe.vcxproj.filters deleted file mode 100644 index 546d7ee8..00000000 --- a/libOTe/libOTe.vcxproj.filters +++ /dev/null @@ -1,369 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {359cc1cc-4102-4809-a1b7-e2caa2a3636c} - - - {6c565298-e3cd-46bb-ae95-92da3ac58263} - - - {027acd13-01ed-4769-97d7-c9f831a8adc7} - - - {b0ad03cd-1191-4a73-b17c-7826ae55a2ec} - - - {5a130c82-f1f4-46dd-a138-71fdde95e3dc} - - - {e224d9db-a72e-43dd-ac72-f1de6f402b5f} - - - {a2dd4791-8f4b-4dac-855c-078730828278} - - - {6d429df5-5441-472c-b3e8-d1c8c526c6f1} - - - {2c805d83-f4ab-4d62-955f-b15c2a623158} - - - {035bde2d-81b4-4425-ad82-3126b065ef78} - - - {2a97e7f3-304a-4572-85d5-2ba9ba9f2d1d} - - - {a05faa47-09f3-49b9-a243-0ba12f7c4c91} - - - {311376e4-22b0-408c-99f0-09c19f3dc25e} - - - {30d947ed-04cf-436d-9448-1a4d7e3ba459} - - - {c78622c2-1a3d-464a-8809-58ffc3acaca4} - - - {19a51d51-a957-4430-8afe-e1b559739ec3} - - - {32e7ac3a-b89a-43f8-b968-3aef3877cac1} - - - {04ae59da-5ccc-426b-8ca9-b9633967c2ca} - - - - - Source Files\Crypto - - - Source Files\Crypto - - - Source Files\Common - - - Source Files\Common - - - Source Files\Common - - - Source Files\Common - - - Source Files\Common - - - Source Files\OT\Base - - - Source Files\MPSI\Dcw - - - Source Files\MPSI\Dcw - - - Source Files\MPSI\Dcw - - - Source Files\MPSI\Dcw - - - Source Files\Common - - - Source Files\Crypto - - - Source Files\Network - - - Source Files\Network - - - Source Files\Network - - - Source Files\Network - - - Source Files\Network - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files\OT\Base\Tools - - - Source Files - - - Source Files\OT - - - Source Files\OT - - - Source Files\OT - - - Source Files\OT - - - Source Files\OT - - - Source Files\OT - - - Source Files\OT - - - Source Files\OT - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files\Common - - - Header Files\Common - - - Header Files\Common - - - Header Files\Common - - - Header Files\Common - - - Header Files\Common - - - Header Files\Crypto - - - Header Files\Crypto - - - Header Files\Crypto - - - Header Files\Crypto - - - Header Files\Common - - - Header Files\Common - - - Header Files\Common - - - Header Files\OT\Base - - - Header Files\MPSI\Dcw - - - Header Files\MPSI\Dcw - - - Header Files\MPSI\Dcw - - - Header Files\MPSI\Dcw - - - Header Files\Crypto - - - Header Files\Network - - - Header Files\Network - - - Header Files\Network - - - Header Files\Network - - - Header Files\Network - - - Header Files\Network - - - Header Files\Network - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files\OT\Base\tools - - - Header Files - - - Header Files\OT - - - Header Files\OT - - - Header Files\OT - - - Header Files\OT - - - Header Files\OT - - - Header Files\OT - - - Header Files\OT - - - Header Files\OT - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files\OT - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - - \ No newline at end of file diff --git a/libOTe/libOTe.vcxproj.vcxproj b/libOTe/libOTe.vcxproj.vcxproj deleted file mode 100644 index 73c3ca17..00000000 --- a/libOTe/libOTe.vcxproj.vcxproj +++ /dev/null @@ -1,230 +0,0 @@ - - - - - Debug_DLLRT - x64 - - - Debug - x64 - - - Release_DLLRT - x64 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {D159E2F9-226C-4B19-905E-CC1EA0EB013F} - libOTe - libOTe - 10.0 - - - - StaticLibrary - true - MultiByte - v142 - - - StaticLibrary - true - MultiByte - v142 - - - StaticLibrary - false - true - MultiByte - v142 - - - StaticLibrary - false - true - MultiByte - v142 - - - - - - - - - - - - - - - - - - - - - $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir) - - - $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir) - - - - Level3 - Disabled - $(ProjectDir)/..;$(ProjectDir)/../cryptoTools/;$(ProjectDir)/../cryptoTools/thirdparty/win/boost;$(ProjectDir)/../SimplestOT/;$(ProjectDir)/../bitpolymul2/;C:\libs\include;$(SolutionDir)/cryptoTools/thirdparty/win/;$(SolutionDir)/cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/miracl - BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE;SOLUTION_DIR=R"**($(SolutionDir))**";_MBCS;%(PreprocessorDefinitions);_WIN32_WINNT=0x0501; - MultiThreadedDebug - true - true - false - - - - - Level3 - Disabled - $(ProjectDir)/..;$(ProjectDir)/../cryptoTools/;$(ProjectDir)/../cryptoTools/thirdparty/win/boost;$(ProjectDir)/../SimplestOT/;$(ProjectDir)/../bitpolymul2/;C:\libs\include;$(SolutionDir)/cryptoTools/thirdparty/win/;$(SolutionDir)/cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/miracl - BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE;SOLUTION_DIR=R"**($(SolutionDir))**";_MBCS;%(PreprocessorDefinitions);_WIN32_WINNT=0x0501; - MultiThreadedDebugDLL - true - true - false - - - - - Level3 - MaxSpeed - true - true - $(ProjectDir)/..;$(ProjectDir)/../cryptoTools/;$(ProjectDir)/../cryptoTools/thirdparty/win/boost;$(ProjectDir)/../SimplestOT/;$(ProjectDir)/../bitpolymul2/;C:\libs\include;$(SolutionDir)/cryptoTools/thirdparty/win/;$(SolutionDir)/cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/miracl - BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE;SOLUTION_DIR=R"**($(SolutionDir))**";_MBCS;%(PreprocessorDefinitions);_WIN32_WINNT=0x0501; - MultiThreaded - true - true - - - true - true - - - - - Level3 - MaxSpeed - true - true - $(ProjectDir)/..;$(ProjectDir)/../cryptoTools/;$(ProjectDir)/../cryptoTools/thirdparty/win/boost;$(ProjectDir)/../SimplestOT/;$(ProjectDir)/../bitpolymul2/;C:\libs\include;$(SolutionDir)/cryptoTools/thirdparty/win/;$(SolutionDir)/cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/miracl - BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE;SOLUTION_DIR=R"**($(SolutionDir))**";_MBCS;%(PreprocessorDefinitions);_WIN32_WINNT=0x0501;NDEBUG - MultiThreadedDLL - true - true - - - true - true - - - - - - \ No newline at end of file diff --git a/libOTe/version.h b/libOTe/version.h index 25c814a5..dafe6f54 100644 --- a/libOTe/version.h +++ b/libOTe/version.h @@ -1,7 +1,7 @@ #pragma once #define LIBOTE_VERSION_MAJOR 1 -#define LIBOTE_VERSION_MINOR 1 -#define LIBOTE_VERSION_PATCH 0 +#define LIBOTE_VERSION_MINOR 5 +#define LIBOTE_VERSION_PATCH 1 #define LIBOTE_VERSION (LIBOTE_VERSION_MAJOR * 10000 + LIBOTE_VERSION_MINOR * 100 + LIBOTE_VERSION_PATCH) diff --git a/libOTe_Tests/AknOt_Tests.cpp b/libOTe_Tests/AknOt_Tests.cpp index f70eaf95..15039476 100644 --- a/libOTe_Tests/AknOt_Tests.cpp +++ b/libOTe_Tests/AknOt_Tests.cpp @@ -48,8 +48,8 @@ namespace tests_libOTe std::vector sendChls(numTHreads), recvChls(numTHreads); for (u64 i = 0; i < numTHreads; ++i) { - sendChls[i] = std::move(ep1.addChannel("chl" + std::to_string(i), "chl" + std::to_string(i))); - recvChls[i] = std::move(ep0.addChannel("chl" + std::to_string(i), "chl" + std::to_string(i))); + sendChls[i] = (ep1.addChannel("chl" + std::to_string(i), "chl" + std::to_string(i))); + recvChls[i] = (ep0.addChannel("chl" + std::to_string(i), "chl" + std::to_string(i))); } diff --git a/libOTe_Tests/BaseOT_Tests.cpp b/libOTe_Tests/BaseOT_Tests.cpp index 032cfa75..4d8b0dda 100644 --- a/libOTe_Tests/BaseOT_Tests.cpp +++ b/libOTe_Tests/BaseOT_Tests.cpp @@ -9,6 +9,17 @@ #include "libOTe/Base/BaseOT.h" #include "libOTe/Base/SimplestOT.h" + +#include "libOTe/Base/McRosRoyTwist.h" +#include "libOTe/Base/McRosRoy.h" + +#include "libOTe/Tools/Popf/EKEPopf.h" +#include "libOTe/Tools/Popf/MRPopf.h" +#include "libOTe/Tools/Popf/FeistelPopf.h" +#include "libOTe/Tools/Popf/FeistelMulPopf.h" +#include "libOTe/Tools/Popf/FeistelRistPopf.h" +#include "libOTe/Tools/Popf/FeistelMulRistPopf.h" + #include "libOTe/Base/MasnyRindal.h" #include "libOTe/Base/MasnyRindalKyber.h" #include @@ -18,6 +29,7 @@ #include #include #include +#include "BaseOT_Tests.h" #ifdef GetMessage #undef GetMessage @@ -72,7 +84,7 @@ namespace tests_libOTe } } #else - throw UnitTestSkipped("NaorPinkas OT not enabled. Requires Relic or Miracl"); + throw UnitTestSkipped("NaorPinkas OT not enabled. Requires libsodium or Relic"); #endif } @@ -119,16 +131,127 @@ namespace tests_libOTe } } #else - throw UnitTestSkipped("Simplest OT not enabled. Requires Relic or the simplest OT ASM library"); + throw UnitTestSkipped("Simplest OT not enabled. Requires libsodium, Relic, or the simplest OT ASM library"); #endif } + template class PopfOT, typename DSPopf> + static void Bot_PopfOT_Test_impl() + { + setThreadName("Sender"); + + IOService ios(0); + Session ep0(ios, "127.0.0.1", 1212, SessionMode::Server); + Session ep1(ios, "127.0.0.1", 1212, SessionMode::Client); + Channel senderChannel = ep1.addChannel(); + Channel recvChannel = ep0.addChannel(); + + PRNG prng0(block(4253465, 3434565)); + PRNG prng1(block(42532335, 334565)); + + u64 numOTs = 50; + std::vector recvMsg(numOTs); + std::vector> sendMsg(numOTs); + BitVector choices(numOTs); + choices.randomize(prng0); + + DSPopf popfFactory; + const char* test_domain = "Bot_PopfOT_Test()"; + popfFactory.Update(test_domain, std::strlen(test_domain)); + + std::thread thrd = std::thread([&]() { + setThreadName("receiver"); + PopfOT baseOTs(popfFactory); + baseOTs.send(sendMsg, prng1, recvChannel); + + }); + + PopfOT baseOTs(popfFactory); + baseOTs.receive(choices, recvMsg, prng0, senderChannel); + thrd.join(); + + for (u64 i = 0; i < numOTs; ++i) + { + if (neq(recvMsg[i], sendMsg[i][choices[i]])) + { + std::cout << "failed " << i <<" exp = m["<< int(choices[i]) <<"], act = " << recvMsg[i] <<" true = " << sendMsg[i][0] << ", " << sendMsg[i][1] <(); + } +#else + void Bot_McQuoidRR_Moeller_EKE_Test() + { + throw UnitTestSkipped("McQuoid Rosulek Roy not enabled (ENABLE_MRR_TWIST, ENABLE_SSE). Requires libsodium and SSE."); + } +#endif + +#ifdef ENABLE_MRR_TWIST + + void Bot_McQuoidRR_Moeller_MR_Test() + { + Bot_PopfOT_Test_impl(); + } + + void Bot_McQuoidRR_Moeller_F_Test() + { + Bot_PopfOT_Test_impl(); + } + + void Bot_McQuoidRR_Moeller_FM_Test() + { + Bot_PopfOT_Test_impl(); + } +#else + void Bot_McQuoidRR_Moeller_MR_Test() + { + throw UnitTestSkipped("McQuoid Rosulek Roy not enabled (ENABLE_MRR_TWIST). Requires libsodium."); + } + + void Bot_McQuoidRR_Moeller_F_Test() + { + throw UnitTestSkipped("McQuoid Rosulek Roy not enabled (ENABLE_MRR_TWIST). Requires libsodium."); + } + + void Bot_McQuoidRR_Moeller_FM_Test() + { + throw UnitTestSkipped("McQuoid Rosulek Roy not enabled (ENABLE_MRR_TWIST). Requires libsodium."); + } +#endif + +#ifdef ENABLE_MRR + void Bot_McQuoidRR_Ristrestto_F_Test() + { + Bot_PopfOT_Test_impl(); + } + + void Bot_McQuoidRR_Ristrestto_FM_Test() + { + Bot_PopfOT_Test_impl(); + } +#else + + void Bot_McQuoidRR_Ristrestto_F_Test() + { + throw UnitTestSkipped("McQuoid Rosulek Roy not enabled (ENABLE_MRR). Requires libsodium or Relic."); + } + + void Bot_McQuoidRR_Ristrestto_FM_Test() + { + throw UnitTestSkipped("McQuoid Rosulek Roy not enabled (ENABLE_MRR). Requires libsodium or Relic."); + } +#endif void Bot_MasnyRindal_Test() { -#ifdef ENABLE_MR +#ifdef ENABLE_MR setThreadName("Sender"); IOService ios(0); @@ -153,7 +276,7 @@ namespace tests_libOTe baseOTs.send(sendMsg, prng1, recvChannel); }); - + MasnyRindal baseOTs; baseOTs.receive(choices, recvMsg, prng0, senderChannel); @@ -168,13 +291,13 @@ namespace tests_libOTe } } #else -throw UnitTestSkipped("MasnyRindal not enabled. Requires Relic."); + throw UnitTestSkipped("MasnyRindal not enabled. Requires libsodium or Relic."); #endif } void Bot_MasnyRindal_Kyber_Test() { -#ifdef ENABLE_MR_KYBER +#ifdef ENABLE_MR_KYBER setThreadName("Sender"); IOService ios(0); @@ -218,4 +341,4 @@ throw UnitTestSkipped("MasnyRindal not enabled. Requires Relic."); #endif } -} \ No newline at end of file +} diff --git a/libOTe_Tests/BaseOT_Tests.h b/libOTe_Tests/BaseOT_Tests.h index 266ad7b7..38212dd3 100644 --- a/libOTe_Tests/BaseOT_Tests.h +++ b/libOTe_Tests/BaseOT_Tests.h @@ -8,4 +8,15 @@ namespace tests_libOTe void Bot_Simplest_Test(); void Bot_MasnyRindal_Test(); void Bot_MasnyRindal_Kyber_Test(); + + void Bot_McQuoidRR_Moeller_EKE_Test(); + void Bot_McQuoidRR_Moeller_MR_Test(); + void Bot_McQuoidRR_Moeller_F_Test(); + void Bot_McQuoidRR_Moeller_FM_Test(); + void Bot_McQuoidRR_Ristrestto_F_Test(); + void Bot_McQuoidRR_Ristrestto_FM_Test(); + + + //template class PopfOT, typename DSPopf> + //void Bot_PopfOT_Test(); } diff --git a/libOTe_Tests/CMakeLists.txt b/libOTe_Tests/CMakeLists.txt index 7479a97e..81680680 100644 --- a/libOTe_Tests/CMakeLists.txt +++ b/libOTe_Tests/CMakeLists.txt @@ -1,8 +1,17 @@ #project(libOTe_Tests) -file(GLOB_RECURSE SRCS *.cpp) +file(GLOB SRCS *.cpp) add_library(libOTe_Tests STATIC ${SRCS}) -target_include_directories(libOTe_Tests PUBLIC ${CMAKE_SOURCE_DIR}) target_link_libraries(libOTe_Tests libOTe) + + +# make projects that include libOTe_Tests use this as an include folder +target_include_directories(libOTe_Tests PUBLIC + $ + $) +target_include_directories(libOTe_Tests PUBLIC + $ + $) + diff --git a/libOTe_Tests/NcoOT_Tests.cpp b/libOTe_Tests/NcoOT_Tests.cpp index c3b44692..a6caac23 100644 --- a/libOTe_Tests/NcoOT_Tests.cpp +++ b/libOTe_Tests/NcoOT_Tests.cpp @@ -161,7 +161,7 @@ namespace tests_libOTe PRNG prng1(block(42532335, 334565)); // The total number that we wish to do - u64 numOTs = 1030; + u64 numOTs = 128; KkrtNcoOtSender sender; KkrtNcoOtReceiver recv; @@ -217,10 +217,9 @@ namespace tests_libOTe prng0.get(inputs.data(), inputs.size()); - - for (u64 k = 0; k < stepSize; ++k) + auto ss = std::min(stepSize, numOTs - i); + for (u64 k = 0; k < ss; ++k) { - // The receiver MUST encode before the sender. Here we are only calling encode(...) // for a single i. But the receiver can also encode many i, but should only make one // call to encode for any given value of i. @@ -231,14 +230,15 @@ namespace tests_libOTe // If we had made more or less calls to encode above (for contigious i), then we should replace // stepSize with however many calls we made. In an extreme case, the reciever can perform // encode for i \in {0, ..., numOTs - 1} and then call sendCorrection(recvChl, numOTs). - recv.sendCorrection(recvChl, stepSize); + recv.sendCorrection(recvChl, ss); // receive the next stepSize correction values. This allows the sender to now call encode // on the next stepSize OTs. - sender.recvCorrection(sendChl, stepSize); + sender.recvCorrection(sendChl, ss); - for (u64 k = 0; k < stepSize; ++k) + for (u64 k = 0; k < ss; ++k) { + // the sender can now call encode(i, ...) for k \in {0, ..., i}. // Lets encode the same input and then we should expect to // get the same encoding. @@ -316,7 +316,7 @@ throw UnitTestSkipped("ENALBE_KKRT is not defined."); PRNG prng0(block(4253465, 3434565)); PRNG prng1(block(42532335, 334565)); - u64 numOTs = 128 * 16; + u64 numOTs = 128 ; IOService ios(0); Session ep0(ios, "localhost", 1212, SessionMode::Server); diff --git a/libOTe_Tests/OT_Tests.cpp b/libOTe_Tests/OT_Tests.cpp index fbef403e..fb5a16b0 100644 --- a/libOTe_Tests/OT_Tests.cpp +++ b/libOTe_Tests/OT_Tests.cpp @@ -1,7 +1,7 @@ #include "OT_Tests.h" #include "libOTe/TwoChooseOne/OTExtInterface.h" - +#include "libOTe/Base/BaseOT.h" #include "libOTe/Tools/Tools.h" #include "libOTe/Tools/LinearCode.h" #include @@ -19,8 +19,6 @@ #include "libOTe/TwoChooseOne/KosDotExtReceiver.h" #include "libOTe/TwoChooseOne/KosDotExtSender.h" -#include "libOTe/TwoChooseOne/IknpDotExtReceiver.h" -#include "libOTe/TwoChooseOne/IknpDotExtSender.h" #include "libOTe/NChooseOne/Kkrt/KkrtNcoOtReceiver.h" #include "libOTe/NChooseOne/Kkrt/KkrtNcoOtSender.h" @@ -440,7 +438,113 @@ namespace tests_libOTe OT_100Receive_Test(choices, recvMsg, sendMsg); #else - throw UnitTestSkipped("ENALBE_KOS is not defined."); + throw UnitTestSkipped("ENABLE_KOS is not defined."); +#endif + } + + + + void OtExt_Kos_fs_Test() + { +#if defined(ENABLE_KOS) + setThreadName("Sender"); + + IOService ios; + Session ep0(ios, "127.0.0.1", 1212, SessionMode::Server); + Session ep1(ios, "127.0.0.1", 1212, SessionMode::Client); + Channel senderChannel = ep1.addChannel(); + Channel recvChannel = ep0.addChannel(); + + PRNG prng0(block(4253465, 3434565)); + PRNG prng1(block(42532335, 334565)); + + u64 numOTs = 20000; + + std::vector recvMsg(numOTs), baseRecv(128); + std::vector> sendMsg(numOTs), baseSend(128); + BitVector choices(numOTs), baseChoice(128); + choices.randomize(prng0); + baseChoice.randomize(prng0); + + for (u64 i = 0; i < 128; ++i) + { + baseSend[i][0] = prng0.get(); + baseSend[i][1] = prng0.get(); + baseRecv[i] = baseSend[i][baseChoice[i]]; + } + + KosOtExtSender sender; + KosOtExtReceiver recv; + + sender.mFiatShamir = true; + recv.mFiatShamir = true; + + std::thread thrd = std::thread([&]() { + setThreadName("receiver"); + + recv.setBaseOts(baseSend, prng0, recvChannel); + recv.receive(choices, recvMsg, prng0, recvChannel); + }); + + sender.setBaseOts(baseRecv, baseChoice, senderChannel); + sender.send(sendMsg, prng1, senderChannel); + thrd.join(); + + OT_100Receive_Test(choices, recvMsg, sendMsg); +#else + throw UnitTestSkipped("ENABLE_KOS is not defined."); +#endif + } + + void OtExt_Kos_ro_Test() + { +#if defined(ENABLE_KOS) + setThreadName("Sender"); + + IOService ios; + Session ep0(ios, "127.0.0.1", 1212, SessionMode::Server); + Session ep1(ios, "127.0.0.1", 1212, SessionMode::Client); + Channel senderChannel = ep1.addChannel(); + Channel recvChannel = ep0.addChannel(); + + PRNG prng0(block(4253465, 3434565)); + PRNG prng1(block(42532335, 334565)); + + u64 numOTs = 20000; + + std::vector recvMsg(numOTs), baseRecv(128); + std::vector> sendMsg(numOTs), baseSend(128); + BitVector choices(numOTs), baseChoice(128); + choices.randomize(prng0); + baseChoice.randomize(prng0); + + for (u64 i = 0; i < 128; ++i) + { + baseSend[i][0] = prng0.get(); + baseSend[i][1] = prng0.get(); + baseRecv[i] = baseSend[i][baseChoice[i]]; + } + + KosOtExtSender sender; + KosOtExtReceiver recv; + + sender.mHashType = KosOtExtSender::HashType::RandomOracle; + recv.mHashType = KosOtExtReceiver::HashType::RandomOracle; + + std::thread thrd = std::thread([&]() { + setThreadName("receiver"); + + recv.setBaseOts(baseSend, prng0, recvChannel); + recv.receive(choices, recvMsg, prng0, recvChannel); + }); + + sender.setBaseOts(baseRecv, baseChoice, senderChannel); + sender.send(sendMsg, prng1, senderChannel); + thrd.join(); + + OT_100Receive_Test(choices, recvMsg, sendMsg); +#else + throw UnitTestSkipped("ENABLE_KOS is not defined."); #endif } @@ -462,37 +566,37 @@ namespace tests_libOTe PRNG prng0(ZeroBlock); choices.randomize(prng0); baseChoice.randomize(prng0); - + for (u64 i = 0; i < 128; ++i) { baseSend[i][0] = prng0.get(); baseSend[i][1] = prng0.get(); baseRecv[i] = baseSend[i][baseChoice[i]]; } - + prng0.get(sendMsg.data(), sendMsg.size()); KosOtExtSender sender; KosOtExtReceiver recv; - auto thrd = std::thread([&]() { - PRNG prng1(OneBlock); + auto thrd = std::thread([&]() { + PRNG prng1(OneBlock); recv.setBaseOts(baseSend, prng1, recvChannel); - recv.receiveChosen(choices, recvMsg, prng1, recvChannel); + recv.receiveChosen(choices, recvMsg, prng1, recvChannel); }); sender.setBaseOts(baseRecv, baseChoice, senderChannel); sender.sendChosen(sendMsg, prng0, senderChannel); thrd.join(); - + for (u64 i = 0; i < numOTs; ++i) { if (neq(recvMsg[i], sendMsg[i][choices[i]])) throw UnitTestFail("bad message " LOCATION); } #else - throw UnitTestSkipped("ENALBE_KOS is not defined."); + throw UnitTestSkipped("ENABLE_KOS is not defined."); #endif } @@ -576,13 +680,13 @@ namespace tests_libOTe recvChannel.close(); #else - throw UnitTestSkipped("ENALBE_KOS is not defined."); + throw UnitTestSkipped("ENABLE_DELTA_KOS is not defined."); #endif } void DotExt_Iknp_Test() { -#ifdef ENABLE_DELTA_IKNP +#ifdef ENABLE_IKNP setThreadName("Sender"); @@ -599,25 +703,27 @@ namespace tests_libOTe for (u64 t = 0; t < numTrials; ++t) { u64 numOTs = 4234; - u64 s = 40; - std::vector recvMsg(numOTs), baseRecv(128 + s); - std::vector> sendMsg(numOTs), baseSend(128 + s); + std::vector recvMsg(numOTs), baseRecv(128); + std::vector> sendMsg(numOTs), baseSend(128); BitVector choices(numOTs); choices.randomize(prng0); - BitVector baseChoice(128 + s); + BitVector baseChoice(128); baseChoice.randomize(prng0); - for (u64 i = 0; i < 128 + s; ++i) + for (u64 i = 0; i < 128; ++i) { baseSend[i][0] = prng0.get(); baseSend[i][1] = prng0.get(); baseRecv[i] = baseSend[i][baseChoice[i]]; } - IknpDotExtSender sender; - IknpDotExtReceiver recv; + IknpOtExtSender sender; + IknpOtExtReceiver recv; + + sender.mHash = false; + recv.mHash = false; std::thread thrd = std::thread([&]() { setThreadName("receiver"); @@ -625,8 +731,8 @@ namespace tests_libOTe recv.receive(choices, recvMsg, prng0, recvChannel); }); - block delta = prng1.get(); - sender.setDelta(delta); + block delta = baseChoice.getArrayView()[0]; + //sender.setDelta(delta); sender.setBaseOts(baseRecv, baseChoice); sender.send(sendMsg, prng1, senderChannel); thrd.join(); @@ -636,7 +742,7 @@ namespace tests_libOTe for (auto& s : sendMsg) { if (neq(s[0] ^ delta, s[1])) - throw UnitTestFail(); + throw UnitTestFail(LOCATION); } } @@ -702,4 +808,4 @@ namespace tests_libOTe -} \ No newline at end of file +} diff --git a/libOTe_Tests/OT_Tests.h b/libOTe_Tests/OT_Tests.h index e4a7e459..40bba027 100644 --- a/libOTe_Tests/OT_Tests.h +++ b/libOTe_Tests/OT_Tests.h @@ -9,6 +9,8 @@ namespace tests_libOTe void OtExt_Kos_Test(); + void OtExt_Kos_fs_Test(); + void OtExt_Kos_ro_Test(); void DotExt_Kos_Test(); void OtExt_genBaseOts_Test(); void OtExt_Chosen_Test(); diff --git a/libOTe_Tests/SilentOT_Tests.cpp b/libOTe_Tests/SilentOT_Tests.cpp index 706db9f5..d6cd7700 100644 --- a/libOTe_Tests/SilentOT_Tests.cpp +++ b/libOTe_Tests/SilentOT_Tests.cpp @@ -9,7 +9,12 @@ #include using namespace oc; +namespace osuCrypto +{ + void bitShiftXor(span dest, span in, u8 bitShift); + void modp(span dest, span in, u64 p); +} void Tools_bitShift_test(const CLP& cmd) { @@ -175,7 +180,172 @@ void Tools_modp_test(const CLP& cmd) #endif } -void OtExt_Silent_Test(const CLP& cmd) + +#ifdef ENABLE_SILENTOT +namespace { + +#ifdef ENABLE_SILENTOT + + void fakeBase(u64 n, + u64 s, + u64 threads, + PRNG& prng, + SilentOtExtReceiver& recver, SilentOtExtSender& sender) + { + sender.configure(n, s, threads); + auto count = sender.silentBaseOtCount(); + std::vector> msg2(count); + for (u64 i = 0; i < msg2.size(); ++i) + { + msg2[i][0] = prng.get(); + msg2[i][1] = prng.get(); + } + sender.setSilentBaseOts(msg2); + + // fake base OTs. + { + recver.configure(n, s, threads); + BitVector choices = recver.sampleBaseChoiceBits(prng); + std::vector msg(choices.size()); + for (u64 i = 0; i < msg.size(); ++i) + msg[i] = msg2[i][choices[i]]; + recver.setSilentBaseOts(msg); + } + } + + void checkRandom( + span messages, span>messages2, + BitVector& choice, u64 n, + bool verbose) + { + + if (messages.usize() != n) + throw RTE_LOC; + if (messages2.usize() != n) + throw RTE_LOC; + if (choice.size() != n) + throw RTE_LOC; + bool passed = true; + + for (u64 i = 0; i < n; ++i) + { + block m1 = messages[i]; + block m2a = messages2[i][0]; + block m2b = (messages2[i][1]); + u8 c = choice[i]; + + + std::array eqq{ + eq(m1, m2a), + eq(m1, m2b) + }; + if (eqq[c] == false || eqq[c ^ 1] == true) + { + passed = false; + if (verbose) + std::cout << Color::Pink; + } + if (eqq[0] == false && eqq[1] == false) + { + passed = false; + if (verbose) + std::cout << Color::Red; + } + } + + if (passed == false) + throw RTE_LOC; + } + + + template + void checkCorrelated( + span Ar, span Bs, + Choice& choice, block delta, u64 n, + bool verbose, + ChoiceBitPacking packing) + { + + if (Ar.usize() != n) + throw RTE_LOC; + if (Bs.usize() != n) + throw RTE_LOC; + if (packing == ChoiceBitPacking::False && + (u64)choice.size() != n) + throw RTE_LOC; + bool passed = true; + //bool first = true; + block mask = AllOneBlock ^ OneBlock; + + + for (u64 i = 0; i < n; ++i) + { + block m1 = Ar[i]; + block m2a = Bs[i]; + block m2b = (Bs[i] ^ delta); + u8 c, c2; + + if (packing == ChoiceBitPacking::True) + { + c = u8((m1 & OneBlock) == OneBlock) & 1; + m1 = m1 & mask; + m2a = m2a & mask; + m2b = m2b & mask; + + if (choice.size()) + { + c2 = choice[i]; + + if (c2 != c) + throw RTE_LOC; + } + } + else + { + c = choice[i]; + } + + std::array eqq{ + eq(m1, m2a), + eq(m1, m2b) + }; + + bool good = true; + if (eqq[c] == false || eqq[c ^ 1] == true) + { + good = passed = false; + //if (verbose) + std::cout << Color::Pink; + } + if (eqq[0] == false && eqq[1] == false) + { + good = passed = false; + //if (verbose) + std::cout << Color::Red; + } + + if (!good /*&& first*/) + { + //first = false; + std::cout << i << " m " << mask << std::endl; + std::cout << "r " << m1 << " " << int(c) << std::endl; + std::cout << "s " << m2a << " " << m2b << std::endl; + std::cout << "d " << (m1 ^ m2a) << " " << (m1 ^ m2b) << std::endl; + } + + std::cout << Color::Default; + } + + if (passed == false) + throw RTE_LOC; + } + +#endif +} +#endif + + +void OtExt_Silent_random_Test(const CLP& cmd) { #ifdef ENABLE_SILENTOT @@ -184,21 +354,97 @@ void OtExt_Silent_Test(const CLP& cmd) Session s1(ios, "localhost:1212", SessionMode::Client); + u64 n = cmd.getOr("n", 10000); + bool verbose = cmd.getOr("v", 0) > 1; + u64 threads = cmd.getOr("t", 4); + u64 s = cmd.getOr("s", 2); + + Channel chl0 = s0.addChannel(); + Channel chl1 = s1.addChannel(); + PRNG prng(toBlock(cmd.getOr("seed", 0))); + PRNG prng1(toBlock(cmd.getOr("seed1", 1))); + + + SilentOtExtSender sender; + SilentOtExtReceiver recver; + fakeBase(n, s, threads, prng, recver, sender); + auto type = OTType::Random; + + std::vector messages2(n); + BitVector choice(n); + std::vector> messages(n); + + auto thrd = std::thread([&] { + sender.silentSend(messages, prng, chl0); }); + recver.silentReceive(choice, messages2, prng, chl1, type); + + thrd.join(); + checkRandom(messages2, messages, choice, n, verbose); + +#else + throw UnitTestSkipped("ENABLE_SILENTOT not defined."); +#endif +} + + +void OtExt_Silent_correlated_Test(const CLP& cmd) +{ +#ifdef ENABLE_SILENTOT + + IOService ios; + Session s0(ios, "localhost:1212", SessionMode::Server); + Session s1(ios, "localhost:1212", SessionMode::Client); u64 n = cmd.getOr("n", 10000); bool verbose = cmd.getOr("v", 0) > 1; u64 threads = cmd.getOr("t", 4); - u64 s = cmd.getOr("s", 4); - u64 sec = cmd.getOr("sec", 80); - //bool mal = cmd.isSet("mal"); + u64 s = cmd.getOr("s", 2); - std::vector chls0(threads), chls1(threads); + Channel chl0 = s0.addChannel(); + Channel chl1 = s1.addChannel(); + PRNG prng(toBlock(cmd.getOr("seed", 0))); + PRNG prng1(toBlock(cmd.getOr("seed1", 1))); - for (u64 i = 0; i < threads; ++i) - { - chls0[i] = s0.addChannel(); - chls1[i] = s1.addChannel(); - } + + SilentOtExtSender sender; + SilentOtExtReceiver recver; + fakeBase(n, s, threads, prng, recver, sender); + + block delta = prng.get(); + + std::vector messages2(n); + BitVector choice(n); + std::vector messages(n); + auto type = OTType::Correlated; + + sender.silentSend(delta, messages, prng, chl0); + recver.silentReceive(choice, messages2, prng, chl1, type); + + checkCorrelated( + messages, messages2, choice, delta, + n, verbose, ChoiceBitPacking::False); +#else + throw UnitTestSkipped("ENABLE_SILENTOT not defined."); +#endif +} + + + +void OtExt_Silent_inplace_Test(const CLP& cmd) +{ +#ifdef ENABLE_SILENTOT + + IOService ios; + Session s0(ios, "localhost:1212", SessionMode::Server); + Session s1(ios, "localhost:1212", SessionMode::Client); + + u64 n = cmd.getOr("n", 10000); + bool verbose = cmd.getOr("v", 0) > 1; + u64 threads = cmd.getOr("t", 4); + u64 s = cmd.getOr("s", 2); + + Channel chl0 = s0.addChannel(); + Channel chl1 = s1.addChannel(); PRNG prng(toBlock(cmd.getOr("seed", 0))); PRNG prng1(toBlock(cmd.getOr("seed1", 1))); @@ -207,83 +453,178 @@ void OtExt_Silent_Test(const CLP& cmd) SilentOtExtSender sender; SilentOtExtReceiver recver; - Timer timer; - sender.setTimer(timer); - recver.setTimer(timer); + block delta = prng.get(); - //sender.mDebug = true; - //recver.mDebug = true; - //recver.mGen.mPrint = false; + //auto type = OTType::Correlated; - // fake base OTs. { - recver.configure(n, s, sec, threads); - BitVector choices = recver.sampleBaseChoiceBits(prng); - std::vector msg(choices.size()); - for (u64 i = 0; i < msg.size(); ++i) - msg[i] = toBlock(i, choices[i]); - recver.setSlientBaseOts(msg); + fakeBase(n, s, threads, prng, recver, sender); + sender.silentSendInplace(delta, n, prng, chl0); + recver.silentReceiveInplace(n, prng, chl1); + auto& messages = recver.mA; + auto& messages2 = sender.mB; + auto& choice = recver.mC; + checkCorrelated(messages, messages2, choice, delta, + n, verbose, ChoiceBitPacking::False); } { - sender.configure(n, s, sec, threads); - auto count = sender.silentBaseOtCount(); - std::vector> msg(count); - PRNG prngz(ZeroBlock); - for (u64 i = 0; i < msg.size(); ++i) - { - msg[i][0] = toBlock(i, 0); - msg[i][1] = toBlock(i, 1); - } - sender.setSlientBaseOts(msg); + fakeBase(n, s, threads, prng, recver, sender); + sender.silentSendInplace(delta, n, prng, chl0); + recver.silentReceiveInplace(n, prng, chl1, ChoiceBitPacking::True); + + auto& messages = recver.mA; + auto& messages2 = sender.mB; + auto& choice = recver.mC; + checkCorrelated(messages, messages2, choice, delta, + n, verbose, ChoiceBitPacking::True); + + } +#else + throw UnitTestSkipped("ENABLE_SILENTOT not defined."); +#endif } - std::vector messages2(n); - BitVector choice; - std::vector> messages(n); +void OtExt_Silent_paramSweep_Test(const oc::CLP& cmd) +{ +#ifdef ENABLE_SILENTOT - sender.silentSend(messages, prng, chls0); - recver.silentReceive(choice, messages2, prng, chls1); - bool passed = true; - BitVector act(n); - choice.resize(n); - for (u64 i = 0; i < n; ++i) + IOService ios; + Session s0(ios, "localhost:1212", SessionMode::Server); + Session s1(ios, "localhost:1212", SessionMode::Client); + + std::vector nn = cmd.getManyOr("n", + { 12, /*134,*/433 , /*4234,*/5466 }); + + bool verbose = cmd.getOr("v", 0) > 1; + u64 threads = cmd.getOr("t", 4); + u64 s = cmd.getOr("s", 2); + + Channel chl0 = s0.addChannel(); + Channel chl1 = s1.addChannel(); + + PRNG prng(toBlock(cmd.getOr("seed", 0))); + PRNG prng1(toBlock(cmd.getOr("seed1", 1))); + + SilentOtExtSender sender; + SilentOtExtReceiver recver; + + block delta = prng.get(); + //auto type = OTType::Correlated; + + for (auto n : nn) { - std::array eqq{ eq(messages2[i], messages[i][0]),eq(messages2[i], messages[i][1]) }; - if (eqq[choice[i]] == false || eqq[choice[i] ^ 1] == true) - { - passed = false; - if (verbose) - std::cout << Color::Pink; - } - if (eqq[0] == false && eqq[1] == false) - { - passed = false; - if (verbose) - std::cout << Color::Red; - } + fakeBase(n, s, threads, prng, recver, sender); + + sender.silentSendInplace(delta, n, prng, chl0); + recver.silentReceiveInplace(n, prng, chl1); - if (verbose) - std::cout << i << " " << messages2[i] << " " << messages[i][0] << " " << messages[i][1] << " " << int(choice[i]) << std::endl << Color::Default; + checkCorrelated(sender.mB, recver.mA, recver.mC, delta, + n, verbose, ChoiceBitPacking::False); + } - if (eq(messages2[i], messages[i][1])) - act[i] = 1; +#else + throw UnitTestSkipped("ENABLE_SILENTOT not defined."); +#endif } - if (verbose) + +void OtExt_Silent_QuasiCyclic_Test(const oc::CLP& cmd) +{ +#if defined(ENABLE_SILENTOT) && defined(ENABLE_BITPOLYMUL) + IOService ios; + Session s0(ios, "localhost:1212", SessionMode::Server); + Session s1(ios, "localhost:1212", SessionMode::Client); + + std::vector nn = cmd.getManyOr("n", + { /*12, 134, 600,*/ 4234/*, 14366 */});// + + bool verbose = cmd.getOr("v", 0) > 1; + u64 threads = cmd.getOr("t", 4); + u64 s = cmd.getOr("s", 2); + + Channel chl0 = s0.addChannel(); + Channel chl1 = s1.addChannel(); + + PRNG prng(toBlock(cmd.getOr("seed", 0))); + PRNG prng1(toBlock(cmd.getOr("seed1", 1))); + + SilentOtExtSender sender; + SilentOtExtReceiver recver; + + sender.mMultType = MultType::QuasiCyclic; + recver.mMultType = MultType::QuasiCyclic; + + //sender.mDebug = true; + //recver.mDebug = true; + + block delta = prng.get(); + //auto type = OTType::Correlated; + + for (auto n : nn) { - std::cout << "act ham " << act.hammingWeight() << " " << act.size() << std::endl; - std::cout << "ret ham " << choice.hammingWeight() << " " << choice.size() << std::endl; + + std::vector> msg2(n); + std::vector msg1(n); + BitVector choice(n); + + fakeBase(n, s, threads, prng, recver, sender); + sender.silentSend(msg2, prng, chl0); + recver.silentReceive(choice, msg1, prng, chl1); + checkRandom(msg1, msg2, choice, n, verbose); + + auto type = ChoiceBitPacking::False; + fakeBase(n, s, threads, prng, recver, sender); + sender.silentSendInplace(delta, n, prng, chl0); + recver.silentReceiveInplace(n, prng, chl1, type); + checkCorrelated(recver.mA, sender.mB, recver.mC, delta, n, verbose, type); + } - if (cmd.isSet("v")) - std::cout << timer << std::endl; +#else + throw UnitTestSkipped("ENABLE_SILENTOT or ENABLE_BITPOLYMUL are not defined."); +#endif + } - if (passed == false) - throw RTE_LOC; - +void OtExt_Silent_baseOT_Test(const oc::CLP& cmd) +{ + +#ifdef ENABLE_SILENTOT + IOService ios; + Session s0(ios, "localhost:1212", SessionMode::Server); + Session s1(ios, "localhost:1212", SessionMode::Client); + u64 n = 123;// + + bool verbose = cmd.getOr("v", 0) > 1; + //u64 threads = cmd.getOr("t", 4); + //u64 s = cmd.getOr("s", 2); + + Channel chl0 = s0.addChannel(); + Channel chl1 = s1.addChannel(); + + PRNG prng(toBlock(cmd.getOr("seed", 0))); + PRNG prng1(toBlock(cmd.getOr("seed1", 1))); + + SilentOtExtSender sender; + SilentOtExtReceiver recver; + + //block delta = prng.get(); + //auto type = OTType::Correlated; + + std::vector> msg2(n); + std::vector msg1(n); + BitVector choice(n); + + auto thrd = std::thread([&] { + sender.silentSend(msg2, prng, chl0); + }); + recver.silentReceive(choice, msg1, prng, chl1); + + thrd.join(); + + checkRandom(msg1, msg2, choice, n, verbose); #else throw UnitTestSkipped("ENABLE_SILENTOT not defined."); #endif @@ -291,6 +632,49 @@ void OtExt_Silent_Test(const CLP& cmd) +void OtExt_Silent_mal_Test(const oc::CLP& cmd) +{ + +#ifdef ENABLE_SILENTOT + IOService ios; + Session s0(ios, "localhost:1212", SessionMode::Server); + Session s1(ios, "localhost:1212", SessionMode::Client); + + u64 n = 12093;// + + bool verbose = cmd.getOr("v", 0) > 1; + //u64 threads = cmd.getOr("t", 4); + //u64 s = cmd.getOr("s", 2); + + Channel chl0 = s0.addChannel(); + Channel chl1 = s1.addChannel(); + + PRNG prng(toBlock(cmd.getOr("seed", 0))); + PRNG prng1(toBlock(cmd.getOr("seed1", 1))); + + SilentOtExtSender sender; + SilentOtExtReceiver recver; + + sender.mMalType = SilentSecType::Malicious; + recver.mMalType = SilentSecType::Malicious; + + std::vector> msg2(n); + std::vector msg1(n); + BitVector choice(n); + + auto thrd = std::thread([&] { + sender.silentSend(msg2, prng, chl0); + }); + recver.silentReceive(choice, msg1, prng, chl1); + + thrd.join(); + + checkRandom(msg1, msg2, choice, n, verbose); +#else + throw UnitTestSkipped("ENABLE_SILENTOT not defined."); +#endif +} + void Tools_Pprf_test(const CLP& cmd) { #ifdef ENABLE_SILENTOT @@ -307,15 +691,11 @@ void Tools_Pprf_test(const CLP& cmd) Session s1(ios, "localhost:1212", SessionMode::Client); - std::vector chls0(threads), chls1(threads); - - for (u64 i = 0; i < threads; ++i) - { - chls0[i] = s0.addChannel(); - chls1[i] = s1.addChannel(); - } + auto chl0 = s0.addChannel(); + auto chl1 = s1.addChannel(); + auto format = PprfOutputFormat::Plain; SilentMultiPprfSender sender; SilentMultiPprfReceiver recver; @@ -325,7 +705,7 @@ void Tools_Pprf_test(const CLP& cmd) auto numOTs = sender.baseOtCount(); std::vector> sendOTs(numOTs); std::vector recvOTs(numOTs); - BitVector recvBits = recver.sampleChoiceBits(domain, false, prng); + BitVector recvBits = recver.sampleChoiceBits(domain, format, prng); //prng.get(sendOTs.data(), sendOTs.size()); //sendOTs[cmd.getOr("i",0)] = prng.get(); @@ -342,10 +722,10 @@ void Tools_Pprf_test(const CLP& cmd) Matrix sOut(domain, numPoints); Matrix rOut(domain, numPoints); std::vector points(numPoints); - recver.getPoints(points); + recver.getPoints(points, format); - sender.expand(chls0, CCBlock, prng, sOut, false, false); - recver.expand(chls1, prng, rOut, false, false); + sender.expand(chl0, CCBlock, prng, sOut, format, threads); + recver.expand(chl1, prng, rOut, format, threads); bool failed = false; @@ -390,7 +770,7 @@ void Tools_Pprf_trans_test(const CLP& cmd) u64 domain = cmd.getOr("d", 334); auto threads = cmd.getOr("t", 3ull); u64 numPoints = cmd.getOr("s", 5) * 8; - bool mal = cmd.isSet("mal"); + //bool mal = cmd.isSet("mal"); PRNG prng(ZeroBlock); @@ -398,16 +778,13 @@ void Tools_Pprf_trans_test(const CLP& cmd) Session s0(ios, "localhost:1212", SessionMode::Server); Session s1(ios, "localhost:1212", SessionMode::Client); - std::vector chls0(threads), chls1(threads); - for (u64 i = 0; i < threads; ++i) - { - chls0[i] = s0.addChannel(); - chls1[i] = s1.addChannel(); - } + auto chl0 = s0.addChannel(); + auto chl1 = s1.addChannel(); + auto format = PprfOutputFormat::InterleavedTransposed; SilentMultiPprfSender sender; SilentMultiPprfReceiver recver; @@ -417,7 +794,7 @@ void Tools_Pprf_trans_test(const CLP& cmd) auto numOTs = sender.baseOtCount(); std::vector> sendOTs(numOTs); std::vector recvOTs(numOTs); - BitVector recvBits = recver.sampleChoiceBits(domain * numPoints, true, prng); + BitVector recvBits = recver.sampleChoiceBits(domain * numPoints, format, prng); //recvBits.randomize(prng); //recvBits[16] = 1; @@ -432,14 +809,15 @@ void Tools_Pprf_trans_test(const CLP& cmd) auto cols = (numPoints * domain + 127) / 128; Matrix sOut(128, cols); Matrix rOut(128, cols); + std::vector points(numPoints); - recver.getTransposedPoints(points); + recver.getPoints(points, format); - sender.expand(chls0, AllOneBlock, prng, sOut, true, mal); - recver.expand(chls1, prng, rOut, true, mal); + sender.expand(chl0, AllOneBlock, prng, sOut, format, threads); + recver.expand(chl1, prng, rOut, format, threads); bool failed = false; Matrix out(128, cols); @@ -485,3 +863,95 @@ void Tools_Pprf_trans_test(const CLP& cmd) throw UnitTestSkipped("ENABLE_SILENTOT not defined."); #endif } + + +void Tools_Pprf_inter_test(const CLP& cmd) +{ +#ifdef ENABLE_SILENTOT + + //u64 depth = 6; + //u64 domain = 13;// (1ull << depth) - 7; + //u64 numPoints = 40; + + u64 domain = cmd.getOr("d", 334); + auto threads = cmd.getOr("t", 3ull); + u64 numPoints = cmd.getOr("s", 5) * 8; + //bool mal = cmd.isSet("mal"); + + PRNG prng(ZeroBlock); + + IOService ios; + Session s0(ios, "localhost:1212", SessionMode::Server); + Session s1(ios, "localhost:1212", SessionMode::Client); + + + auto chl0 = s0.addChannel(); + auto chl1 = s1.addChannel(); + + + + auto format = PprfOutputFormat::Interleaved; + SilentMultiPprfSender sender; + SilentMultiPprfReceiver 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; + 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); + + + sender.expand(chl0, AllOneBlock, prng, sOut2, format, threads); + recver.expand(chl1, prng, rOut2, format, threads); + + for (u64 i = 0; i < rOut2.rows(); ++i) + { + sOut2(i) = (sOut2(i) ^ rOut2(i)); + } + + + bool failed = false; + for (u64 i = 0; i < sOut2.rows(); ++i) + { + + auto f = std::find(points.begin(), points.end(), i) != points.end(); + + auto exp = f ? AllOneBlock : ZeroBlock; + + if (neq(sOut2(i), exp)) + { + failed = true; + + if (cmd.getOr("v", 0) > 1) + std::cout << Color::Red; + } + if (cmd.getOr("v", 0) > 1) + std::cout << i << " " << sOut2(i) << " " << exp << std::endl << Color::Default; + } + + if (failed) + throw RTE_LOC; + + +#else + throw UnitTestSkipped("ENABLE_SILENTOT not defined."); +#endif +} diff --git a/libOTe_Tests/SilentOT_Tests.h b/libOTe_Tests/SilentOT_Tests.h index cb8d2252..f3eda2a5 100644 --- a/libOTe_Tests/SilentOT_Tests.h +++ b/libOTe_Tests/SilentOT_Tests.h @@ -3,7 +3,14 @@ void Tools_Pprf_test(const oc::CLP& cmd); void Tools_Pprf_trans_test(const oc::CLP& cmd); -void OtExt_Silent_Test(const oc::CLP& cmd); +void Tools_Pprf_inter_test(const oc::CLP& cmd); +void OtExt_Silent_random_Test(const oc::CLP& cmd); +void OtExt_Silent_correlated_Test(const oc::CLP& cmd); +void OtExt_Silent_inplace_Test(const oc::CLP& cmd); +void OtExt_Silent_paramSweep_Test(const oc::CLP& cmd); +void OtExt_Silent_QuasiCyclic_Test(const oc::CLP& cmd); +void OtExt_Silent_baseOT_Test(const oc::CLP& cmd); +void OtExt_Silent_mal_Test(const oc::CLP& cmd); void Tools_bitShift_test(const oc::CLP& cmd); void Tools_modp_test(const oc::CLP& cmd); diff --git a/libOTe_Tests/UnitTests.cpp b/libOTe_Tests/UnitTests.cpp index 5c60b25c..4df0c6ba 100644 --- a/libOTe_Tests/UnitTests.cpp +++ b/libOTe_Tests/UnitTests.cpp @@ -20,42 +20,60 @@ namespace tests_libOTe //void OtExt_genBaseOts_Test() - tc.add("Tools_Transpose_View_Test ", Tools_Transpose_View_Test); - tc.add("Tools_Transpose_Test ", Tools_Transpose_Test); - - tc.add("Tools_LinearCode_Test ", Tools_LinearCode_Test); - tc.add("Tools_LinearCode_sub_Test ", Tools_LinearCode_sub_Test); - tc.add("Tools_LinearCode_rep_Test ", Tools_LinearCode_rep_Test); - - tc.add("Tools_bitShift_test ", Tools_bitShift_test); - tc.add("Tools_modp_test ", Tools_modp_test); - tc.add("Tools_bitpolymul_test ", Tools_bitpolymul_test); - - tc.add("Tools_Pprf_test ", Tools_Pprf_test); - tc.add("Tools_Pprf_trans_test ", Tools_Pprf_trans_test); - - tc.add("Bot_NaorPinkas_Test ", Bot_NaorPinkas_Test); - tc.add("Bot_Simplest_Test ", Bot_Simplest_Test); - tc.add("Bot_MasnyRindal_Test ", Bot_MasnyRindal_Test); - tc.add("Bot_MasnyRindal_Kyber_Test ", Bot_MasnyRindal_Kyber_Test); - - tc.add("OtExt_genBaseOts_Test ", OtExt_genBaseOts_Test); - tc.add("OtExt_Chosen_Test ", OtExt_Chosen_Test); - tc.add("OtExt_Iknp_Test ", OtExt_Iknp_Test); - tc.add("OtExt_Kos_Test ", OtExt_Kos_Test); - tc.add("OtExt_Silent_Test ", OtExt_Silent_Test); - - tc.add("DotExt_Kos_Test ", DotExt_Kos_Test); - tc.add("DotExt_Iknp_Test ", DotExt_Iknp_Test); - - tc.add("NcoOt_Kkrt_Test ", NcoOt_Kkrt_Test); - tc.add("NcoOt_Oos_Test ", NcoOt_Oos_Test); - tc.add("NcoOt_Rr17_Test ", NcoOt_Rr17_Test); - tc.add("NcoOt_genBaseOts_Test ", NcoOt_genBaseOts_Test); - - tc.add("AknOt_sendRecv1000_Test ", AknOt_sendRecv1000_Test); - - + tc.add("Tools_Transpose_View_Test ", Tools_Transpose_View_Test); + tc.add("Tools_Transpose_Test ", Tools_Transpose_Test); + + tc.add("Tools_LinearCode_Test ", Tools_LinearCode_Test); + tc.add("Tools_LinearCode_sub_Test ", Tools_LinearCode_sub_Test); + tc.add("Tools_LinearCode_rep_Test ", Tools_LinearCode_rep_Test); + + tc.add("Tools_bitShift_test ", Tools_bitShift_test); + tc.add("Tools_modp_test ", Tools_modp_test); + tc.add("Tools_bitpolymul_test ", Tools_bitpolymul_test); + + + tc.add("Tools_Pprf_test ", Tools_Pprf_test); + tc.add("Tools_Pprf_trans_test ", Tools_Pprf_trans_test); + tc.add("Tools_Pprf_inter_test ", Tools_Pprf_inter_test); + + tc.add("Bot_NaorPinkas_Test ", Bot_NaorPinkas_Test); + tc.add("Bot_Simplest_Test ", Bot_Simplest_Test); + + tc.add("Bot_McQuoidRR_Moeller_EKE_Test ", Bot_McQuoidRR_Moeller_EKE_Test); + tc.add("Bot_McQuoidRR_Moeller_MR_Test ", Bot_McQuoidRR_Moeller_MR_Test); + tc.add("Bot_McQuoidRR_Moeller_F_Test ", Bot_McQuoidRR_Moeller_F_Test); + tc.add("Bot_McQuoidRR_Moeller_FM_Test ", Bot_McQuoidRR_Moeller_FM_Test); + tc.add("Bot_McQuoidRR_Ristrestto_F_Test ", Bot_McQuoidRR_Ristrestto_F_Test); + tc.add("Bot_McQuoidRR_Ristrestto_FM_Test ", Bot_McQuoidRR_Ristrestto_FM_Test); + + tc.add("Bot_MasnyRindal_Test ", Bot_MasnyRindal_Test); + tc.add("Bot_MasnyRindal_Kyber_Test ", Bot_MasnyRindal_Kyber_Test); + + tc.add("OtExt_genBaseOts_Test ", OtExt_genBaseOts_Test); + tc.add("OtExt_Chosen_Test ", OtExt_Chosen_Test); + tc.add("OtExt_Iknp_Test ", OtExt_Iknp_Test); + tc.add("OtExt_Kos_Test ", OtExt_Kos_Test); + tc.add("OtExt_Kos_fs_Test ", OtExt_Kos_fs_Test); + tc.add("OtExt_Kos_ro_Test ", OtExt_Kos_ro_Test); + tc.add("OtExt_Silent_random_Test ", OtExt_Silent_random_Test); + tc.add("OtExt_Silent_correlated_Test ", OtExt_Silent_correlated_Test); + tc.add("OtExt_Silent_inplace_Test ", OtExt_Silent_inplace_Test); + tc.add("OtExt_Silent_paramSweep_Test ", OtExt_Silent_paramSweep_Test); + tc.add("OtExt_Silent_QuasiCyclic_Test ", OtExt_Silent_QuasiCyclic_Test); + tc.add("OtExt_Silent_baseOT_Test ", OtExt_Silent_baseOT_Test); + tc.add("OtExt_Silent_mal_Test ", OtExt_Silent_mal_Test); + + tc.add("DotExt_Kos_Test ", DotExt_Kos_Test); + tc.add("DotExt_Iknp_Test ", DotExt_Iknp_Test); + + tc.add("NcoOt_Kkrt_Test ", NcoOt_Kkrt_Test); + tc.add("NcoOt_Oos_Test ", NcoOt_Oos_Test); + tc.add("NcoOt_Rr17_Test ", NcoOt_Rr17_Test); + tc.add("NcoOt_genBaseOts_Test ", NcoOt_genBaseOts_Test); + + tc.add("AknOt_sendRecv1000_Test ", AknOt_sendRecv1000_Test); + + }); diff --git a/libOTe_Tests/bitpolymul_Tests.cpp b/libOTe_Tests/bitpolymul_Tests.cpp index f2d96a8b..81177bdc 100644 --- a/libOTe_Tests/bitpolymul_Tests.cpp +++ b/libOTe_Tests/bitpolymul_Tests.cpp @@ -4,7 +4,6 @@ #include "libOTe/Tools/bitpolymul.h" -#include "libOTe/Tools/bitpolymul/bpmDefines.h" #include #include #include @@ -15,18 +14,41 @@ #define bm_func2 bitpolymul_2_128 +template +struct toStr_ { + const T& mV; + toStr_(const T& v) : mV(v) {} + + +}; +template +inline toStr_ toStr(const T& v) +{ + return toStr_(v); +} +template +inline std::ostream& operator<<(std::ostream& o, const toStr_& t) +{ + o << "[" << t.mV.size() << "]["; + for (const auto& v : t.mV) + { + o << v << ", "; + } + o << "]"; + return o; +} using namespace oc; -using namespace bpm; void Tools_bitpolymul_test(const CLP& cmd) { -#ifdef ENABLE_SILENTOT +#ifdef ENABLE_BITPOLYMUL + using namespace bpm; uint64_t TEST_RUN = cmd.getOr("t", 4); uint64_t len = (1ull << cmd.getOr("n", 12)); - bpm::aligned_vector + aligned_vector poly1(len), poly2(len), poly3(len), @@ -76,7 +98,7 @@ void Tools_bitpolymul_test(const CLP& cmd) } - bpm::FFTPoly fft1, fft2, fft3, fft_12, fft_13; + FFTPoly fft1, fft2, fft3, fft_12, fft_13; auto vecAdd = [](std::vector a, std::vector& b) { for (oc::u64 i = 0; i < a.size(); ++i) @@ -151,7 +173,7 @@ void Tools_bitpolymul_test(const CLP& cmd) fft_12.decode(poly_12, false); fft_13.decode(poly_13, false); - bpm::FFTPoly fft_12_13; + FFTPoly fft_12_13; fft_12_13.add(fft_13, fft_12); auto poly_r = vecAdd(poly_12, poly_13); diff --git a/libOTe_Tests/cmakeTests/CMakeLists.txt b/libOTe_Tests/cmakeTests/CMakeLists.txt new file mode 100644 index 00000000..20e03d80 --- /dev/null +++ b/libOTe_Tests/cmakeTests/CMakeLists.txt @@ -0,0 +1,8 @@ + cmake_minimum_required(VERSION 3.15) +project(cmakeTest) + +add_executable(main main.cpp) + +find_package(libOTe REQUIRED HINTS ${LIBOTE_HINT}) + +target_link_libraries(main oc::libOTe) \ No newline at end of file diff --git a/libOTe_Tests/cmakeTests/main.cpp b/libOTe_Tests/cmakeTests/main.cpp new file mode 100644 index 00000000..b05ccd37 --- /dev/null +++ b/libOTe_Tests/cmakeTests/main.cpp @@ -0,0 +1,12 @@ + + +#include "libOTe/Tools/Tools.h" + +int main() +{ + using namespace oc; + MatrixView in, out; + // call a function that requires linking... + transpose(in , out); + return 0; +} \ No newline at end of file diff --git a/libOTe_Tests/libOTe_Tests.vcxproj.filters b/libOTe_Tests/libOTe_Tests.vcxproj.filters deleted file mode 100644 index 7024a870..00000000 --- a/libOTe_Tests/libOTe_Tests.vcxproj.filters +++ /dev/null @@ -1,111 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/libOTe_Tests/libOTe_Tests.vcxproj.vcxproj b/libOTe_Tests/libOTe_Tests.vcxproj.vcxproj deleted file mode 100644 index 1c2342d7..00000000 --- a/libOTe_Tests/libOTe_Tests.vcxproj.vcxproj +++ /dev/null @@ -1,166 +0,0 @@ - - - - - Debug_DLLRT - x64 - - - Debug - x64 - - - Release_DLLRT - x64 - - - Release - x64 - - - - {294C00B6-949E-4A45-AFA8-45D53590FC11} - libOTe_Tests - libOTe_Tests - 10.0 - - - - StaticLibrary - true - v142 - MultiByte - - - StaticLibrary - true - v142 - MultiByte - - - StaticLibrary - false - v142 - true - MultiByte - - - StaticLibrary - false - v142 - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - Level3 - Disabled - true - $(ProjectDir)..;$(ProjectDir)../cryptoTools/;$(ProjectDir)../cryptoTools/thirdparty\win\boost\;$(ProjectDir)../cryptoTools/thirdparty\win\;$(ProjectDir)../cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/miracl - MultiThreadedDebug - SOLUTION_DIR=R"**($(SolutionDir))**";_WIN32_WINNT=0x0501;_MBCS;%(PreprocessorDefinitions) - true - true - false - - - - - Level3 - Disabled - true - $(ProjectDir)..;$(ProjectDir)../cryptoTools/;$(ProjectDir)../cryptoTools/thirdparty\win\boost\;$(ProjectDir)../cryptoTools/thirdparty\win\;$(ProjectDir)../cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/miracl - MultiThreadedDebugDLL - SOLUTION_DIR=R"**($(SolutionDir))**";_WIN32_WINNT=0x0501;_MBCS;%(PreprocessorDefinitions) - true - true - false - - - - - Level3 - MaxSpeed - true - true - true - $(ProjectDir)..;$(ProjectDir)../cryptoTools/;$(ProjectDir)../cryptoTools/thirdparty\win\boost\;$(ProjectDir)../cryptoTools/thirdparty\win\;$(ProjectDir)../cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/miracl - MultiThreaded - SOLUTION_DIR=R"**($(SolutionDir))**";_WIN32_WINNT=0x0501;_MBCS;%(PreprocessorDefinitions) - true - true - - - true - true - - - - - Level3 - MaxSpeed - true - true - true - $(ProjectDir)..;$(ProjectDir)../cryptoTools/;$(ProjectDir)../cryptoTools/thirdparty\win\boost\;$(ProjectDir)../cryptoTools/thirdparty\win\;$(ProjectDir)../cryptoTools/thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/miracl - MultiThreadedDLL - SOLUTION_DIR=R"**($(SolutionDir))**";_WIN32_WINNT=0x0501;_MBCS;%(PreprocessorDefinitions) - true - true - - - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libOTe_TestsVS/AknOT_TestsVS.cpp b/libOTe_TestsVS/AknOT_TestsVS.cpp deleted file mode 100644 index 7c9a02dc..00000000 --- a/libOTe_TestsVS/AknOT_TestsVS.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "stdafx.h" -#ifdef _MSC_VER -#include "CppUnitTest.h" -#include "AknOt_Tests.h" -#include "Common.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; -// -//void BitVector_Indexing_Test_Impl(); -//void BitVector_Parity_Test_Impl(); -//void BitVector_Append_Test_Impl(); -//void BitVector_Copy_Test_Impl(); -// -//void Transpose_Test_Impl(); -// -// -// -//void OTExt_100Receive_Test_Impl(); -//void KosOtExt_Setup_Test_Impl(); - - - -namespace tests_libOTe -{ - TEST_CLASS(AknOtTests) - { - public: - - TEST_METHOD(AknOt_sendRecv_TestVS) - { - InitDebugPrinting(); - AknOt_sendRecv1000_Test(); - } - - }; -} -#endif \ No newline at end of file diff --git a/libOTe_TestsVS/BaseOT_TestsVS.cpp b/libOTe_TestsVS/BaseOT_TestsVS.cpp deleted file mode 100644 index 3970c500..00000000 --- a/libOTe_TestsVS/BaseOT_TestsVS.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "stdafx.h" -#ifdef _MSC_VER -#include "CppUnitTest.h" -#include "BaseOT_Tests.h" -#include "Common.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -namespace tests_libOTe -{ - TEST_CLASS(BaseOT_Tests) - { - public: - - TEST_METHOD(NaorPinkasOt_TestVS) - { - InitDebugPrinting(); - NaorPinkasOt_Test_Impl(); - } - - }; -} -#endif \ No newline at end of file diff --git a/libOTe_TestsVS/OT_TestsVS.cpp b/libOTe_TestsVS/OT_TestsVS.cpp deleted file mode 100644 index 93635e05..00000000 --- a/libOTe_TestsVS/OT_TestsVS.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "stdafx.h" -#ifdef _MSC_VER -#include "CppUnitTest.h" -#include "OT_Tests.h" -#include "NcoOT_Tests.h" -#include "Common.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -namespace tests_libOTe -{ - TEST_CLASS(OT_Tests) - { - public: - - TEST_METHOD(Transpose_TestVS) - { - InitDebugPrinting(); - Transpose_Test_Impl(); - } - - TEST_METHOD(TransposeMatrixView_TestVS) - { - InitDebugPrinting(); - TransposeMatrixView_Test_Impl(); - } - - TEST_METHOD(Iknp_200Receive_TestVS) - { - InitDebugPrinting(); - IknpOtExt_100Receive_Test_Impl(); - } - - - - TEST_METHOD(Kos_200Receive_TestVS) - { - InitDebugPrinting(); - KosOtExt_100Receive_Test_Impl(); - } - - TEST_METHOD(OtExt_genBaseOts_TestVS) - { - InitDebugPrinting(); - OtExt_genBaseOts_Test_Impl(); - } - - TEST_METHOD(OtExt_chosen_TestVS) - { - InitDebugPrinting(); - OtExt_Chosen_Test_Impl(); - } - - TEST_METHOD(KosDot_200Receive_TestVS) - { - InitDebugPrinting(); - KosDotExt_100Receive_Test_Impl(); - } - - - TEST_METHOD(IknpDot_200Receive_TestVS) - { - InitDebugPrinting(); - IknpDotExt_100Receive_Test_Impl(); - } - - TEST_METHOD(Kkrt_200Receive_TestVS) - { - InitDebugPrinting(); - KkrtNcoOt_Test_Impl(); - } - - TEST_METHOD(Oos_200Receive_TestVS) - { - InitDebugPrinting(); - OosNcoOt_Test_Impl(); - } - - TEST_METHOD(NcoOt_genBaseOts_TestVS) - { - InitDebugPrinting(); - NcoOt_genBaseOts_Test_Impl(); - } - - TEST_METHOD(NcoOt_chosen_TestVS) - { - InitDebugPrinting(); - NcoOt_chosen_Impl(); - } - TEST_METHOD(Rr17_200Receive_TestVS) - { - InitDebugPrinting(); - Rr17NcoOt_Test_Impl(); - } - - TEST_METHOD(LinearCode_TestVS) - { - InitDebugPrinting(); - LinearCode_Test_Impl(); - } - - - TEST_METHOD(LinearCode_subBlock_TestVS) - { - InitDebugPrinting(); - LinearCode_subBlock_Test_Impl(); - } - - TEST_METHOD(LinearCode_repetition_TestVS) - { - InitDebugPrinting(); - LinearCode_repetition_Test_Impl(); - } - - - - - //TEST_METHOD(LinearCode_rand134_TestVS) - //{ - // InitDebugPrinting(); - // LinearCode_rand134_Test_Impl(); - //} - - - - //TEST_METHOD(Kos2_200Receive_TestVS) - //{ - // InitDebugPrinting(); - // Kos2OtExt_100Receive_Test_Impl(); - //} - - }; -} -#endif \ No newline at end of file diff --git a/libOTe_TestsVS/libOTe_TestsVS.filters b/libOTe_TestsVS/libOTe_TestsVS.filters deleted file mode 100644 index d77713bf..00000000 --- a/libOTe_TestsVS/libOTe_TestsVS.filters +++ /dev/null @@ -1,63 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/libOTe_TestsVS/libOTe_TestsVS.vcxproj b/libOTe_TestsVS/libOTe_TestsVS.vcxproj deleted file mode 100644 index ce45c586..00000000 --- a/libOTe_TestsVS/libOTe_TestsVS.vcxproj +++ /dev/null @@ -1,144 +0,0 @@ - - - - - Debug_DLLRT - x64 - - - Debug - x64 - - - Release - x64 - - - - {3EC91167-3C50-4271-988F-0F774FFA8ACC} - Win32Proj - libOTe_TestsVS - 10.0 - - - - DynamicLibrary - true - v142 - Unicode - false - - - DynamicLibrary - true - v142 - Unicode - false - - - DynamicLibrary - false - v142 - true - Unicode - false - - - - - - - - - - - - - - - - - - - - - - Use - Level3 - Disabled - $(ProjectDir)../cryptoTools;$(solutionDir)thirdparty\win\boost\;$(ProjectDir)/../libOTe_Tests;$(SolutionDir)/libOTe;$(SolutionDir)thirdparty\win\;$(SolutionDir)thirdparty/win/NTL/include;$(SolutionDir)thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/miracl;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) - SOLUTION_DIR=R"**($(SolutionDir))**";_WIN32_WINNT=0x0501;_DEBUG;%(PreprocessorDefinitions) - true - MultiThreadedDebug - true - true - false - - - Windows - true - %(AdditionalLibraryDirectories);$(ProjectDir)..\cryptoTools\thirdparty\win\boost\stage\lib;C:/libs/boost\stage\lib;$(OutDir);$(ProjectDir)..\cryptoTools\thirdparty\win\;C:/libs/;C:/libs/Miracl/x64/$(Configuration);$(ProjectDir)..\cryptoTools/thirdparty\win/Miracl/x64/$(Configuration);C:/libs/lib; - cryptoTools.lib;libOTe.lib;libOTe_Tests.lib;%(AdditionalDependencies) - - - - - Use - Level3 - Disabled - $(ProjectDir)../cryptoTools;$(solutionDir)thirdparty\win\boost\;$(ProjectDir)/../libOTe_Tests;$(SolutionDir)/libOTe;$(SolutionDir)thirdparty\win\;$(SolutionDir)thirdparty/win/NTL/include;$(SolutionDir)thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/miracl;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) - SOLUTION_DIR=R"**($(SolutionDir))**";_WIN32_WINNT=0x0501;_DEBUG;%(PreprocessorDefinitions) - true - MultiThreadedDebug - true - true - false - - - Windows - true - %(AdditionalLibraryDirectories);$(ProjectDir)..\cryptoTools\thirdparty\win\boost\stage\lib;C:/libs/boost\stage\lib;$(OutDir);$(ProjectDir)..\cryptoTools\thirdparty\win\;C:/libs/;C:/libs/Miracl/x64/$(Configuration);$(ProjectDir)..\cryptoTools/thirdparty\win/Miracl/x64/$(Configuration);C:/libs/lib; - cryptoTools.lib;libOTe.lib;libOTe_Tests.lib;%(AdditionalDependencies) - - - - - Level3 - Use - MaxSpeed - true - true - $(ProjectDir)../cryptoTools;$(solutionDir)thirdparty\win\boost\;$(ProjectDir)/../libOTe_Tests;$(SolutionDir)/libOTe;$(SolutionDir)thirdparty\win\;$(SolutionDir)thirdparty/win/NTL/include;$(SolutionDir)thirdparty/win/miracl;C:/libs/boost;C:/libs/;C:/libs/miracl;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) - SOLUTION_DIR=R"**($(SolutionDir))**";_WIN32_WINNT=0x0501;NDEBUG;%(PreprocessorDefinitions) - true - MultiThreaded - true - true - - - Windows - true - true - true - %(AdditionalLibraryDirectories);$(ProjectDir)..\cryptoTools\thirdparty\win\boost\stage\lib;C:/libs/boost\stage\lib;$(OutDir);$(ProjectDir)..\cryptoTools\thirdparty\win\;C:/libs/;C:/libs/Miracl/x64/$(Configuration);$(ProjectDir)..\cryptoTools/thirdparty\win/Miracl/x64/$(Configuration);C:/libs/lib; - cryptoTools.lib;libOTe.lib;libOTe_Tests.lib;%(AdditionalDependencies) - - - - - - - - - - - - Create - Create - Create - - - - - - \ No newline at end of file diff --git a/libOTe_TestsVS/stdafx.cpp b/libOTe_TestsVS/stdafx.cpp deleted file mode 100644 index 226a0c12..00000000 --- a/libOTe_TestsVS/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// tests_libOTeVS.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/libOTe_TestsVS/stdafx.h b/libOTe_TestsVS/stdafx.h deleted file mode 100644 index f7043d46..00000000 --- a/libOTe_TestsVS/stdafx.h +++ /dev/null @@ -1,14 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once -// This file and the associated implementation has been placed in the public domain, waiving all copyright. No restrictions are placed on its use. - -#include "targetver.h" - -// Headers for CppUnitTest -#include "CppUnitTest.h" - -// TODO: reference additional headers your program requires here diff --git a/libOTe_TestsVS/targetver.h b/libOTe_TestsVS/targetver.h deleted file mode 100644 index 1b4a643d..00000000 --- a/libOTe_TestsVS/targetver.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -// This file and the associated implementation has been placed in the public domain, waiving all copyright. No restrictions are placed on its use. - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/KyberOT/CMakeLists.txt b/thirdparty/KyberOT/CMakeLists.txt similarity index 51% rename from KyberOT/CMakeLists.txt rename to thirdparty/KyberOT/CMakeLists.txt index ba90325e..ade68641 100644 --- a/KyberOT/CMakeLists.txt +++ b/thirdparty/KyberOT/CMakeLists.txt @@ -8,14 +8,21 @@ SET(SRCS kem.c poly.c polyvec.c polyvec_pointwise_acc.s fips202.c reduce.c cbde add_library(KyberOT STATIC ${SRCS}) -target_include_directories(KyberOT PUBLIC ${CMAKE_SOURCE_DIR}) + +# make projects that include libOTe use this as an include folder +target_include_directories(KyberOT PUBLIC + $ + $) +target_include_directories(KyberOT PUBLIC + $ + $) ############################################# # Install # ############################################# # install library -install(TARGETS KyberOT DESTINATION lib) +#install(TARGETS KyberOT DESTINATION lib) # install headers -install(DIRECTORY . DESTINATION include/KyberOT FILES_MATCHING PATTERN "*.h") +#install(DIRECTORY . DESTINATION include/KyberOT FILES_MATCHING PATTERN "*.h") diff --git a/KyberOT/KyberOT.c b/thirdparty/KyberOT/KyberOT.c similarity index 100% rename from KyberOT/KyberOT.c rename to thirdparty/KyberOT/KyberOT.c diff --git a/KyberOT/KyberOT.h b/thirdparty/KyberOT/KyberOT.h similarity index 100% rename from KyberOT/KyberOT.h rename to thirdparty/KyberOT/KyberOT.h diff --git a/KyberOT/PQCgenKAT_kem.c b/thirdparty/KyberOT/PQCgenKAT_kem.c similarity index 100% rename from KyberOT/PQCgenKAT_kem.c rename to thirdparty/KyberOT/PQCgenKAT_kem.c diff --git a/KyberOT/api.h b/thirdparty/KyberOT/api.h similarity index 100% rename from KyberOT/api.h rename to thirdparty/KyberOT/api.h diff --git a/KyberOT/cbd.h b/thirdparty/KyberOT/cbd.h similarity index 100% rename from KyberOT/cbd.h rename to thirdparty/KyberOT/cbd.h diff --git a/KyberOT/cbdeta4.s b/thirdparty/KyberOT/cbdeta4.s similarity index 100% rename from KyberOT/cbdeta4.s rename to thirdparty/KyberOT/cbdeta4.s diff --git a/KyberOT/cbdref.c b/thirdparty/KyberOT/cbdref.c similarity index 100% rename from KyberOT/cbdref.c rename to thirdparty/KyberOT/cbdref.c diff --git a/KyberOT/consts.c b/thirdparty/KyberOT/consts.c similarity index 100% rename from KyberOT/consts.c rename to thirdparty/KyberOT/consts.c diff --git a/KyberOT/cpucycles.c b/thirdparty/KyberOT/cpucycles.c similarity index 100% rename from KyberOT/cpucycles.c rename to thirdparty/KyberOT/cpucycles.c diff --git a/KyberOT/cpucycles.h b/thirdparty/KyberOT/cpucycles.h similarity index 100% rename from KyberOT/cpucycles.h rename to thirdparty/KyberOT/cpucycles.h diff --git a/KyberOT/fips202.c b/thirdparty/KyberOT/fips202.c similarity index 100% rename from KyberOT/fips202.c rename to thirdparty/KyberOT/fips202.c diff --git a/KyberOT/fips202.h b/thirdparty/KyberOT/fips202.h similarity index 100% rename from KyberOT/fips202.h rename to thirdparty/KyberOT/fips202.h diff --git a/KyberOT/fips202x4.c b/thirdparty/KyberOT/fips202x4.c similarity index 100% rename from KyberOT/fips202x4.c rename to thirdparty/KyberOT/fips202x4.c diff --git a/KyberOT/fips202x4.h b/thirdparty/KyberOT/fips202x4.h similarity index 100% rename from KyberOT/fips202x4.h rename to thirdparty/KyberOT/fips202x4.h diff --git a/KyberOT/genmatrix.c b/thirdparty/KyberOT/genmatrix.c similarity index 100% rename from KyberOT/genmatrix.c rename to thirdparty/KyberOT/genmatrix.c diff --git a/KyberOT/genmatrix.h b/thirdparty/KyberOT/genmatrix.h similarity index 100% rename from KyberOT/genmatrix.h rename to thirdparty/KyberOT/genmatrix.h diff --git a/KyberOT/indcpa.c b/thirdparty/KyberOT/indcpa.c similarity index 100% rename from KyberOT/indcpa.c rename to thirdparty/KyberOT/indcpa.c diff --git a/KyberOT/indcpa.h b/thirdparty/KyberOT/indcpa.h similarity index 100% rename from KyberOT/indcpa.h rename to thirdparty/KyberOT/indcpa.h diff --git a/KyberOT/invntt.s b/thirdparty/KyberOT/invntt.s similarity index 100% rename from KyberOT/invntt.s rename to thirdparty/KyberOT/invntt.s diff --git a/KyberOT/keccak4x/KeccakP-1600-times4-SIMD256.c b/thirdparty/KyberOT/keccak4x/KeccakP-1600-times4-SIMD256.c similarity index 100% rename from KyberOT/keccak4x/KeccakP-1600-times4-SIMD256.c rename to thirdparty/KyberOT/keccak4x/KeccakP-1600-times4-SIMD256.c diff --git a/KyberOT/keccak4x/KeccakP-1600-times4-SIMD256.o b/thirdparty/KyberOT/keccak4x/KeccakP-1600-times4-SIMD256.o similarity index 100% rename from KyberOT/keccak4x/KeccakP-1600-times4-SIMD256.o rename to thirdparty/KyberOT/keccak4x/KeccakP-1600-times4-SIMD256.o diff --git a/KyberOT/keccak4x/KeccakP-1600-times4-SnP.h b/thirdparty/KyberOT/keccak4x/KeccakP-1600-times4-SnP.h similarity index 100% rename from KyberOT/keccak4x/KeccakP-1600-times4-SnP.h rename to thirdparty/KyberOT/keccak4x/KeccakP-1600-times4-SnP.h diff --git a/KyberOT/keccak4x/KeccakP-1600-unrolling.macros b/thirdparty/KyberOT/keccak4x/KeccakP-1600-unrolling.macros similarity index 100% rename from KyberOT/keccak4x/KeccakP-1600-unrolling.macros rename to thirdparty/KyberOT/keccak4x/KeccakP-1600-unrolling.macros diff --git a/KyberOT/keccak4x/SIMD256-config.h b/thirdparty/KyberOT/keccak4x/SIMD256-config.h similarity index 100% rename from KyberOT/keccak4x/SIMD256-config.h rename to thirdparty/KyberOT/keccak4x/SIMD256-config.h diff --git a/KyberOT/keccak4x/align.h b/thirdparty/KyberOT/keccak4x/align.h similarity index 100% rename from KyberOT/keccak4x/align.h rename to thirdparty/KyberOT/keccak4x/align.h diff --git a/KyberOT/keccak4x/brg_endian.h b/thirdparty/KyberOT/keccak4x/brg_endian.h similarity index 100% rename from KyberOT/keccak4x/brg_endian.h rename to thirdparty/KyberOT/keccak4x/brg_endian.h diff --git a/KyberOT/kem.c b/thirdparty/KyberOT/kem.c similarity index 100% rename from KyberOT/kem.c rename to thirdparty/KyberOT/kem.c diff --git a/KyberOT/kex.c b/thirdparty/KyberOT/kex.c similarity index 100% rename from KyberOT/kex.c rename to thirdparty/KyberOT/kex.c diff --git a/KyberOT/kex.h b/thirdparty/KyberOT/kex.h similarity index 100% rename from KyberOT/kex.h rename to thirdparty/KyberOT/kex.h diff --git a/KyberOT/ntt.h b/thirdparty/KyberOT/ntt.h similarity index 100% rename from KyberOT/ntt.h rename to thirdparty/KyberOT/ntt.h diff --git a/KyberOT/ntt.s b/thirdparty/KyberOT/ntt.s similarity index 100% rename from KyberOT/ntt.s rename to thirdparty/KyberOT/ntt.s diff --git a/KyberOT/params.h b/thirdparty/KyberOT/params.h similarity index 100% rename from KyberOT/params.h rename to thirdparty/KyberOT/params.h diff --git a/KyberOT/poly.c b/thirdparty/KyberOT/poly.c similarity index 100% rename from KyberOT/poly.c rename to thirdparty/KyberOT/poly.c diff --git a/KyberOT/poly.h b/thirdparty/KyberOT/poly.h similarity index 100% rename from KyberOT/poly.h rename to thirdparty/KyberOT/poly.h diff --git a/KyberOT/polyvec.c b/thirdparty/KyberOT/polyvec.c similarity index 100% rename from KyberOT/polyvec.c rename to thirdparty/KyberOT/polyvec.c diff --git a/KyberOT/polyvec.h b/thirdparty/KyberOT/polyvec.h similarity index 100% rename from KyberOT/polyvec.h rename to thirdparty/KyberOT/polyvec.h diff --git a/KyberOT/polyvec_pointwise_acc.s b/thirdparty/KyberOT/polyvec_pointwise_acc.s similarity index 100% rename from KyberOT/polyvec_pointwise_acc.s rename to thirdparty/KyberOT/polyvec_pointwise_acc.s diff --git a/KyberOT/precomp.c b/thirdparty/KyberOT/precomp.c similarity index 100% rename from KyberOT/precomp.c rename to thirdparty/KyberOT/precomp.c diff --git a/KyberOT/randombytes.c b/thirdparty/KyberOT/randombytes.c similarity index 100% rename from KyberOT/randombytes.c rename to thirdparty/KyberOT/randombytes.c diff --git a/KyberOT/randombytes.h b/thirdparty/KyberOT/randombytes.h similarity index 100% rename from KyberOT/randombytes.h rename to thirdparty/KyberOT/randombytes.h diff --git a/KyberOT/reduce.c b/thirdparty/KyberOT/reduce.c similarity index 100% rename from KyberOT/reduce.c rename to thirdparty/KyberOT/reduce.c diff --git a/KyberOT/reduce.h b/thirdparty/KyberOT/reduce.h similarity index 100% rename from KyberOT/reduce.h rename to thirdparty/KyberOT/reduce.h diff --git a/KyberOT/rng.c b/thirdparty/KyberOT/rng.c similarity index 100% rename from KyberOT/rng.c rename to thirdparty/KyberOT/rng.c diff --git a/KyberOT/rng.h b/thirdparty/KyberOT/rng.h similarity index 100% rename from KyberOT/rng.h rename to thirdparty/KyberOT/rng.h diff --git a/KyberOT/speed.c b/thirdparty/KyberOT/speed.c similarity index 100% rename from KyberOT/speed.c rename to thirdparty/KyberOT/speed.c diff --git a/KyberOT/test_kex.c b/thirdparty/KyberOT/test_kex.c similarity index 100% rename from KyberOT/test_kex.c rename to thirdparty/KyberOT/test_kex.c diff --git a/KyberOT/test_kyber.c b/thirdparty/KyberOT/test_kyber.c similarity index 100% rename from KyberOT/test_kyber.c rename to thirdparty/KyberOT/test_kyber.c diff --git a/KyberOT/testvectors.c b/thirdparty/KyberOT/testvectors.c similarity index 100% rename from KyberOT/testvectors.c rename to thirdparty/KyberOT/testvectors.c diff --git a/KyberOT/verify.c b/thirdparty/KyberOT/verify.c similarity index 100% rename from KyberOT/verify.c rename to thirdparty/KyberOT/verify.c diff --git a/KyberOT/verify.h b/thirdparty/KyberOT/verify.h similarity index 100% rename from KyberOT/verify.h rename to thirdparty/KyberOT/verify.h diff --git a/thirdparty/SimplestOT/CMakeLists.txt b/thirdparty/SimplestOT/CMakeLists.txt new file mode 100644 index 00000000..e14afcc0 --- /dev/null +++ b/thirdparty/SimplestOT/CMakeLists.txt @@ -0,0 +1,34 @@ +#project(SimplestOT C C++ ASM) + +enable_language(ASM) + +file(GLOB_RECURSE SRC_SIMPLE_LIB + ${CMAKE_CURRENT_SOURCE_DIR}/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/*.s) + +add_library(SimplestOT STATIC ${SRC_SIMPLE_LIB}) +target_link_libraries(SimplestOT PUBLIC cryptoTools) +#target_compile_options(SimplestOT PUBLIC -fPIC -no-pie) +target_link_options(SimplestOT PUBLIC -fPIC -no-pie) + + + +# make projects that include libOTe use this as an include folder +target_include_directories(SimplestOT PUBLIC + $ + $) +target_include_directories(SimplestOT PUBLIC + $ + $) + + + +############################################# +# Install # +############################################# + +# install library +#install(TARGETS SimplestOT DESTINATION lib) + +# install headers +#install(DIRECTORY . DESTINATION include/SimplestOT FILES_MATCHING PATTERN "*.h") diff --git a/SimplestOT/Keccak-simple-settings.h b/thirdparty/SimplestOT/Keccak-simple-settings.h similarity index 100% rename from SimplestOT/Keccak-simple-settings.h rename to thirdparty/SimplestOT/Keccak-simple-settings.h diff --git a/SimplestOT/Keccak-simple.c b/thirdparty/SimplestOT/Keccak-simple.c similarity index 100% rename from SimplestOT/Keccak-simple.c rename to thirdparty/SimplestOT/Keccak-simple.c diff --git a/SimplestOT/LICENSE b/thirdparty/SimplestOT/LICENSE similarity index 100% rename from SimplestOT/LICENSE rename to thirdparty/SimplestOT/LICENSE diff --git a/SimplestOT/consts.s b/thirdparty/SimplestOT/consts.s similarity index 100% rename from SimplestOT/consts.s rename to thirdparty/SimplestOT/consts.s diff --git a/SimplestOT/consts4x.s b/thirdparty/SimplestOT/consts4x.s similarity index 100% rename from SimplestOT/consts4x.s rename to thirdparty/SimplestOT/consts4x.s diff --git a/SimplestOT/cpucycles.c b/thirdparty/SimplestOT/cpucycles.c similarity index 100% rename from SimplestOT/cpucycles.c rename to thirdparty/SimplestOT/cpucycles.c diff --git a/SimplestOT/cpucycles.h b/thirdparty/SimplestOT/cpucycles.h similarity index 100% rename from SimplestOT/cpucycles.h rename to thirdparty/SimplestOT/cpucycles.h diff --git a/SimplestOT/crypto_hash.h b/thirdparty/SimplestOT/crypto_hash.h similarity index 100% rename from SimplestOT/crypto_hash.h rename to thirdparty/SimplestOT/crypto_hash.h diff --git a/SimplestOT/fe25519.h b/thirdparty/SimplestOT/fe25519.h similarity index 100% rename from SimplestOT/fe25519.h rename to thirdparty/SimplestOT/fe25519.h diff --git a/SimplestOT/fe25519_add.c b/thirdparty/SimplestOT/fe25519_add.c similarity index 100% rename from SimplestOT/fe25519_add.c rename to thirdparty/SimplestOT/fe25519_add.c diff --git a/SimplestOT/fe25519_freeze.s b/thirdparty/SimplestOT/fe25519_freeze.s similarity index 100% rename from SimplestOT/fe25519_freeze.s rename to thirdparty/SimplestOT/fe25519_freeze.s diff --git a/SimplestOT/fe25519_getparity.c b/thirdparty/SimplestOT/fe25519_getparity.c similarity index 100% rename from SimplestOT/fe25519_getparity.c rename to thirdparty/SimplestOT/fe25519_getparity.c diff --git a/SimplestOT/fe25519_invert.c b/thirdparty/SimplestOT/fe25519_invert.c similarity index 100% rename from SimplestOT/fe25519_invert.c rename to thirdparty/SimplestOT/fe25519_invert.c diff --git a/SimplestOT/fe25519_iseq_vartime.c b/thirdparty/SimplestOT/fe25519_iseq_vartime.c similarity index 100% rename from SimplestOT/fe25519_iseq_vartime.c rename to thirdparty/SimplestOT/fe25519_iseq_vartime.c diff --git a/SimplestOT/fe25519_mul.s b/thirdparty/SimplestOT/fe25519_mul.s similarity index 100% rename from SimplestOT/fe25519_mul.s rename to thirdparty/SimplestOT/fe25519_mul.s diff --git a/SimplestOT/fe25519_neg.c b/thirdparty/SimplestOT/fe25519_neg.c similarity index 100% rename from SimplestOT/fe25519_neg.c rename to thirdparty/SimplestOT/fe25519_neg.c diff --git a/SimplestOT/fe25519_nsquare.s b/thirdparty/SimplestOT/fe25519_nsquare.s similarity index 100% rename from SimplestOT/fe25519_nsquare.s rename to thirdparty/SimplestOT/fe25519_nsquare.s diff --git a/SimplestOT/fe25519_pack.c b/thirdparty/SimplestOT/fe25519_pack.c similarity index 100% rename from SimplestOT/fe25519_pack.c rename to thirdparty/SimplestOT/fe25519_pack.c diff --git a/SimplestOT/fe25519_pow2523.c b/thirdparty/SimplestOT/fe25519_pow2523.c similarity index 100% rename from SimplestOT/fe25519_pow2523.c rename to thirdparty/SimplestOT/fe25519_pow2523.c diff --git a/SimplestOT/fe25519_setint.c b/thirdparty/SimplestOT/fe25519_setint.c similarity index 100% rename from SimplestOT/fe25519_setint.c rename to thirdparty/SimplestOT/fe25519_setint.c diff --git a/SimplestOT/fe25519_square.s b/thirdparty/SimplestOT/fe25519_square.s similarity index 100% rename from SimplestOT/fe25519_square.s rename to thirdparty/SimplestOT/fe25519_square.s diff --git a/SimplestOT/fe25519_sub.c b/thirdparty/SimplestOT/fe25519_sub.c similarity index 100% rename from SimplestOT/fe25519_sub.c rename to thirdparty/SimplestOT/fe25519_sub.c diff --git a/SimplestOT/fe25519_unpack.c b/thirdparty/SimplestOT/fe25519_unpack.c similarity index 100% rename from SimplestOT/fe25519_unpack.c rename to thirdparty/SimplestOT/fe25519_unpack.c diff --git a/SimplestOT/ge25519.data b/thirdparty/SimplestOT/ge25519.data similarity index 100% rename from SimplestOT/ge25519.data rename to thirdparty/SimplestOT/ge25519.data diff --git a/SimplestOT/ge25519.h b/thirdparty/SimplestOT/ge25519.h similarity index 100% rename from SimplestOT/ge25519.h rename to thirdparty/SimplestOT/ge25519.h diff --git a/SimplestOT/ge25519_add.c b/thirdparty/SimplestOT/ge25519_add.c similarity index 100% rename from SimplestOT/ge25519_add.c rename to thirdparty/SimplestOT/ge25519_add.c diff --git a/SimplestOT/ge25519_add_p1p1.s b/thirdparty/SimplestOT/ge25519_add_p1p1.s similarity index 100% rename from SimplestOT/ge25519_add_p1p1.s rename to thirdparty/SimplestOT/ge25519_add_p1p1.s diff --git a/SimplestOT/ge25519_dbl_p1p1.s b/thirdparty/SimplestOT/ge25519_dbl_p1p1.s similarity index 100% rename from SimplestOT/ge25519_dbl_p1p1.s rename to thirdparty/SimplestOT/ge25519_dbl_p1p1.s diff --git a/SimplestOT/ge25519_double.c b/thirdparty/SimplestOT/ge25519_double.c similarity index 100% rename from SimplestOT/ge25519_double.c rename to thirdparty/SimplestOT/ge25519_double.c diff --git a/SimplestOT/ge25519_lookup.s b/thirdparty/SimplestOT/ge25519_lookup.s similarity index 100% rename from SimplestOT/ge25519_lookup.s rename to thirdparty/SimplestOT/ge25519_lookup.s diff --git a/SimplestOT/ge25519_lookup_niels.s b/thirdparty/SimplestOT/ge25519_lookup_niels.s similarity index 100% rename from SimplestOT/ge25519_lookup_niels.s rename to thirdparty/SimplestOT/ge25519_lookup_niels.s diff --git a/SimplestOT/ge25519_nielsadd2.s b/thirdparty/SimplestOT/ge25519_nielsadd2.s similarity index 100% rename from SimplestOT/ge25519_nielsadd2.s rename to thirdparty/SimplestOT/ge25519_nielsadd2.s diff --git a/SimplestOT/ge25519_p1p1_to_p2.s b/thirdparty/SimplestOT/ge25519_p1p1_to_p2.s similarity index 100% rename from SimplestOT/ge25519_p1p1_to_p2.s rename to thirdparty/SimplestOT/ge25519_p1p1_to_p2.s diff --git a/SimplestOT/ge25519_p1p1_to_p3.s b/thirdparty/SimplestOT/ge25519_p1p1_to_p3.s similarity index 100% rename from SimplestOT/ge25519_p1p1_to_p3.s rename to thirdparty/SimplestOT/ge25519_p1p1_to_p3.s diff --git a/SimplestOT/ge25519_pack.c b/thirdparty/SimplestOT/ge25519_pack.c similarity index 100% rename from SimplestOT/ge25519_pack.c rename to thirdparty/SimplestOT/ge25519_pack.c diff --git a/SimplestOT/ge25519_scalarmult.c b/thirdparty/SimplestOT/ge25519_scalarmult.c similarity index 100% rename from SimplestOT/ge25519_scalarmult.c rename to thirdparty/SimplestOT/ge25519_scalarmult.c diff --git a/SimplestOT/ge25519_scalarmult_base.c b/thirdparty/SimplestOT/ge25519_scalarmult_base.c similarity index 100% rename from SimplestOT/ge25519_scalarmult_base.c rename to thirdparty/SimplestOT/ge25519_scalarmult_base.c diff --git a/SimplestOT/ge25519_setneutral.c b/thirdparty/SimplestOT/ge25519_setneutral.c similarity index 100% rename from SimplestOT/ge25519_setneutral.c rename to thirdparty/SimplestOT/ge25519_setneutral.c diff --git a/SimplestOT/ge25519_unpack.c b/thirdparty/SimplestOT/ge25519_unpack.c similarity index 100% rename from SimplestOT/ge25519_unpack.c rename to thirdparty/SimplestOT/ge25519_unpack.c diff --git a/SimplestOT/ge4x.c b/thirdparty/SimplestOT/ge4x.c similarity index 100% rename from SimplestOT/ge4x.c rename to thirdparty/SimplestOT/ge4x.c diff --git a/SimplestOT/ge4x.data b/thirdparty/SimplestOT/ge4x.data similarity index 100% rename from SimplestOT/ge4x.data rename to thirdparty/SimplestOT/ge4x.data diff --git a/SimplestOT/ge4x.h b/thirdparty/SimplestOT/ge4x.h similarity index 100% rename from SimplestOT/ge4x.h rename to thirdparty/SimplestOT/ge4x.h diff --git a/SimplestOT/ge4x_add_p1p1.s b/thirdparty/SimplestOT/ge4x_add_p1p1.s similarity index 100% rename from SimplestOT/ge4x_add_p1p1.s rename to thirdparty/SimplestOT/ge4x_add_p1p1.s diff --git a/SimplestOT/ge4x_double_p1p1.s b/thirdparty/SimplestOT/ge4x_double_p1p1.s similarity index 100% rename from SimplestOT/ge4x_double_p1p1.s rename to thirdparty/SimplestOT/ge4x_double_p1p1.s diff --git a/SimplestOT/ge4x_lookup.s b/thirdparty/SimplestOT/ge4x_lookup.s similarity index 100% rename from SimplestOT/ge4x_lookup.s rename to thirdparty/SimplestOT/ge4x_lookup.s diff --git a/SimplestOT/ge4x_lookup_niels.s b/thirdparty/SimplestOT/ge4x_lookup_niels.s similarity index 100% rename from SimplestOT/ge4x_lookup_niels.s rename to thirdparty/SimplestOT/ge4x_lookup_niels.s diff --git a/SimplestOT/ge4x_niels_add_p1p1.s b/thirdparty/SimplestOT/ge4x_niels_add_p1p1.s similarity index 100% rename from SimplestOT/ge4x_niels_add_p1p1.s rename to thirdparty/SimplestOT/ge4x_niels_add_p1p1.s diff --git a/SimplestOT/ge4x_pack.c b/thirdparty/SimplestOT/ge4x_pack.c similarity index 100% rename from SimplestOT/ge4x_pack.c rename to thirdparty/SimplestOT/ge4x_pack.c diff --git a/SimplestOT/ge4x_unpack_vartime.c b/thirdparty/SimplestOT/ge4x_unpack_vartime.c similarity index 100% rename from SimplestOT/ge4x_unpack_vartime.c rename to thirdparty/SimplestOT/ge4x_unpack_vartime.c diff --git a/SimplestOT/gfe4x.c b/thirdparty/SimplestOT/gfe4x.c similarity index 100% rename from SimplestOT/gfe4x.c rename to thirdparty/SimplestOT/gfe4x.c diff --git a/SimplestOT/gfe4x.h b/thirdparty/SimplestOT/gfe4x.h similarity index 100% rename from SimplestOT/gfe4x.h rename to thirdparty/SimplestOT/gfe4x.h diff --git a/SimplestOT/gfe4x_add.s b/thirdparty/SimplestOT/gfe4x_add.s similarity index 100% rename from SimplestOT/gfe4x_add.s rename to thirdparty/SimplestOT/gfe4x_add.s diff --git a/SimplestOT/gfe4x_getparity.c b/thirdparty/SimplestOT/gfe4x_getparity.c similarity index 100% rename from SimplestOT/gfe4x_getparity.c rename to thirdparty/SimplestOT/gfe4x_getparity.c diff --git a/SimplestOT/gfe4x_iseq_vartime.c b/thirdparty/SimplestOT/gfe4x_iseq_vartime.c similarity index 100% rename from SimplestOT/gfe4x_iseq_vartime.c rename to thirdparty/SimplestOT/gfe4x_iseq_vartime.c diff --git a/SimplestOT/gfe4x_mul.s b/thirdparty/SimplestOT/gfe4x_mul.s similarity index 100% rename from SimplestOT/gfe4x_mul.s rename to thirdparty/SimplestOT/gfe4x_mul.s diff --git a/SimplestOT/gfe4x_nsquare.c b/thirdparty/SimplestOT/gfe4x_nsquare.c similarity index 100% rename from SimplestOT/gfe4x_nsquare.c rename to thirdparty/SimplestOT/gfe4x_nsquare.c diff --git a/SimplestOT/gfe4x_pow2523.c b/thirdparty/SimplestOT/gfe4x_pow2523.c similarity index 100% rename from SimplestOT/gfe4x_pow2523.c rename to thirdparty/SimplestOT/gfe4x_pow2523.c diff --git a/SimplestOT/gfe4x_square.s b/thirdparty/SimplestOT/gfe4x_square.s similarity index 100% rename from SimplestOT/gfe4x_square.s rename to thirdparty/SimplestOT/gfe4x_square.s diff --git a/SimplestOT/gfe4x_sub.s b/thirdparty/SimplestOT/gfe4x_sub.s similarity index 100% rename from SimplestOT/gfe4x_sub.s rename to thirdparty/SimplestOT/gfe4x_sub.s diff --git a/SimplestOT/network.c b/thirdparty/SimplestOT/network.c similarity index 100% rename from SimplestOT/network.c rename to thirdparty/SimplestOT/network.c diff --git a/SimplestOT/network.h b/thirdparty/SimplestOT/network.h similarity index 100% rename from SimplestOT/network.h rename to thirdparty/SimplestOT/network.h diff --git a/SimplestOT/ot_config.h b/thirdparty/SimplestOT/ot_config.h similarity index 100% rename from SimplestOT/ot_config.h rename to thirdparty/SimplestOT/ot_config.h diff --git a/SimplestOT/ot_receiver.c b/thirdparty/SimplestOT/ot_receiver.c similarity index 100% rename from SimplestOT/ot_receiver.c rename to thirdparty/SimplestOT/ot_receiver.c diff --git a/SimplestOT/ot_receiver.h b/thirdparty/SimplestOT/ot_receiver.h similarity index 100% rename from SimplestOT/ot_receiver.h rename to thirdparty/SimplestOT/ot_receiver.h diff --git a/SimplestOT/ot_receiver_test.c b/thirdparty/SimplestOT/ot_receiver_test.c similarity index 100% rename from SimplestOT/ot_receiver_test.c rename to thirdparty/SimplestOT/ot_receiver_test.c diff --git a/SimplestOT/ot_sender.c b/thirdparty/SimplestOT/ot_sender.c similarity index 100% rename from SimplestOT/ot_sender.c rename to thirdparty/SimplestOT/ot_sender.c diff --git a/SimplestOT/ot_sender.h b/thirdparty/SimplestOT/ot_sender.h similarity index 100% rename from SimplestOT/ot_sender.h rename to thirdparty/SimplestOT/ot_sender.h diff --git a/SimplestOT/ot_sender_test.c b/thirdparty/SimplestOT/ot_sender_test.c similarity index 100% rename from SimplestOT/ot_sender_test.c rename to thirdparty/SimplestOT/ot_sender_test.c diff --git a/SimplestOT/randombytes.c b/thirdparty/SimplestOT/randombytes.c similarity index 100% rename from SimplestOT/randombytes.c rename to thirdparty/SimplestOT/randombytes.c diff --git a/SimplestOT/randombytes.h b/thirdparty/SimplestOT/randombytes.h similarity index 100% rename from SimplestOT/randombytes.h rename to thirdparty/SimplestOT/randombytes.h diff --git a/SimplestOT/sc25519.h b/thirdparty/SimplestOT/sc25519.h similarity index 100% rename from SimplestOT/sc25519.h rename to thirdparty/SimplestOT/sc25519.h diff --git a/SimplestOT/sc25519_from32bytes.c b/thirdparty/SimplestOT/sc25519_from32bytes.c similarity index 100% rename from SimplestOT/sc25519_from32bytes.c rename to thirdparty/SimplestOT/sc25519_from32bytes.c diff --git a/SimplestOT/sc25519_random.c b/thirdparty/SimplestOT/sc25519_random.c similarity index 100% rename from SimplestOT/sc25519_random.c rename to thirdparty/SimplestOT/sc25519_random.c diff --git a/SimplestOT/sc25519_window4.c b/thirdparty/SimplestOT/sc25519_window4.c similarity index 100% rename from SimplestOT/sc25519_window4.c rename to thirdparty/SimplestOT/sc25519_window4.c diff --git a/SimplestOT/to_4x.h b/thirdparty/SimplestOT/to_4x.h similarity index 100% rename from SimplestOT/to_4x.h rename to thirdparty/SimplestOT/to_4x.h diff --git a/thirdparty/getBitpolymul.py b/thirdparty/getBitpolymul.py new file mode 100644 index 00000000..50ee8b2d --- /dev/null +++ b/thirdparty/getBitpolymul.py @@ -0,0 +1,71 @@ + +import os +import sys +import platform + + +def get(install, prefix, par): + + cwd = os.getcwd() + #thirdparty = os.path.dirname(os.path.realpath(__file__)) + + if os.path.isdir("bitpolymul") == False: + os.system("git clone https://github.com/ladnir/bitpolymul.git") + + os.chdir(cwd + "/bitpolymul") + os.system("git checkout 3afe2d39ca14cf85fa537238cc9b412cd33358fb") + + buildDir = cwd + "/bitpolymul/build" + + config = "" + argStr = "-DCMAKE_BUILD_TYPE=Release" + + osStr = (platform.system()) + sudo = "" + if(osStr == "Windows"): + config = " --config Release " + buildDir = buildDir + "_win" + if not install: + prefix = cwd + "/win" + else: + if install and "--sudo" in sys.argv: + sudo = "sudo " + buildDir = buildDir + "_linux" + if not install: + prefix = cwd + "/unix" + + + + parallel = "" + if par != 1: + parallel = "--parallel " + str(par) + + CMakeCmd = "cmake -S . -B {0} {1}".format(buildDir, argStr) + BuildCmd = "cmake --build {0} {1} {2} ".format(buildDir, config, parallel) + + InstallCmd = "{0}cmake --install {1}".format(sudo, buildDir) + if len(prefix): + InstallCmd += " --prefix {0} ".format(prefix) + + print("\n\n=========== getBitpolymul.py ================") + print("mkdir "+ buildDir) + print(CMakeCmd) + print(BuildCmd) + print(InstallCmd) + print("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n\n") + + if not os.path.exists(buildDir): + os.mkdir(buildDir) + + os.system(CMakeCmd) + os.system(BuildCmd) + + if len(sudo): + print ("Installing bitpolymul: {0}".format(InstallCmd)) + + os.system(InstallCmd) + + + +if __name__ == "__main__": + getBitpolymul(False, "", 1) diff --git a/title.PNG b/title.PNG deleted file mode 100644 index e71746cb33b57316899700484d51e7b0a2de5e7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66494 zcmdSC3pkW(_Xmv1p;A;Na;}s^MGb{Wg-TH}3_?yR$6b+A=pe}(g zC9$y)nh`=JIfa~Z9KQ9;IH%tIeb?UK_3zqyzwcGkf>>*RIS-_LO^R#9E7 zv-gTh@N9jQlgI{ZBEL+7Cky+{}h95?YGzO zdDmFs(0?;j;Nz{sgQt=^f8X=Ft^22A_0hJg`Bmy~*d?ye8(dMfhsys=&5+%3@coL? zi`9D#(;Tgmo2_oN-?H#;{oOJB0t>G0PLW+E>fR-e^kJ19EQ9x2xovkiy)WIrGd6e8 zNS))K5e9X+xpph=Rh)SwYPHFIy_aEc&5kb3_(*4m^Pj^6k0d=Cz!lZ6REqrj-i}9( z7h1|X-5Q4q{iCZV>f7i}G`0j{$NT_3I7ge9!(^ zK~v@No*+{6*e9{Kxf7$g>79?1saw7YPV@-AE%*Gk<4cS3glnC#dnXD{AgmmHwaxPi zwKps`-*W(GlG-^?ZBpn-?JzOV9WHesHjaNww;QeR_PjxbA67UHKjM_vSd(DgH~2f* zM*E^C0;tW~yk3m=DNn2(?J$|BP0OWrI=uCwR(qLFP#Y%#spS)6T6N=tUK49a;c1k= zbbC!Ge4cMj#t!yxRPbS*V}+m69(ht2^r(Ne^S#{Z+!~)=;DW_|UbE~4m!)?|8LNa$ zo^>f}2`kPhQWSr5Fju-}ai(yMMeYlaZ~d9PyE;B+Mjtp6B9^D^q>jOMvFdW&6bcpb zjbk-cT})b|BB{!u!I|gBYPRJn#_#{#2MJ1-fBqG3F3x=Ig?`A)2j5*H<8C{hz4+&P zZgCO?x}D()j#Y-{ifHr&zw7V)WbzJMd2_8ZO+D>x=}k^@tBiFWpmYrl00eVe`_4&4K=KH5_V<9+Gtqb>Cxf6%@N_Ub2J*@xkzZ{qwPGV6oy z9LWI1joYlvj>Z22?o8L~qYi;RI_T0Z+*c)vStTMlbuGNf;hdqIx|tdNMBdI(wM;>G z4dn9dbtG^7WzG@bA{5F%83-EN*;2P6&E{vzRO2?a%j$NzCO;hG&S`ucIYFXMJttm# z)pzzeV>tC zwkhSQ&s4Zg6EZ}>L>J@y=w|6n6j|un;x5`@u zef#r@`hE(J7MgtDO!#R`0I_nNsj3<#ah)jy4x4@v$2dSnn>UuDmGzFIF5%R8kawG0@YS+^Bb_KECu|l-p_9eUhq3 zwAUc>zrc!o7XWA7B8bnkBID0LAhRqGOlN)NpWN>GzNWmRD}$NjSveT?>Gig(-?u*& zul(sU`MtU9yjt0dj8>NI1D6d8M2-=I-avPx3%YIu*!<%UMi_n?2K;6r2Z&Cy0>{h; zcfZRj>J9aTAfQKZoII|EX$v5Vh~g;$!~kL~>Kg~e$9*up`ARjfd8z;Zb>QM;mAYS2 z81GT$vDNe#`r)(va@nYY6KK>U3~SP6QM{uX<~FCUjT%M`)5)93YV$IiU~dsX7W}_% zgE+6$eRvaUmxJd<$)(@nYI8x;1oqFV*QIqu|F6e1y>9Dk7_Z@uiA{w@J=%GHVh_?X z%Ya8%YfaMk#^=eQoAQdWdV|)UJ$%BUze-ReryB@`a!`hMm>lKN;rb~wDG;6kPVT6X69G8%i@1ydJh!hCRaE(ZuW?(R-->Wg2@$+6f|`E;D?_%dO`O6Bq8zt92J zi(kjIlwU%b>X6U=%)8FruohkcuBBimz&!Tr+Pc)}k z?H2)-66uG9D0W&@NmC5@(9ew&wLZ^JQ*mNzzFy6*VxX_|c+J|##BaL?pLw4{H~cK? z0WZ2OPumTRzai+w+=G_=RVXA0->-sSoN}}|aAP>r zQvQs#MCm9jcK54&zp1V>joXpu7eF-Fkq3-!7^g0$cWOgam{>%&GrCLfmG-Z~ik0au zHQO^p$UVq|Y5plT3n2Q5;9L9j-UYQ{jeeEYjY%va-OBtJ=Y5;}+y6K}eebw_EM{?% zkKZo>%fcM43sba4#_w!T=1ux}%)>I7s_y6-6Tgak@T=T9_S`&<4k)FBZcpLG{*TqI zGEGcxu`If6_0I3D_0wM^BTqrSNFVMB{eFPSWFTat2WuNJn8Wd zjkJl;G+|-c64wvoKW`AL24_wTx8X=rQAVcGeI8SC5Rp>fR8r&`)_8-6 zJ@~7j9VU*B7hY7=JO+&)ua&@R^Td@igBPpHC)5GFHZNzWe5b#&Fjk!R*9a?FJvm^w zmV;xvr1P|AvGWBx@@l_4kKi|eX338{Y zvI_PJrXogz5Q=|-tWC=47V%B|=*e5ZV}BL)H?YuYIcWtoZ`n=IfrQf5M#~Ga0%ocX zmnE4n*qa2X9*N*Hei_nD!$r$3Ic5%~!Q# z^$@LvDc?y021F$HOSTlJwvI*!m9W|z)AuGH{ZH!3KUWw1e<~{n4xm{`-{}Fdf~M=t zcIzGW&+#&oIUCj&NURmY+wcD`1ObQ!>nFOm|1Wv~2T202FKT{O`M5JjsBq{7@;Bzc zL@sd!Dto7vb(!p&q}%^xt=NBYquPu2P_Kpgza?VjsaV5-Tju{Tuy?fTSkoK zTl`)zfCsCzci1awj(7VvH8KB%?~3EPhN)5)%d7qPoR62_sjBrR-KO5COw}>OF0fOx zjGb87hQ|ANIpIAorw%h#H#1{uD1V$6p=o4!*Llaay0_l%z<+}!Yp_ZzBL$G!1OG+! z%(NVIM%DArby9SJKgQ5@ zbqwx^68=hBYhPd5@OZUI7NU3#T%V`iPrXpqjAJCG*|QKq`K91%8Gv^97j>lniEAKM za`=O?8Fd`}$dZGSFLi6PH!&tq$zzKM-fl&%guZRt&7s|qX>f@F$u?Jq`$bosWis(5 z0E|Cl!Abd6sC27Qx#ivKfkpVH;K0F+mq7fTU9pzaY|B&$>)+M4{TJaZg|H^y3>54~ zp;EriJGIhhG*wZ5+uhVRH{{MRB!?S7z6<+We&^fW-W2eFp}7 z2b9G2V)lbJZL&`LFYDv}3t#Y=%LfAy1bY)JFLjOBDz#`}scxNsXLZ)ZIAKv+^b^4_ z&B8;XlG&?txiM|gdXbl0l3$X7EccS11bRh}zrAR8;caATd7IZp$$gl8dJ)}TM#+6! z`jj@2zZEKmAHiID78+C@pT28np0%EX5dNZFbt{Q->w&Dg!U9^!I7P9ZVc6vqEjtZ%_r`w-L+&H7=#nPYNwpT9oK#(eW zC(kLM`22`I*DzCsA;g-26`})=1r>$J_58;l3@}c$T`c^SS$azG86-GD4SHYlrCicX8OthX_YR>xEvVyW z$|~OUIAmPW8l7#xB_t_Kf}3p4a5A;Kqo`7%&v2cZ8yS*h+bQKTZihE|W4_sCOKX%`pd&+}QqRrOu>I>N>Tj$zyL?j%E{e%1sR>C?yZc1&XCCX-YfIP@ zwUQy)ql~HI<3?hv8f`pn=BJnW0?L{0`zhn3#E&-m2B}8ASxMAnK(>V0^l0tCGT)@y z|H$Y47nydTmp@U?>-e{=e9o+nAwOaK(ZhT3a?p9R?h@?GlDzgc z|5dpBFXZ43DR>qk%6&7&tdGo#z?)<1ap-KzE7$orG$!Q6BY#_~g8Klssbi)5#k4QG z@jC{-tVy%3=3|vunQzcf#cfi<6i+GQxzsVLLX=a8eXPwh$YhwIU;gh)Bpc4WW!;ab z=|YAtQgOD``Kzwo>UWkBu>)RmnVqvvDCy zo&J_C+%QcHEJ%6$7q@{BCby5nhNj#e<_tA(@)zY`u`oP$&4UxuoLFBc7{B@(;t*C9 z=y8flrjCUxG@Xk*q!1l)1s!SOjrtwwAr!r;*A~uTvtAU+ZWM*kgNzVWHa%|_$P-^S zXX!%R)ZN7=xXsp?pF8WTIw-AG6@OG?c9ZD$T-<-rdzNKf&$^dx_)b2=H!Qj}ywOKA zV?%mnJH&=^oDv^A0 zr1!;2&+YnlspLD0R_qdbHb60SXEv|!_&ZoAv@!lG3jZIpq#18ZDw#a)NKwgQlfABxY-%fQtZ!H<>YEFJoBv9Xa+%hA@K|cd~76<7KC&K)FqP_D_YQOfsa>-ikcy zOsnIV>Vp9~)KnFXkP6kr|DxwNJ8kPe`jK!KJLbM zwm;WiPN=lYnMieccjg(&xr_m)2-;K&q#4-vJvw94bI{ERNe(bSuT+-n3E`ypisHp* z$|G>nXhu^1@Enxw(c^D&(l~> z%p8>W;X@Gk#5i=x^N(Bf3aMY$yRTGEFsk}DqYI@d)~Qxl*~+1OFYW=9 zU;jdS+&N$19FM|XUc#V(f+N-~7s97HKVy|f*CZdq@=e)!Ze8D9A547#MsVysOV9n@ zluvgwWXt6IC%bKnMevX9e|Dg*NQ}ueEm3wS`_N~??_))ZHMo+PR!FTf`^crEP1g(=@{08yO z9l-{M=qz6d;3m(}t`YTnF@}N{Sp*c^N|=^ytP|`zqs?rZ@PJtD?Yu4Q3c~Zv_U9$6 z%NRnfKT3$=qxNB(rgMEG?!#n$s%JU)ai?YG{2u)kE=rM(&ly=ZY|9xEfu6ugzFr5- zp;3KgE=ftd< zh3My z_rs2rBL0$J4I@MY52}hh!I?qOwXiewHebk2;zlYja9VA z9WGrAqt|J-2T1S`i*(d(Dwmn-NGAK26aMhjZF4hnp1T+2d=5A^Gui+EtYV&a@X9R4 ziR4`f%w0q*KB4^F4~#@m(euqnnm0)M28x1nqmI-LODbM`I8pXhJaSItgW4(sy*lg$ zDn|5<8Ppq&6&;~QJ-Rq$1Kg+LG(;sotdHF&hxOvH2LZLqZbDO`C zMS~RYtiSa2MPNG1!{}gR`@~er;WCBptb+3TGliIu-ElUK3!F9c0>o)&b zGY5?!=I4HkGg^nR19oid3{y2&HKek8bzQ~|68?BKB>uxoFM>~vr>vZYFN+^xZ+Ygn zoZSp2JUOXh4M#_b$+%3E#_j&Ydl*R>*Ga94z2FlHFzZz$e}L2oS-pqPf4Z%{sbp)W z!6vP!cY8x(xy;+F?k1Hu$<5_NvU<||gdtObCSxoJCyG`&T=vpmZxx0GBQTa?0O}v_d&qE?<+{yTO+b_|811KF7=h(P+o2RAW*h;^RtemOf~+3%5o{Apbq<@QC(A;!2`<;TX@|1@o|!M&;c1;&m#P_1R3 z*_n3y8mWJWM)ik`h`If@4K9YNldy^`3M{K}kk|3`Qfd7Mp6hm6FTqrZ2d{)BbsX8l z_kesXjx%&SxjlLpXAu9<+F^V_Axs-t*z+F0Ld;;FHbU>mSYOY=mMz<+xi<|6wyzIn z1;gb~^qyL$SpuTinCokiI1Gu#d;&)fdC zDkulc>HWSdtm`ljddM~CuA20(0^S?<4qQQ}736NdMTvCNWIlQPG9jj*j=fBvw{zt{ zBdcMmKSwBUyUh`o!SmOY(v(Hcx;?Fc5VRO-G=(cU+XmH~sv{xjIO} z7AsTHJ*?;i8TO>}ueHWKc;FHx`|h`wpRTVpJ_8qcs<4C=2Lysj+fHc;QjW4ssZbl* zBiNltD&P$qt@7v5P=4fCmXtYfW<_9n$YnZ!z^(*r@bymZXQIN1_kP9C0Tp?tLc!<* zNi^Gl`-%jXKd;ty;z8qx6#!*{{vI_&0(-w9pvlTEG$bTU|XgvLHzU3Jk_5 z&-li3J0XwLo_gLm$~`w(0c8Wv(nyv+$;VQ`i4JJp_bt4&sq>OD6e{0@Z7Wq9;IU^S%a#ZXXf>5^ogVN*npoSsH{|7_U+uLju~R z$OBn6nePQwGq$nM6`>&L4qlofTW5Q%1*Jp7lQ8v4bSCG97^2#8SL`aRI(DUby~kjE z(P+b<(wIQz1H*H#xPoh*SPd?QlaP#zUEn0@uRwqP;}M_`fIH~fb~6?&CfLxsn~HkD z6{3Pcf>eH!x}l)kXjYK<J06zg-pd+#*~klI3S*8R zg)>Unz~W-+bu`WsrTqI*OU%!WQhDw)S7m-_AHg_5+_`<87i6mYj)M8i%~r3dU) zj5@#58=>jTKMPrb`&Yuu*Uy_R zQBc=@16g;MkYt=*R!r`OTm63eiP3TqjG;{4sZ{Bpk8oS4!XI#(SLW5)*S>W5a*z-T z9jjO~Z>RICPrV8tCa*IcC}hw;7^J`rdDbk`z7CnJDf4`h3yq>^qvgrh#h;ila;#7L$xUhnrOxB>3r0V#@E+oFG&SCVzYK z=x0y98STp4=4oO?@~%}|1(+nHY#~hICJbYwut?Lmy7JOtl=)*H2E z21Wvxuus=Drg6X(yL8g?7MtN)aVAvj^VLSq8wcNA(2}vC;6K6awr_jqWZMZ?p-^c` z>r0G#*E2CsEu&}1I$G|Q6)k|RMud=czzm6A#_A>$4t2LU?2G6f$kAQqN|YJiuIQQa zk$Lp*(Wf6Fbxt0B;PT~6Wtr6qe`5T4>apZDPm{CbeO2q3BvCmWx(b)MXsvZ4VBCls zbYnD4eAYM2O01m97?Dz`0sC5NQaR8&O3~A-sF3bmgeRFqmGq%aXh0?Sifg2AZ_QVZ zd1hGiZUOr{E-$!{{n74S7YvjHJ&ExxJ|QL_IIF^E?(2}cpzv5^}^*uGa9w6%nT?C5@9_KU4a>(2xT(;GpLg_ z;7*po@BVDYTbDU4-^UF~Q?_P)x!PD_+*Rt}xnq3P*nR_e!;5VvPcD$12p}*wBM8Y_ z1$Yl4g}u*(Wv4I4F&JCA*LiRJI#dCbR+;W5KcFEkRv%B5U?+h~Jie@8-{rUhmb~I+ z$m2t+iu7|(SgT>Oy@|aui5e8BHTL5^9G)oadbkq;(2u5L>C_{N9%pF^AgX}I!rQjZ zA$pn@-6j&%m#kY@s9qAy5nC*V@P%3%E}5KA5%h<}V>h)cW6%aNFYX&XyUo z^ffxIbTF4Yh`+6KWr>Jn$Xc^zaHQ7<2D?}=P3ujameLojhM}n$jQ3+~JY_%ts=t{W zILTCG?!3c`{nFi;WeLG+f%!EdOE7Jac4GOa;LRjx1X=0@3*mchAeCvZ7n|4^0*`6%v_8iO%T}*haJoaJbTfvE;!YhkYyq{2voQ=jt z>bsIMyV`jng5ZsNY#(2&cdF*R*>&_@!*H4N$LhB0-?>)oHN>^v-j4}h`BY%yqx`B$ zaev}s93s&XP_8sw8mfx1h7w=#=Nl`S;KcXqFd+^#fXGUZ9L5JQk#j7dWZxF?(M$yg za2P+F7K4_XLcDXRi|>;5&Hls~8c|6BLMos!*FJTuw?s_r{%`x5tj5z}9OIu;`Tk*Z z{6XatR#C2}7kO26`B)o^0YarTg$7C z!KwdnCLoQUZpg<3?fHgDe$KS){a{jAf7)e6Sj?;l>&-=N)ABkT<<_2HQG9ocOM_E< zy3hJ@9{;XG_m-398M&KPGZKWXKXHcgt~dyKyDyc95J%vJxq6-!8e(aE%8k!PRUe0( zd~g%wDq16KLgZ%s=6Y*|LV~Z>A3b@xloR9}zx)O1A>DxoQ zI)QW)9?Kz0Nr!c*FSM># zG>{<2K|v~sUS}iiL0%+vo%lxn#0}37EL*qn)&wR~kKRvKylsgrZ5_)I;v&K}qfxJb zKM%W%evw5G09bLE2=ID#)m>6Gx2o?h%a0ZpBQG2(t=oMHZ=6GYU(>EDFI4&{}iaxMUv%w{yXw`M_FwGBa3H5 z(h!rtBaPHYJ<9r_)j{DXfTSj1ZshXe`VbWx%eH#chOm?8izZR+9PbQ{Cc-{ri)(de z!}V%CCqBCrPS`hE20Tk8jpeQPmsw{vFYOyBlc(X>28b}R*;@}Gw<{s-aHwV~DCZ7C z#4WhHIyg=*%K2|uyQeK-GLNxU%%GraE?xO5_pTljc%0n9_j)gQSy)RLO8WfDS#7?E z;!zjnSDM0@)ES}i*$t|b={r3F(+Q`kd=)ZtohAA5!23hK{f}q99aa|emrQ2$%*ARt zcnl2?y!N;PTf?`2X#6;@d0S75sNgWGu@xCYv;K6MV#X@4W{!fz7V{@BS1SN{I>4Q0 zZTIcHUhd%=t>S#(O|pA*y~#PNbW=`<9WYl|kdWTq|8y_S4CZ_@AvxCl*g`Irodc$M7|FqqHLVM*#5b*K7-meA z9=MwVr93R}Y^6u!Z)^4pM?DgunXmSDK>^SiB9QhMg}^ciZy{q|YjR22Ga73TsPMWS;kCwL^mW zjZ>E&{)U+Q!CCqL;O>CX0s8*XSWCW^HTL}F)kxtZQMcceat3PYSx45FqXqTJp zEWef$jh@=kQ`jVAN0ID&fgPp6>REOW>ZvsTL2#TgR~0sxJyk z6v+L9SWdrx2-clN1}wmx&Nzp;q^hMbg^^|b<;G}ixI@nH9bh0NhhZ%D%{i7lYc}-e zK+@Lie(fwVbn2Jnk`;UL;Mx~nh6H$hS{G&ge)=*pXi1Iv64S&SbLxy4|AuWxHXRN9 zQ40WCNQEgH+p@iB7iU%km~A?9Hk-*5GUXgO^hKaQcfxh}$wC0U>t$_2J2kkr1iFF^ z87*W(Y@n$_riX)+9`%|OBxYqan57ch5^|qr;q`zSC#RO=oj|K;<+LOmUf954eGmj! zm{Vci`3_G9?BPN!QGAat$&nCdV7(m}SM0&+E_QpOkszyQ%uwPp(c{^UhxI z3-AbB(ey_E&V2F_m~_yp$Rk+)8N~okyp8jaKZkH8T6XcQWk0f-g$I+aKtCfc! zu|Oh+h-vhJ>?IooIQ3VkHx0&NyE40Tn4xCVUWhTYB`s-qBwp*%6lf?!!Q^2aOBcd9 zFbWCAFt_PH*HMiqWzZ1LC@ugMAULLOAQy~c3-3Hh8oih(WK*1?uKoYxsDI^*$#L__ z?IRXVj-&CJD-OrvK(%VlWg576=3+k-=RkgWC32Vzk!F+F_;H~Y_u0W%>fVQ0P@q&_zq!^A5MS25?&_Ebx0ctZmYTiG;- zd4+MzhW%_W>u=ErQgFLZ>E26S_u8B=KEanA9wRW=-%>NDVv^O9t<{dj zC!oH7gpS8B6=D`IKSW+5Xc9#J!9iW1;tEkoY1@ZD$-C`p(}{h&_-dLhERfVg)xE=4 z^wwS^;v!KinV|z>r`!2bRP}~JL9a{6O}7*_2~u0tgNIw91T++z^I^+PDa*&?V*$`p?i|))}LCkL8kwv4&;461sRkttG zU=Ge<7CepZkO~&oO|2@=5fIf<=uEL7WPdxn>1g;}$&A(*m+k~wO+Qrs^gWAf?6L=y z1`@P3K8kX)?rn_?k{$osWlrr-?wcNunKZurp%vo^E<4#plGg!`nd2b4Q;l6|ijt4d z#i~F{GbeWwj;82H=b#iix89(!`F~>1^jkPYwfi7(YK^j$>*0xjfDMps{voD<@4nQc zFog-*LUb1sAbv}Yxmk`r@)~($0f0p-UMsrcX>{y5^EUZbUR>+nJIarYjEvA_OtXw< z3ZEf0eQz%Cs$KeAQYo+Z1@RV|mpiyJs#jZljjKs228K7gNqYJFx z0j<{02_S#v%!9Ja%dhu+GzgpS(9|uCnyyQI(cI>3T)2Key?#`?Ex@v)Nl!oe9lt@! z`IbufFrZVxqV)9&^Hh|azYCMd)|;y{xn!$LH@3AMM^Kw(7&Aded`|`iG83){0j;uK zO#z?w3yyF!RA(4otg+-9(#R#uO`Z7^I%r0);R6h-p6#wG-l|~g`1@M-T7nT!>aXp{ zvzCp8tKCkAK+~P-3AMo3ot)*-iIL zbLS^P9$(ChHin&)vECkPY~+&^>!+zq?N^~i)Hz^!ZWy?0e8{)Uh>OjY+Tt}XHVy6P z1Pf`}Vx45O$sKUuzJuoe`XtF<-+i)j^@4`{Qj|7~wMfL{Ih3rR6h z166W`TQw~?T+jyngeXAr`V12N1YAGemcBu1l?R-O>hI@C?kiJh%I+X*?)u>Uxn|x) ztOb=_$aNjdxrR8j4|5`ZkIXS+I4CYeM1wdbU4jV6WNF7l3+#{_3*!_kR;Rj-{B5Ol z4XOmdw26Y48kIX9eOFloW&e8GZNqIqE zqKHQ$QY`Z+#AK{RtSOJ?VkD-@>ngTBGuY3-f z=UxpcOBPxUKx&^wFbt{&A)cVZ0m8_+)v7(t?QAO@eEx!GH8?H^x^tiS;E}$0$CNraA95E;~{fH13Y+H*0rrKS|t<~$n8xAmB&=p2Id5{3~@JYS-`n*tVhYm z5fLhlLZ-!9TSDmg&nkv|@2wiV#8y zB6XB0`fL`PFs*d*8Y}e5cQ=%!ehK1&AgmYPvz(-<*mEFDtm%Qq)@Ki0*UmZL@{Tz4 zVp7zSBj}X*j)wlut98_Mrlrv2pCW=Mr%9}s%|hLRx`LQ#-_G@LF&|?=;7oro@nytH z*aBm4AIy33O#wT;n)}#5sMXw>JJ$ON;*Ir`;7Y;`>Zy0s1zaEYr0MpjmZSi{-blz9 z5uYNeq3XC-GFyfxQoY8zksj86{`Mgo5C#{x8>RvCeU`y2@FIN&mXg3ZF=YuhC8!H} zq`1n>+kp@?!#~-9ouc?;u;LlckX55%HPIE?d)BC6lbse#RZYFQVD+aX5+bG@ zAWc@Kg1=CP*o;h=}%TJ!eQHTG31_zY=EW+T;pY{b&Qmh_65 z18P|30tP@(@R2H2$8BhPh4%MNaZJ+%>574nvx+K`^|=Uc>fVn&dQT>$*S=ZiA1;eL7O+38^cwj&KJxoA$)^k#!6JB9>Nn5M{+K#HF>eTq`-Y@}bl?Q2e zP8BTnutehBvEgzrI!u{Eut6nS+tI_4SBnGJ+8v^JG<@e4*Y{Ug!c7uJ+R7uIZ}sR* zZVTa=hdKheE@R4>;>By{BvDgiu&XE2CltKzBi|3a`b+}FR`hx`!Bw0Ip;tBe*e2Z_ z$SOn9jhyRIu05~Tvd}GW8U;#+-s*a1EI8D_I)S+$VVSuHyxFmkV3-Cie?0K_ zFMQRZkS{W|R5o)q=88RAtGwA(^K#fo0(8%j30&(t@OuABC@0(&2+K^>G~P`L&KV&S zWOJ|1O|wLwl|kthD^d#D84e>$b6fIO(dkKO7pG_db9PhmjII`eSy7IqC*Wmeta?tB z2d7FJz|jIyZxMprl1JmOvo)4suP$^y1gL?6W!1yA8bXyIZ1Dzo&E*7Qph&{_ z(ON?Q0AfS7zJqib*ze+<#zK^(68Ov2CTXI#cEt>HWuyaVy{0_wh$nh(^}i!9kRyLi zf;IgfpzsPHO|zgtC6X7uD{hWx$*TXMO;j-emFMCPqHL2;kjzd>CU}Pg(v!!j(o_Kk zX*TMOm&;}&2s`AR1TJ7>!ANCTj@=6m zNRtU<@r6W7{X=TlQGzB)y9)QUVs}Ve+oNcEf%>`Z-|brHKKyy;#f#u?p3oG$e8TAf z9bXx7YmnFN`4IjHiATxBRR^JpOuJf6DtM@4in&4>#5=oIPxGc{15h3#j#;-f}UFCjV;;K*f-09SN}a z({-)*cHgMqN>6aXQc`%6WH>aUwWe#LEjsaWp$6iv?Fo;Vg(zoUV7dV)es$|bfYAnh zU-XiKTIh=T+7WWJF>L4LVs_Gs$2|gY29(h2m{?Bpiqw#^`2BeKQ_;6-mQ_X9sjf9z zQ%*YLHuiOn-*@;#QT0WAALk0>^Hx3e6BDU~#02PA;L+^iYD{9@7YSGm<)Yd{Al3`H zuKN8GGw|L`uG~inYOQn6@vlUU1<#Si8!7|0_fj%4y@VGLDyKXMOo(<`Hj{z^ z=aEaylQQ<^9hwHv~O*8S6EyP#SvgJ$WG$ zE@L8Wli55IWu!>?tBSO|Mo!Q%^1`kY2|=_^u442|JWvfS$wp3ObW!wpzt}Xirfnk?65uH*h%YP#A0I#Qxwtcprbp)j)rbHy08e%l5YT|%sT{+P8)V#RJgS6z4X$N z=PXLE_pa=u2NM-M&~YEC#j9jWB&(40j(kco`#e{DOR~p@WhQ6#;wx^^T&J#ZsK98O zTge+7fg6o7e$%Zm7s08WM(tnd(W5vh$2cV17Fm>T2Qk#)0?|AJr{c4V4q^?bu&yuG zuazXJ<+K+pTU#fDL&Neox&k~qRyZ_CnS*ks0CPjYZL_gS!|Ag7_c$h5LhFzDH;0^x zQ$G4htUx+>dwD>3)0H=RQZ~EU6doF>b{22&C2KgO>XDIDJgXtb1Kyl$C-7`AzPnMO zp=X6+w@6#L-@F5O!YfSqK63LqAOjivc!g}z{R4r{Vg7*YxlGih9vGYn;X>$|R%uuU za%aVj5XOL}?Lu?qyOp~)R9&StYtG91;m@&3R7Tg!Ww#x5iFB18X^jm=`a9Vs`TT*~ zL6;WiYTnZ|@fc7+v{UN~+=f2f=urymybwM54l+;!X>KFKdrW458w27-`@f~<@)Od} zq&IrH_qAp}g8;`=o_R3BA;-1v@f;?h#mOC|vd~cpaE8W+ZSb+Kh#RGqG$=064>L0k z(>tN~K#-9ub~SPjk0SyHx_GVS%~`lsF1?)&UdT(=7Pxm?PQ<@=`g|6OEnrXB?ch#+ z&(XYx6oI&b89}c%FAYa6>%LHfRD-yEQM|NuAtHiPcwAD(QbOvPI@>2l`~J$#1l+f% zJo})7XI})LvctS(d7&1*Je-u%eXy`zWJtG6-c>~FkFW40zNyX~ckLc5Ac2@Q-Ev=!!z=5`rv@h*v~na~p! zq2ARgh0tH)s%{{D4ObtS6HW*bI3Ba_@fW@)fGDf*_4Fl~m|(EmYX1OYIIXZB%VoL* zLKs$gA6hl05UYr!mOwnvB|_-^h>-0fgDKclYHN)D$AQmhKmUC%#1sz&xcAkYt9P(X2^t?W-6lanW8r-XU2F znn1GR`EJO=C@*a`S3)yt{d^}`fAac*p#$bWFUj}gHgZd~h&0+Jlb07jRNIkfFtGX& z%|p;@FgziTAgY3+0lEv(WIzZpy)Bs!3MQLEe&_s-(yBvZkvmzaZCpx zz$Zvz#SQd*Q=zX(HmYB5I(ko)hG-$XlB1)iP_WRZtjbR!39%^TQz;Ol4WWut5U~rA zyC>52q${gWGppP(llrX=p)vfBpsAS6;~D zykj#U7XZx+6v8^8#4Kf!*rsU!at#?($>eO zK{iSUHwTqWDAZ0Ea1C?FWF5ggnf&ufCl>*%w&8%88tq2jC?FMQ9Tu$$^EUVqu;E0V$hMG!t@nL! z%K+igu0pr}{ zA;yi9HcB|9b#zH`nH-`xcl8cI1k2N*Et5gpHKy>sVjLXbcC;Q6(;0DDV2*7b-R^?4 zlJRuq93K4aRJ&T4e1~M#H^oR$uq@)hEib4=>QO_MRT70$Fl-tPFK|^?<%^G4c|G-n zR6xuN>VGsf|73{(f#YBh)(>en+RX_^$dQM$RcmUM_q$lOyXCt}m`>?wJR&lyMxdii zJJwomkBR&>$Pi^(rD{2}=0MIoZNNqVhq?ApK0yI`&4UDa-a~*+^qb*OwU`z|Q_1>; z%jJtnN!i~FVC7IAICo7*_jmxxvUrW6XN~={=Fm@K%EN3w`ra(DY=Y6nnkC)m?uCMa z8WAkaBn7a=^r&g?JCHjunoBEAl5Ix2C&s%!9d&S9ZESwq+g!bA9C!{+!lQ$3{-@@} zk4$SJ?&+eo6ANuVwic7VjTTjrfi{f(wkjqPg2c=Wk+AF9YxWd;x(WNe3+*Hdc`a1!X2s@sXtQU96)onk zqB9XWGE4G#J9#?b4!`J-s6`qWRk9&Wyh8ZlG%4b9ray>lQr}-)mey(K;LeBiPO@VU z2Ou4VsP3e>$h+PEx-F)qHK0ZG8~;ezt(U~6acP&n6RruVp)!+~vD$>#O)PmqKE??m zrRjp*Vf7$sSEQZsLxOn65;$W+cCN@1QILre;I`;OGnAN-dsG@gMHpPf2?j|U?r;o^Ccr7Z#~Oi0t&~84I|PB38;U1m z{6n~+>-i=w2U;-(B0v%hbASg(%(q^c<^PkJ-lmZ6POfuVv+i2pq#N6=_nxCwP7G{^RWGQgmQbgZK+air}Lt)*?Q0-qKz&OD^WIgn+E8%Ikt#7EfIW@XO9`!=s;-Gad7FjN=`X_sbC z*995Q3R=I)j7#7*-QxD8=mZdV$&h)vvBTl$)qnuP5t_eeH7L)`W7y1&Lb-+D^%Tj* z7=6*q=53ypJ-CA=g*-OD(R`m1beMgBipk&ic0jg3r%_X3i)ao`?L4Rp1d)ZfbtG1Q zzmUlNk~6Zr-7pJ!n|4ANDHXfx^k4baQsw!HX+F&sRw|7+p1 zOCh(wtAV)CtQVS|o&dE&^D*?FKg;=KcNlf&bqFSb^5!f@zW6l~ZO{#`B`7#Yf2=T_ z4s0Dyn{K_N6#!{h-ydx3DrN$-vezb|{hNb!k0LMTbzFF5XdZ|PcdnjGNZKbd`@W(n zJuCha!FL9Ete=2uUdYZ22m~<5O4G!w(iRRqC*GL@10P;temqJZW^3$4SGaMRZDGQ2 z!tI8{*C`JG5Zm{s)2%!+nR_~ zM^6NOYW*;N%QIFhrJuuDCxa!}?#7oZ7ImUG+Q%&-T3OqbY;ByLW;p-R)z(dvtF`_! zlg0T=S|)RCa-2f2l(K@3^9I8MHy&n2Dq!kEkJ#5G7Ja(*v~*?o?x*Dk(oaPsEOHQt zSx4o6-59^9e&=R4kr+P%nyaC-9>7RA7_ra6HH;5irMFC#PqLRoD+f{?dbBg2w}i*$ zwkr1vumkAn_T)fRJxD$ZLr3^L1C!aVveMaS9bPl3)Hm8L4kal?n!2stodGKpZ(FkEa9k`Kh57}ng z{05wSVzqE6&<=sbN!@yLp zS1QKqTiQ_TWBv^=8t?6~H1*}$N(rRaw0ZdkSr?!og zRbZgI6B9k`Rs<5UP^J1)M{cUHBM{rGgA6Q1NABbmqAfx-0M&S@53$*Bo1~h{81yMT zP_qoVYFzcMEs+J7K03V!J)D~ws%YdQFn4sZ0jpV{TENDg2WY-rWWF!QF_?WPp9ouR z3gzMk228cp*AR$El(&14O`qk>)q>EpkqrO{1G#TKnPF?mZv%Mi2ywDEI?UB@`Re+v4`^BhP+lYi2a zBgoM4Nw=m`UsV@YIq>Xb_F#6m-S;qH)ucn1dSermtaDdzQZ_9S(p_}QE|_lR=6t3e zc%;yH*hv)8dYr-DY9&d~+CyOcDHM)8l%T?kgB`RCZ~}PxKDFg6bahH0*jpapSx<*f z1&pgQ3kZRGw}!O?$e8CKS%aedYKQ>HO_&y4!W95{Lp?_a0x&seuqXLhD#c(K0%vY+ z3|#=uTwP!tOsu%oz9Tp3fIH=i>I0Z#b05p)G zlKe2T!@w)4Ian>=>9+wWDXG>5v_<|HlCo9Y{6B$GY^B2;m z{*JlzCwQD#esjC5o&vhxe#zRC9Nm^Rj@uTK3RV@wbV#1yH48i)kP6km_lVg+*tY)O z>^@0j2Vw^<$V`;`dy~ z2v&6yl#eelfOr*+-J_5xXrG`ECNP!lAOL#I0PP4+XPvnUWJv%@vu;?{orw*Ek&Q^N zN1|mh$n*S27oq1ND<{SS20Ymd%qmmhS5j*+NgPLhVRBfHKxk)wm6pR5gm0}#4TZG>vohiVvZfTMxTm^W%*FayU5P+f z&l=plj*7kvQ&}f`u85ri7c0j@Q%lBi=pr=9Bvu3MPF(cKu7^mch-63-(($8-<_GlR z1A9)xhO@94&8QR88{FW@GXRe<3+bYHG^*81a9GGZxy>anW5hWqFIOrD3?}*YyBwbM zO>@^z%c*Go^L*!d8;zO+ro&8+TQ0jce1rI_U!%; zb0c_v`BS-?-pd3XAL6ENXUpEU)%J&0?4~AtdSBIb_@d&MjE4{mslq0Ql$`z!EK;d* zuo*KE#gA}M4$^~-`n)Zg zQr8XWgP`gtF(WNrGxT*5jGo#*=7vr|_&XqFB?~a<+{lwDJq3JXxzO!Dn`4+E4PoX4 zwc3li7Jl$lG`oty`WeBXAr}wTI*`PKtIriCmUlFWUk5-sJKSGq#iee_;l0MHG1M;M zJZ{)~&1=G`@3`C7sL_V<;B2j|M2@`htVVPZ+4=9IITOLv!OGNThySO#Zvlroefuw^ zW-Flskz*>mh{~xPlVmq5n_?zHsFZOk=W}UF8?hy9gzX?of$dQ{(kT8|NgJ{dabVAb&Z*PpXYw=!{@#~pQlo4H5KnXxqUYyqilr~zLGii zs$3_D8vi4ik`dA$&C@gn(-o9w{I0brW(5Y7l z!uU8O0)+-`>3tHInR*bg%^#dcoM@K`{nPl>EJ&;8_uk{{3QU#(S8!H{LzoUAYrK@` z%Tf3>kiFg z^sXt%?aih2=hE+^qsDtZi$XYIKUt~Nr&GPwXO4kQ~qt_4md9BXO5s=VnQ~~&oQgUKE{iqV-kEF;jn6v} zu?_fvTm}xpjqn(m6`x6EreowMkg6@ARn=Mti&D;G+^zA9krweHClh}rJwdh9UI0Y{ z$6exUqNgu%cHhbpVFT9Fv5^28p(qTdHW5izZ@2mG4G*IY$gPvCn;Grdqe^5UQp3dk z#)!hYsds++dL4MR80XA!>j^<79@!eBX_EYu=Sft{4L&ahD`0ur`AuOk0ZDD9;R2Jm zeaOSXd|Kl5BdXx=zzG0W05a63D7Z=fTMuZAG~+EjDi#)E+3kwwYK z+y-#JAO|u77sGGPBgjr9XPwh4CLKLf@qS;*b@)iju%?gE zb|~6P)hZ_)%y=iEY3$mGzO~K=#UQCzMkDBX;E`+0}-twR#?X ze7aKXXZc)a*T+mN#+@;%V5(kS^dPd0l?#U4*di@Ev0Tp38i<7pafY9v!iQiz$2(a`82}l}`R%pRxs;CQ8hM_hCqf zg3u8j6UHeDs|TOq`&6_u7~lqii#N$F#`o~%s2#<2Us{s3dno8cWt_s#D)kdLj(x&L z7zNg#QkRk-Wtn}3f=r9`;0*nOOe}$iL^L`PsXf<<#!w+eJ~PPK<~7}cFOgdDH*{{H zlWSn<)3s&R^TN1riR;6ZEm4@e1DZnB8?YdEOY%Le=i^(gL=sK~S5ffm;`CCk(p(^K z_6xtdU#2zBO*p05&dY*eggez07ulR$I6^=1YDwXnAR>kFHaem@{;U!Go|n2uV<-sP;oa2yZRMx-A6Z9@|sb9XUz?!-P z?gzMIN3HW4>`AcvAyt%QtS)-imM-Oefhb?tdaI+TtL1fYVcbgA-7w{^mlu&I@xyCL z4fJ=hW_(f90GD03M6e`-%4++fGo4M2I1?^wM35FCowLDmd7iY(A@RqmptSgj>##e^ zhY%|u*icnq;&7>H9D9Uz#;LdiAMt%=hhg{@&>X(NO1?D0Wzv%@Z{<X zlkfbnk{hr?;?F_U=_8cRhnNx}-@4)~uV4bBc z6>+Y!&K5u~NH;AZrM6KXng?^<^cA;Zu~|SeG`!BrBw_NS^m0jjIt-$T-TYq3Xa5u# zbo7cl*#N^UG5RBOI>Obd2o?0Z0@Wa$gDudU7$Af7Sojs!#e`GRYGti88P3}F%)>VZ z3z%hL{HB&yBB|SWHR^Vd%;*uF(k*^n+A;d?d(IBJLmt3qngoVFD`Ag1pl>ACiTswh zq!hd$_+|&?BW?%do{(0^!hHLhnUey~dVr7ihwkd<*w?WESw-}?J~qP2@>vITVR~at zoRO%1mx0w@Sn+QYL1?NYL=ZVh*1eidGGA^AnInrobBw=oR%xKLCCheSoU8(w1cyHC zQ`Y=Gc3Xs4-`vHccUwkF0B$(zE|M93*)mDI`^ZzJoT1jvSXesW-aKt*CV`o~LgV9L z-i?F&$lCmAUt6HivjGuJi*c#2lZQKME_@|(9dN&ghz;NpH~ARvHbUUG^C>Al+~A$i zJ$GHZp8yS(CF;a^b{4Y-FP-3*@m5yS5qhyaGj%SwdC;UR|2Ge0SK%thx5D1D~P9$K1Hm?J)24pQvlMqWbZuK%UCe@Gu}2_;rY z;v=^TaxT%EZf*j*CGsl;3N~Vsn_kUs_l62tLenmRxiT!sxKE^@g*g?ljt@F~*v;E1 z&^5c-X{ztDasQlW`s%Hhz5-o=gBS%qiWguv3KbwIZ_8~P>2LnlLlb;_CE@*?Ntk$a zwf*JqpQN3ny|~0dkBh}UIekpIdcT%I^EDm%$mKL=&(*j;j?owP5wx5*VvSR7|4TMT zzg1ItWI2*WQw~Ig>z{~Jon0~*58}?ne}QuFj}(W3Wx#K-IOKLvPi^dD#Ky9Dm%v^i zBDhHYgM0*D2F@?LE`)~#c$Ck8(47e#=hoen8c>+H2HQWsf3X*Xs74Mnq#O*a8rpUJ z5~dA+AjXeC?!2}>bf_jgU>za*S4b<}+9u|Xp~s`^>{&jAe4cnPcQUp-M0+v~;B|rb zsaFt@S>ad|7IJAvE#vG2%f#;YwQrn%c_&0N^NkLPSROy_L_gi5itSCk#7_~XtMyx* zQVB1~v+1Y{B_7x`%>v^904MLP)4X#V5p6puX;SaQ4**zx#s1DC_aTGZnckFDx&+TGCh6!6<&IVffW#q$Hu`NfaBZaa&fX2x)wi>Cci`%In18YnSSH+DsaGd zmZ7n88vxrqKxM>iC(_$d1_l}Zo5a6mS6^0#iEEfvxXNw3nNzb-Y;tjVb(!%T(dd15J0Hztf9 zAmRew#-<}4C#^sI76%-(O2W?E2W4-2U@G~&8t^aEIs(60i5;w!*n}gmMuZpvU1G8( zbkna9DfMkP?)MF8tB4DE@xC6n1l6}5@6U#n_cE>Wg-s9PGD{C87+Fq`#bflb&8kK8 z!w9@Wxw;-69T|*ggU8Y$kpW+xMj-rQVoI%#s7RnO`F>9S z2yz?>@qttU3%8n5|H|oLIi01zB`e+Nq8L`prMf3&%W6Oez?aLm0I1VaT*RByM~AiV z0oFp@F3=pi^9P%MAyjLaELE~e}mo}VA5bo=kn5smjf?D{8jxx!IGHVe+AseZ-82-I3AJM1->GNyL5H(c;AQc%p6M)@- z=JDeJyP2L5OB`&`Vh)72<#@h9t}B>TEwPdcYdnnNuddEB?{eJ8yX*b=Wj-{O(p5$u;A}h&#sAIJBw=eZ&cQPGY6~7x5OZNa@fCapkx&g>2H_;VQHR&_(x_{Z}jFe zi~i&ELl;IE3Hg>F=6bZnE7N-)bw_8jIV@ayt#>(hokk6;)hE|pn8;o9mAb}WCn3$T zm?U5i@e?Z=PhY^K054hKn9Fmxkx9O5cW7c?Bvn4FDks7%RM67v4*$#mAUm_&9GaND z;y%64Bgi>eud9u!0Nv%3GnYd>K;%Y}-b~4F-Xy zQoXjwxz`%1^6bG|ma*<{vn>8O5uF^PbjBFb=9NaS96C2dMoYt3=)N}J`{-`T(8NGO z_DulHq$7~{HrCXs75y0)&E?Pp-6hxb$pfZN8YFOl4+=EjLncNsB^a&{w;q#hxU^ym z^i;6))UelsSG^}bKQ{W3m0iG7y(8ALX72qW`P8Go0Jx$2n+{w{JEQN6AAkT=J2iZ- z;~tkYq0JdaMN}A_3aa6yzV^MTKlz!gg4-*Ib+X#bM1E5}6!t}BxZ~m@Ci^)~XfIIf zj0!uFSAeH9<3WS6Vzo5*YZ$w;2UP;`v!RG+8*)eAs(7oUE*}u(RXUEptDPWqo%yR= z#>-9RA3_x3<$&Z>4tG49ntW>cD=L*h;AOXbXPv$oL_+u{#4acZ%3Wur52F%(=PG_m zQW7)BO$R>w=H1;7@7>@H=)dTtr91Syk>6eKb@OBQ7FN>F&1ZTP(VE{$x(kFyK~{U? z8v35S>hlM1hj*H{s4LaKQtHd2{Gs}F&txtWhj)$VcGP&OwoLIz;UNh_&}>d^^!^CB zCW3%y>?g|s|1N|5idvFd19T5>z|@`NzU`E=Wun25+mO*#n%;29&)m5%cBccEzEu2E z%rRx|>8G6&o2N%pl7UsgF0sE!`V3n}5Mo}RPFxx&OO^BMi(GGl0k!h#KqkF3=jJV@ zoCf5+*Rp?U1{G;xXLAE9RcDsI$jkZecm*P+c|mO-M%wBS&$Fxih!#93CRLomky}nf z67xrGpS{+megyaf4{UZ=;lQK(p85`c?}V{va|1~^cc!wDQh2F)_igpHQh0klQv@I9 z1acT;yeDl%Ke7eJaiOcuPJpUlOl>gP$X~`A7)2MS93Kv9b_g((h68?@Ej{;(q<8ZMQa&^u0dd_)0vDvj+(~CEkl?ylk zo>LAn^129I#8wV}47VD#!YK>hf+N!ll;|q+mV=&_XUQAM(2KhLcFGv7E&`%UzwTg~lsZYbgGE zIVT7O%9h(Ha4*i45$pUc@MEgIA#;(ef^-``+GZ(yJ}On7eXgM0QYuX{HkxV-j|oTR zUo^^ltVA*cbh!LC=fKg5@IVt`(BZ7jK^kZN^ebt;?PW#3h7#e1E?EbPCO8zB$`|;> zU3Tvg6PAxz4P%YJT}@d75fr=*+_0h}SCA2DDHOu=jYq=62^d5)di3 z>I0hV`#PCMD3hAM&r@5&;wIk&IoiHwSobkAzkwGKw-oIlqkj8uE|PTD#Sa9fFGY7* zhL#Oh9GhOe z{YwI7KOP0(`v%-Pqq-X;L~aNvp4!X`HPsQlmkO7I-r|Wbz<*c%JCe#p1672BSrA0_ zI$wYH3#bVmMwo7S9K>MOse!-HT91UuEsEG`NWyyPX2bZr(xT(Qd9mFA$ub%NIu$lx zyWb{zX_uPM6ArC2hmI6n1ItoDh9NCP1=(*uCQb@p5LT4vJ>peeF!&g9G7GPs!{Bir z#CaM)El@R8fsWO06LlXJg&4dEf1Nd+!iIZ+t%t0`LBt?rED*Y0e9BH}y#Wc}_*+B^ zWAbSYwIkM93zGRwrN$&@x1O-t)Mt#zPHhfeJDu~+&N<*?N{oR(P`a`d3W0+D_|T+z zI`f2VQ_#vQyc*xZcRaZ!oVbdpL6{6Bs=>_)&=5H{ellFOPt3XFVvEf5v3}Xu`(D;S z5>NKjQ1!O2f^*&G==(nU8lqm*eakLh2Yli*3i+Ff5|UXU>@CazGD2hk>MQ6m3ELzi zNWQj{lKwOdFfDK}9RZ;B1zvDpwv5OFMB%I)K6&?fVrcpoYq{L$lgRWq3wZnHX_uzo ze9+?RW>sqN?Vc_Dx@R-W)$pX<7ml`IshZUE&K4_3F~OdLJNV55r;0+qurIq}qDhJq9PVy|VPFui0tG?0$#*sHK%h0= zk7nLtKV7ZPA}X*m({*r1mtDYwB69H@Hh;bK*Uma?$LC{-uvAFs0BH?m#+HL6e$&l8 z0}e)n8awcZWYio#I7Csqj0q*&P1?N_V?Ve_4n*ry1HjlN<&@X`@dnzh4RDtO0A%kV z3y)P`=%2x5P8_OJ2``O3+oEc(iRq=^rnYgwznoEq*` ze)%S-kUpB)lwy-;oP3oKu@n8niMk^hoA=$@_uGX}DSUTn%EJ4${Poawlg!?aTQ|H_ zK6d2p`HR0Vy&l`-?6F-YCS;=mfBxnW{l}TPI-Z6mmKu#My>#(|3C!VNtGk#9UGZa# zltL55W^fGtxf8bqI}cYYYQ^;Z8Evt75!MzJVzBy=p!E)?yrZZP(J>NzJe{fuz`K;R_4^>G5@ zv&?zrTRL((;b+rd@|m9G3t44zo%Q`?V#=A&7p^aVkiNZr@@4qs6)mR;^JkA+fRAZ4 zo;%fU#XPy5l(NbiW^rCh2ndyIx`;V}N@af#d=D=nACyt%EoG>SUm|Loo}J&mZ5-31 zAnN*hhe7q@qfsYk{c$XCc}C{%3XAdOumH8wkNxfX=|P`% z$_0u=UTtQZ_M`AN58l(mSJC-4qo8~FcqwtK;uXEiL>XAR>4nFcu$L0PN0#=ql@74a zt-C%uR(n^u4(@1tq)ES3EdsyIqXG1vvsdtBy=l`jNlHOHms|tL6`WXn^k|m1>v=sL zOf4#8R~xxEt1XBoy@=v~qV)?F`1&b{M{76zNE(mS+=Ex}Z#Spy#i$b|-nvYtQuFk2 zL!&LejVoNZZ~KtVr));sZL2Wdo>Tod2JB4x?qyH)#Gq(TBjk;7C&lwVNR9NsTB^g7 zB<3p0k>hldy-)mYZ&bfAgZ9If7e%Ua-tBeIx7d+^=Rlx{p{S2kWF&ZtQw zEIzITF;*87`44s|Q;aE@dTd)3)(RY>H)Za5?jUl=8#t&R_+;=Y6F47q8P=-J`h*z+ z1cPKP@Dsv68!7xu1caN$%XS)VLgViog9G}P2fB3O-Trzh_bOx7pDZTOw0eiu9j{>q z6FoB9hFd@LPWtaLjdFC+!O-+E`uQK~g?86n7bQ#ph_ertT|4$E7ycTT=?k5&y99iXLeF)b<1B zJ5PDD{U?3z~Uialj2C^}8>=GRIW8n z&pB|aSHb@r`C39fADjZacy*0Va-bIY*+)hJXDm>u%g(EfC-xcRUeptxF17BtSjVW8 z!RZxwPv*3lu6xJUVBA@TKMJt9H>@?oUBPI7C6rIi?VNbP4z)A8b=tFSVxn-Qz}XAh^JQuxxx7yGtm7%JA*bSLnfE@e%XQ-Qcgu+o?>dv0>v1x0 zSF^sy&|4D=MUA2R%|qzo!zpluVCKk*@qU+&F^qPXkFN@(ESZ9`>gnTu44?3+H_1EG zc}`kxq%m*&eK+&3+;h8*<=O0-Or*3IM{M;iKOz3d)*7;#4kk|*Q^fS`6X_iryx3;9 zxFw8EfO300vrT?O;Q(PuMeA-~m$YTBByLEyTEouk1D)yS_axJE5boN#Kn$Se2(I#E zRCX(JAM-400f);-YT0f3lloeURGe0Rmk~i!+`V0X{JljUAEmE|nX$#or12mM>ntI# zKJ1nq$9=9caJM_1q7I1ya)8g1_%wLZvQN1x%k-(Aynz z0rfYY<)UtX_anJw;0WbvXRE&Uculdb_{2Ml>KBMUPIQ2@H&2J%wmE?`gW&Iqo+014)d>Zu`+x_12V&|&(2=8s}BR4w*0tCmr zJ164jW{Vf{uIb2eW7gp^Q|h*5*GtHvWKpjMOfp?_B=9eW#c@NEb$ue*OGfvYZPdfK zmF78%iPv}*TO>5D!|BzvjPbVJs{+_a~@dUm6U=Q z>daFcZo+qo`St5Kt~qXa3R(FYB}jFU)wqkS5n{GAv(^yF7+7zfWyRMyd&S9I!xTiJ|M1=WLr_OUan2;WA6z%U9Rr#N?1{BZt z#T#i8A;C~>8qzM+AG8=33@rEwQt(=`+!DRGDXO_SpMarlYQta|A%D2gI!_XRR8nC5 zA2GB2&5UtE8pmEF2m>>};QUhUYXvdq;bs+QthWmPz{;#(-M)M7XN(BeZB|t>^O-m2 zn9xy5PQ64Fm)r`H886AFl;+e--mhcIN6D03NfORx+mQmS1C>68EK7knv*a>Ag&^wt zTudQww82$7<0lmD?9|Zb#NP3b(WUy9El-cNrdE%?Qo*^utZ^1Y9CO>0V~_t}R`u#e zerw2B5qmlXi*wPK{*sg6Lczf{Dm$Wm)V~Ya>{C3)!NKm&dhqYK%KwMYoD*rIPFghj zUP)XO5=0ypur~Cdgu+?F-j%?gRgYdtGIN;H#XOOg7|Nv+#8s{mR|mERiiU>bU#FH%rS^sJhFxyiHJn!Lu@9p? zbstW3%syj!1!6c~51ieMK^-T{{fh+q+trxw3rAO%sGQBXQQ-+ z1wwuM!hiQO=Xq@h#cZ7`>v7}@#I22M!H#0&A;N)y1?pg)EF}(0lGHvvROLZiPW(Qg z*jo|jTW(nFu^$urL;7jq1C>%px_2{1p95)dJPhJ_Odfyp`^?0r|G-IKgZleltlPi; z%!;|^rxEYC$cEe69g1E!I(F+%a08CUN~|EY%0bcIH}Ao#_f1T$d)8oy!ajyFo4u0@ z%Sou%LUk{J_uhn0DjM!+w{)euP!b4BkLqAd_)J+}lnyC5dF|2ukwWc&Qj6VMg>n3p zYRxW_tH~-coNYv~zJ+7P_hJ{rzV^uCOcoQUYRlkJ*G+Hh7>f2Tg6Uw0Gnp8&n<~%J z!)T9`h|K}wW*k4~)MAtk<~!(Fv3@?%!~W6l0W$OQtpEHo@6Lq}GOjrsmVoTRtpJ5R zY3rtJ!AG%KM%cP>30^{OF-EBrjrg_Y5~T5KZB@cz;~k!*1V3z_o;o$#k>6CB1>_=| z3IGd$T+=B5=jrh=TiBWUf72DQPx!ZMaeDK-A|Cm{|Ku|d&Bdzf@r~O{Se^-z1F@gj z{%JxIIj5vi6K8Kv>d4qYf@yD)fm2f!Ds`g`Cx1qYm<43PQI06EU_(J1fYIS>Y_m7mKK95J9PIf;iiuy3L*Tx+LRmIcsvA>=JYUp#zDQRkcI6(^~U+=wkD zxV>6(6v?v`B<03GTx{78c&a_j>v?0=7E;VYJ*+<2bx4AmD*+Xc&wUAabO}(7BEAFU zw+YhAtKm(m%-0oht^+)IdKl@rfEP=jHK?Izc7fPJa1#JMAnC(`DqLvwrIO&1Q=rh5 zK^`36j@b0@7Lpnyhxpvj@8Jk%b6MAv+a24@{9NJR`rH}+J28H8l72b3XoAtYlGo4H zs}(EXY>X@e?ZgW_izZfkDq$|cqa{J$!J8BCBLdMjAq z|Kb+$0Y61hT!g2H`C0o`5XKoZ`R*3dF5s^YY?Q&hXh-#p(gH9=nJ5K-vx-~jYgW%apd*X)=L~UroyYvzMk%SDFO*jn^H*y-dr^Mx z6Op%?q<@qz>S!}xZEd(0I=<9ZoEl_Kp87oHC>z0;hgke$jXs^e%}0**b8(vX^I!M| z?68@Qm(3I|^P zPa{`>n-oA6p+N+vhj@oDtLGGIPIS{#eR%T2Os{0DGvoEBRgbro*ZVu$LWlvwKLkEq zh=za8mnZ$8e;s4(-}avH69AcYE789BubnQ%O0s!CN$S zSr7*)uU5BvwFwVXJwBH(v(WejmB1f$BuG+XsdUe^@9fiph^B&wxtp?ZJvn48=zIuN zcgAagrm(TdCr!+*!e>~PT7X8;{*vknzigKTaIU2)!{8!B2 z{kE3-aN1@nnFZw#L%|=8(>IF$xd;tb(9J^1?O8}UazGsANornANWUC%26a#O-Yu#; zWrgR2kEe+PJo=^!y{fNpGOP6qR^YO$d~U!%pEzjvgmWKvgr<;UNJ0P2mFocgp9zx- z%3|s*b@9B-O!5z`3U~g}3`yWGChT`UMm{BhFMGpJNH|^gC`*lWH@b)!ca`t}y4uY_ z$5}0ug;fGB@dZbrH5NXF<+21UqY%jxG8=M^L5+`;^*R{(evCF97jgM<%h?=~>?_C+ zR|d^Y6V2@P|8WpwbrWLw)R8G$E-Ubd7Kjrx>p3Qm!ltw91%K#DcMM4L)Eyhyp@+tv z#H8eLKWAsf3(Aa_cMJ>Lq<1Ey^WicZ=bdjBSmpkbpCIN`IJBA@owsneGrtm~S_b2b zpilGo8=IY2VO>+BuuJz2*#{i;0zH^msNrdX%q=K`d086-G6jBtf{wwEbw|@w0S@1W zT7V#hx{JzM)`65lVNDQ6gJn0k5tD^VR+%(@tE}jpSM_q{feU0Rq#+CRIF_CY!h9~t z_P25IGci1#3iTMI;1$pfvOT{Zw`EaC>8K1FT?7a&jL3Y|_xU#ff}y)%&d13y7E-;D zHRXKjihDhem6*u!nx$E0smR$(TxDsfvJAGEi+DPez}{ffb+~pEZAVDl=(wj$N{sSC zHRHx2RmGAIUvTVTImd>xR*>$F_`SF1HrZIdP{ZbMOXaHccdx2q3pHB*&30z`;)d?G z9X$MVrVxOpPCA@~0LEN72piJ4<2WkTaLIqrl4JM9zlHSwKhI6nGjn)!0OJ?uVQ*)| z>;xeV=>POsf(X^C%6I)CN7IFSL>+bcLbfHW$8wniXa;$Z@i*NZ9gHm0$ciMj(ek8K zsx3ajTq%{v-134<{e}sS8*G}rr&L8OS$)^co6l3rOBcza3>FDo8(?=QDOVxpgt9hx z!$D2Prb~xK7p@UM=FycK&Y<_QI0iZx1EKsFhgA?%mmaU#0Ld>43W51Pe-zfzu9!8C zzA*PS+;K(8_(yFfmM>~CGVApE`%#sqi*akH?>oc}rvghCAl~md1&?ZzR7gJzq!9q` zPW9Vo?0B|WQi~kbNM?AVb^~=F1nd+4?%xN(xLgU2O62Qm$W@3v*o9 zV|-EXQ!5q=u)_?uwdg}sNL6k>V+BEuo&PP&#BliN$`YG8|H%Z=<2C>Apf6Fh5>Y{! zrwtbD(X<8XcGFd^yr2%XRxh_sdkOJWbt&SJ_ObI}7L`t6*O=pqG)lxmHe4EEy-m8S z{8TWzIQ7uw1A{gEI=$rycYI_wJ$h+hz$sW3WPX%2+#o4nPQo1iWDf%ZXLT?^1exVu zN7URUr0}*=@6&+6v7kdI%}Jgwq=2R{bqH}f*H)6&_?hf}2FVcnYYEKBmO}F%p`C%n zF3gxxS;=FQp6cYk9fj5V_CQMaKK)ISe2UYl``-lvzp_03hco7lKC!YTHVMA{jZm*N z^C9zSYo|j9P((#1KOVmPSl+LQQ-?0t+B;Ll^U90DFMk&or&0&Xr;T(y6r-#O=xP-0 z_p$=(r(bl%O?HtvGldH?rKLF}?7=roJeopAE-1pYk0ihKSpj@>K`#j@R305qQC!HG z0p*?6C5*$^XH1|XD^#9a4MT?P?WFD5htb!Z8f?9q`be}F?i)&+LBjrbkLmYEMP`u+ zVI1YVlPmKk*+&{X`BFWa%ZjunpVzO{MKXD$^5$f=fAb00Jy+}bJhDo)*{@L^2g(;M z3$iKdpSNvEy8SB&S{qQvzD^B+83PZ}V>xI;eC_@(%(L0z_(})g;4VJZ(4VqWn;(}5 zZ~|*QHVSDq0rD4sqCM;^I%xqE(;3uuK_)@Nm05BnDgNzuf`cJ|9{1|17Z(pAK3Iv6 zPS{g%Fe-YHxLWIjN%1R>eA}lVQn2gI(xkuh*ts5En-?uwa`%^gI!ETvRR52+zB`Jx z@uqJb$yv@EacM5F+DLU7NJ`?+k>)fkhSvl0<_eluzvz8v>s!^SdY2c$kD5~-TlL6) zXE_$s6685@r#~pG&*&W;oD%V%erazN4II$Eta@xRxi!(Qc`Zx_ZJ7=BJK=_2>Bp;y zj1SiF8jUxrt}csrsd54IWmQrfgKBsQ9mOtxU~+gt^d-5{=Xi357H4x^{5+b+>~GVE zd;ZnSJo0?9bD6la-|TR4Wyw4a)a)N_d_V8Enf+e5S1M2cCx5l>#>-Q@+cJ0jR8XP( R=OXy$7rle~9_>9I^j~rkm2Ln4