├── .gitignore ├── .gitmodules ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake └── OTExtensionConfig.cmake.in ├── mains ├── CMakeLists.txt ├── otmain.cpp ├── otmain.h ├── test.cpp └── test.h └── ot ├── OTconstants.h ├── alsz-ot-ext-rec.cpp ├── alsz-ot-ext-rec.h ├── alsz-ot-ext-snd.cpp ├── alsz-ot-ext-snd.h ├── asharov-lindell.cpp ├── asharov-lindell.h ├── baseOT.h ├── iknp-ot-ext-rec.cpp ├── iknp-ot-ext-rec.h ├── iknp-ot-ext-snd.cpp ├── iknp-ot-ext-snd.h ├── kk-ot-ext-rec.cpp ├── kk-ot-ext-rec.h ├── kk-ot-ext-snd.cpp ├── kk-ot-ext-snd.h ├── kk-ot-ext.h ├── maskingfunction.h ├── naor-pinkas.cpp ├── naor-pinkas.h ├── naor-pinkas_noro.cpp ├── naor-pinkas_noro.h ├── nnob-ot-ext-rec.cpp ├── nnob-ot-ext-rec.h ├── nnob-ot-ext-snd.cpp ├── nnob-ot-ext-snd.h ├── ot-ext-rec.cpp ├── ot-ext-rec.h ├── ot-ext-snd.cpp ├── ot-ext-snd.h ├── ot-ext.cpp ├── ot-ext.h ├── pvwddh.cpp ├── pvwddh.h ├── simpleot.cpp ├── simpleot.h └── xormasking.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.h~ 2 | *.cpp~ 3 | *.c~ 4 | *.o 5 | *.exe 6 | .metadata 7 | .cproject 8 | .project 9 | .settings 10 | 11 | # build directory 12 | build*/ 13 | 14 | # CMake 15 | CMakeCache.txt 16 | CMakeFiles 17 | CMakeScripts 18 | Testing 19 | Makefile 20 | cmake_install.cmake 21 | install_manifest.txt 22 | compile_commands.json 23 | CTestTestfile.cmake 24 | 25 | # VS Code Directory 26 | .vscode/ 27 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "extern/ENCRYPTO_utils"] 2 | path = extern/ENCRYPTO_utils 3 | url = https://github.com/encryptogroup/ENCRYPTO_utils.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: g++ 3 | dist: xenial 4 | 5 | addons: 6 | apt: 7 | sources: 8 | - sourceline: 'ppa:ubuntu-toolchain-r/test' 9 | - sourceline: 'ppa:mhier/libboost-latest' 10 | packages: 11 | - g++-8 12 | - libboost1.67-dev 13 | - libgmp-dev 14 | - libssl-dev 15 | 16 | before_install: 17 | # Install a recent CMake 18 | - mkdir $HOME/prefix 19 | - export PATH="$HOME/prefix/bin:$PATH" 20 | - wget https://cmake.org/files/v3.14/cmake-3.14.0-Linux-x86_64.sh -O cmake_install.sh 21 | - chmod +x cmake_install.sh 22 | - ./cmake_install.sh --prefix=$HOME/prefix --exclude-subdir --skip-license 23 | 24 | script: 25 | - mkdir build_debug 26 | - cd build_debug 27 | - CC=/usr/bin/gcc-8 CXX=/usr/bin/g++-8 cmake .. -DCMAKE_BUILD_TYPE=Debug -DOTEXTENSION_BUILD_EXE=On 28 | - make 29 | - ./mains/test 0 & 30 | - ./mains/test 1 31 | 32 | notifications: 33 | - email: false 34 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | project(OTExtension LANGUAGES CXX) 3 | 4 | if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) 5 | message(FATAL_ERROR "ENCRYPTO_utils require at least g++-8") 6 | endif() 7 | 8 | option(OTEXTENSION_BUILD_EXE "Build executables" OFF) 9 | 10 | find_package(ENCRYPTO_utils QUIET) 11 | if(ENCRYPTO_utils_FOUND) 12 | message(STATUS "Found ENCRYPTO_utils") 13 | elseif(NOT ENCRYPTO_utils_FOUND AND NOT TARGET ENCRYPTO_utils::encrypto_utils) 14 | message("ENCRYPTO_utils was not found: add ENCRYPTO_utils subdirectory") 15 | if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/ENCRYPTO_utils/CMakeLists.txt") 16 | find_package(Git REQUIRED) 17 | message("initialize Git submodule: extern/ENCRYPTO_utils") 18 | execute_process(COMMAND git submodule update --init extern/ENCRYPTO_utils 19 | WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}") 20 | endif() 21 | add_subdirectory(extern/ENCRYPTO_utils) 22 | endif() 23 | find_package(Threads REQUIRED) 24 | 25 | 26 | add_library(otextension 27 | ot/alsz-ot-ext-rec.cpp 28 | ot/alsz-ot-ext-snd.cpp 29 | # ot/asharov-lindell.cpp 30 | ot/iknp-ot-ext-rec.cpp 31 | ot/iknp-ot-ext-snd.cpp 32 | ot/kk-ot-ext-rec.cpp 33 | ot/kk-ot-ext-snd.cpp 34 | ot/naor-pinkas.cpp 35 | # ot/naor-pinkas_noro.cpp 36 | ot/nnob-ot-ext-rec.cpp 37 | ot/nnob-ot-ext-snd.cpp 38 | ot/ot-ext.cpp 39 | ot/ot-ext-rec.cpp 40 | ot/ot-ext-snd.cpp 41 | ot/pvwddh.cpp 42 | ot/simpleot.cpp 43 | ) 44 | add_library(OTExtension::otextension ALIAS otextension) 45 | 46 | target_compile_features(otextension PUBLIC cxx_std_17) 47 | target_compile_options(otextension PRIVATE "-Wall" "-Wextra") 48 | #target_compile_options(otextension PUBLIC "-fno-omit-frame-pointer" "-fsanitize=address") 49 | #target_link_options(otextension PUBLIC "-fno-omit-frame-pointer" "-fsanitize=address") 50 | 51 | target_include_directories(otextension 52 | PUBLIC 53 | $ 54 | $ 55 | ) 56 | 57 | 58 | target_link_libraries(otextension 59 | PUBLIC ENCRYPTO_utils::encrypto_utils 60 | PUBLIC Threads::Threads 61 | ) 62 | 63 | 64 | install(TARGETS otextension 65 | EXPORT "${PROJECT_NAME}Targets" 66 | ARCHIVE DESTINATION lib 67 | LIBRARY DESTINATION lib 68 | INCLUDES DESTINATION lib 69 | ) 70 | install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ot" 71 | DESTINATION include 72 | FILES_MATCHING PATTERN "*.h" 73 | ) 74 | export(TARGETS otextension NAMESPACE "${PROJECT_NAME}::" FILE "${PROJECT_NAME}Targets.cmake") 75 | install(EXPORT "${PROJECT_NAME}Targets" 76 | NAMESPACE "${PROJECT_NAME}::" 77 | DESTINATION "lib/cmake/${PROJECT_NAME}" 78 | ) 79 | 80 | 81 | include(CMakePackageConfigHelpers) 82 | 83 | configure_package_config_file("${CMAKE_CURRENT_LIST_DIR}/cmake/${PROJECT_NAME}Config.cmake.in" 84 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake 85 | INSTALL_DESTINATION "lib/cmake/${PROJECT_NAME}" 86 | ) 87 | 88 | install(FILES 89 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 90 | DESTINATION "lib/cmake/${PROJECT_NAME}" 91 | ) 92 | 93 | if(OTEXTENSION_BUILD_EXE) 94 | add_subdirectory(mains) 95 | endif(OTEXTENSION_BUILD_EXE) 96 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OTExtension [![Build Status](https://travis-ci.org/encryptogroup/OTExtension.svg?branch=master)](https://travis-ci.org/encryptogroup/OTExtension) 2 | 3 | ## DESCRIPTION 4 | Implementation of the passive secure OT extension protocol of [1] and the active secure OT extension protocols of [2] and [3]. Implements the general OT (G_OT), correlated OT (C_OT), global correlated OT (GC_OT), sender random OT (SR_OT), and receiver random OT (RR_OT) (Definitions of the functionalities will follow). Implements the base-OTs by Naor-Pinkas [4], Peikert-Vaikuntanathan-Waters [5], and Chou-Orlandi [6]. The code is based on the OT extension implementation of [7] and uses the MIRACL libary [8] for elliptic curve arithmetic. 5 | 6 | Update: Implemented 1-out-of-2 OT from the 1-out-of-N OT extension of [9]. 7 | 8 | ## REQUIREMENTS 9 | 10 | * A **Linux distribution** of your choice (the OT extension code was developed under [Ubuntu](http://www.ubuntu.com/)). 11 | * **Required packages:** 12 | * [`g++`](https://packages.debian.org/testing/g++) 13 | * [`make`](https://packages.debian.org/testing/make) 14 | * [`libgmp-dev`](https://packages.debian.org/testing/libgmp-dev) 15 | * [`libssl-dev`](https://packages.debian.org/testing/libssl-dev) 16 | * [`libboost-all-dev`](https://packages.debian.org/testing/libboost-all-dev) (version >= 1.66) 17 | 18 | Install these packages with your favorite package manager, e.g, `sudo apt-get install `. 19 | 20 | 21 | ## COMPILING 22 | 23 | 1. Clone a copy of the OTExtension git repository: 24 | ``` 25 | git clone https://github.com/encryptogroup/OTExtension.git 26 | ``` 27 | 28 | 2. Enter the Framework directory: `cd OTExtension/` 29 | 30 | 3. Create and enter a build directory: `mkdir build && cd build` 31 | 32 | 4. Use CMake to create build files. Use 33 | 34 | ``` 35 | cmake .. 36 | ``` 37 | 38 | The following options are available: 39 | 40 | * `-DCMAKE_INSTALL_PREFIX=/path/to/installation` 41 | * `-DOTEXTENSION_BUILD_EXE=On` to build executables (they are written to `mains/` in the build directory) 42 | 43 | In case [ENCRYPTO_utils](https://github.com/encryptogroup/ENCRYPTO_utils) 44 | cannot be found on your system, it will automatically be compiled. If it is 45 | installed in a non-standard location, the path can be provided via 46 | `-DCMAKE_PREFIX_PATH=/some/path`. 47 | 48 | 5. Call `make` in the build directory to compile. 49 | 50 | 51 | ## USE 52 | To start OT extension, open two terminals on the same PC and call `otmain -r 0` in one terminal to start OT extension as sender and call `otmain -r 1` in the second terminal to start OT extension as receiver. This will invoke the passive secure IKNP 1-out-of-2 OT extension protocol for 1 million OTs on 8-bit strings. The result of the OT will be checked for correctness and the times (in ms) for the base-OTs, for the OT extensions, the number of bytes sent and the number of bytes received will be printed on the terminals. 53 | A list of all available options can be obtained via `otmain -h`. 54 | 55 | ## NOTES 56 | An example implementation of OT extension can be found in `mains/otmain.cpp`. 57 | 58 | OT related source code is found in `ot/`. 59 | 60 | Some compilation flags can be set in `ot/OTconstants.h`. 61 | 62 | 63 | ## REFERENCES 64 | * [1] G. Asharov, Y. Lindell, T. Schneider, M. Zohner: More Efficient Oblivious Transfer and Extensions for Faster Secure Computation (CCS'13). 65 | * [2] G. Asharov, Y. Lindell, T. Schneider, M. Zohner: More Efficient Oblivious Transfer Extensions with Security for Malicious Adversaries. EUROCRYPT (1) 2015: 673-701. 66 | * [3] J. B. Nielsen, P. S. Nordholt, C. Orlandi, S. S. Burra: A New Approach to Practical Active-Secure Two-Party Computation. CRYPTO 2012: 681-700. 67 | * [4] M. Naor, B. Pinkas: Efficient oblivious transfer protocols. SODA 2001: 448-457. 68 | * [5] C. Peikert, V. Vaikuntanathan, B. Waters: A Framework for Efficient and Composable Oblivious Transfer. CRYPTO 2008: 554-571. 69 | * [6] T. Chou, C. Orlandi: The Simplest Protocol for Oblivious Transfer. Online at: http://eprint.iacr.org/2015/267. 70 | * [7] S.G. Choi, K.W. Hwang, J.Katz, T. Malkin, D. Rubenstein: Secure multi-party computation of Boolean circuits with applications to privacy in on-line market-places. In CT-RSA’12. LNCS, vol. 7178, pp. 416–432. 71 | * [8] CertiVox, Multiprecision Integer and Rational Arithmetic Cryptographic Library (MIRACL) https://github.com/CertiVox/MIRACL 72 | * [9] V. Kolesnikov, R. Kumaresan: Improved OT Extension for Transferring Short Secrets. In CRYPTO'13 (2). 73 | * [10] D. Demmler, T. Schneider, M. Zohner: ABY - A Framework for Efficient Mixed-Protocol Secure Two-Party Computation. NDSS 2015. https://github.com/encryptogroup/ABY 74 | -------------------------------------------------------------------------------- /cmake/OTExtensionConfig.cmake.in: -------------------------------------------------------------------------------- 1 | get_filename_component(OTExtension_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 2 | 3 | list(APPEND CMAKE_MODULE_PATH "${OTExtension_CMAKE_DIR}") 4 | 5 | include(CMakeFindDependencyMacro) 6 | 7 | find_dependency(ENCRYPTO_utils) 8 | 9 | if(NOT TARGET OTExtension::otextension) 10 | include("${OTExtension_CMAKE_DIR}/OTExtensionTargets.cmake") 11 | endif() 12 | -------------------------------------------------------------------------------- /mains/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(test test.cpp) 2 | target_link_libraries(test OTExtension::otextension) 3 | 4 | add_executable(otmain otmain.cpp) 5 | target_link_libraries(otmain OTExtension::otextension) 6 | -------------------------------------------------------------------------------- /mains/otmain.cpp: -------------------------------------------------------------------------------- 1 | #include "otmain.h" 2 | #include 3 | #include 4 | 5 | //pthread_mutex_t CLock::share_mtx = PTHREAD_MUTEX_INITIALIZER; 6 | 7 | BOOL Init(crypto* crypt) 8 | { 9 | return TRUE; 10 | } 11 | 12 | BOOL Cleanup() 13 | { 14 | delete sndthread; 15 | 16 | //rcvthread->Wait(); 17 | 18 | delete rcvthread; 19 | 20 | //std::cout << "Cleaning" << std::endl; 21 | //std::cout << "done" << std::endl; 22 | return true; 23 | } 24 | 25 | 26 | void InitOTSender(const std::string& address, const int port, crypto* crypt, CLock *glock) 27 | { 28 | #ifdef OTTiming 29 | timespec np_begin, np_end; 30 | #endif 31 | m_nPort = (uint16_t) port; 32 | m_nAddr = &address; 33 | 34 | //Initialize values 35 | Init(crypt); 36 | 37 | //Server listen 38 | m_Socket = Listen(address, port); 39 | if (!m_Socket) { 40 | std::cerr << "Listen failed on " << address << ":" << port << "\n"; 41 | std::exit(1); 42 | } 43 | 44 | sndthread = new SndThread(m_Socket.get(), glock); 45 | rcvthread = new RcvThread(m_Socket.get(), glock); 46 | 47 | rcvthread->Start(); 48 | sndthread->Start(); 49 | 50 | switch(m_eProt) { 51 | case ALSZ: sender = new ALSZOTExtSnd(crypt, rcvthread, sndthread, m_nBaseOTs, m_nChecks); break; 52 | case IKNP: sender = new IKNPOTExtSnd(crypt, rcvthread, sndthread); break; 53 | case NNOB: sender = new NNOBOTExtSnd(crypt, rcvthread, sndthread); break; 54 | case KK: sender = new KKOTExtSnd(crypt, rcvthread, sndthread); break; 55 | default: sender = new ALSZOTExtSnd(crypt, rcvthread, sndthread, m_nBaseOTs, m_nChecks); break; 56 | } 57 | 58 | if(m_bUseMinEntCorAssumption) 59 | sender->EnableMinEntCorrRobustness(); 60 | sender->ComputeBaseOTs(m_eFType); 61 | } 62 | 63 | void InitOTReceiver(const std::string& address, const int port, crypto* crypt, CLock *glock) 64 | { 65 | m_nPort = (uint16_t) port; 66 | m_nAddr = &address; 67 | 68 | //Initialize values 69 | Init(crypt); 70 | 71 | //Client connect 72 | m_Socket = Connect(address, port); 73 | if (!m_Socket) { 74 | std::cerr << "Connect failed on " << address << ":" << port << "\n"; 75 | std::exit(1); 76 | } 77 | 78 | sndthread = new SndThread(m_Socket.get(), glock); 79 | rcvthread = new RcvThread(m_Socket.get(), glock); 80 | 81 | rcvthread->Start(); 82 | sndthread->Start(); 83 | 84 | switch(m_eProt) { 85 | case ALSZ: receiver = new ALSZOTExtRec(crypt, rcvthread, sndthread, m_nBaseOTs, m_nChecks); break; 86 | case IKNP: receiver = new IKNPOTExtRec(crypt, rcvthread, sndthread); break; 87 | case NNOB: receiver = new NNOBOTExtRec(crypt, rcvthread, sndthread); break; 88 | case KK: receiver = new KKOTExtRec(crypt, rcvthread, sndthread); break; 89 | default: receiver = new ALSZOTExtRec(crypt, rcvthread, sndthread, m_nBaseOTs, m_nChecks); break; 90 | } 91 | 92 | 93 | if(m_bUseMinEntCorAssumption) 94 | receiver->EnableMinEntCorrRobustness(); 95 | receiver->ComputeBaseOTs(m_eFType); 96 | } 97 | 98 | 99 | BOOL ObliviouslySend(CBitVector** X, int numOTs, int bitlength, uint32_t nsndvals, 100 | snd_ot_flavor stype, rec_ot_flavor rtype, crypto* crypt) 101 | { 102 | bool success = FALSE; 103 | 104 | m_Socket->ResetSndCnt(); 105 | m_Socket->ResetRcvCnt(); 106 | timespec ot_begin, ot_end; 107 | 108 | clock_gettime(CLOCK_MONOTONIC, &ot_begin); 109 | // Execute OT sender routine 110 | success = sender->send(numOTs, bitlength, nsndvals, X, stype, rtype, m_nNumOTThreads, m_fMaskFct); 111 | clock_gettime(CLOCK_MONOTONIC, &ot_end); 112 | 113 | #ifndef BATCH 114 | printf("Time spent:\t%f\n", getMillies(ot_begin, ot_end) + rndgentime); 115 | std::cout << "Sent:\t\t" << m_Socket->getSndCnt() << " bytes" << std::endl; 116 | std::cout << "Received:\t" << m_Socket->getRcvCnt() <<" bytes" << std::endl; 117 | #else 118 | std::cout << getMillies(ot_begin, ot_end) + rndgentime << "\t" << m_Socket->getSndCnt() << "\t" << m_Socket->getRcvCnt() << std::endl; 119 | #endif 120 | 121 | 122 | return success; 123 | } 124 | 125 | BOOL ObliviouslyReceive(CBitVector* choices, CBitVector* ret, int numOTs, int bitlength, uint32_t nsndvals, 126 | snd_ot_flavor stype, rec_ot_flavor rtype, crypto* crypt) 127 | { 128 | bool success = FALSE; 129 | 130 | m_Socket->ResetSndCnt(); 131 | m_Socket->ResetRcvCnt(); 132 | 133 | 134 | timespec ot_begin, ot_end; 135 | clock_gettime(CLOCK_MONOTONIC, &ot_begin); 136 | // Execute OT receiver routine 137 | success = receiver->receive(numOTs, bitlength, nsndvals, choices, ret, stype, rtype, m_nNumOTThreads, m_fMaskFct); 138 | clock_gettime(CLOCK_MONOTONIC, &ot_end); 139 | 140 | #ifndef BATCH 141 | printf("Time spent:\t%f\n", getMillies(ot_begin, ot_end) + rndgentime); 142 | 143 | std::cout << "Sent:\t\t" << m_Socket->getSndCnt() << " bytes" << std::endl; 144 | std::cout << "Received:\t" << m_Socket->getRcvCnt() <<" bytes" << std::endl; 145 | #else 146 | std::cout << getMillies(ot_begin, ot_end) + rndgentime << "\t" << m_Socket->getSndCnt() << "\t" << m_Socket->getRcvCnt() << std::endl; 147 | #endif 148 | 149 | 150 | return success; 151 | } 152 | 153 | 154 | int main(int argc, char** argv) 155 | { 156 | std::string addr = "127.0.0.1"; 157 | uint16_t port = 7766; 158 | 159 | //Determines whether the program is executed in the sender or receiver role 160 | m_nPID = atoi(argv[1]); 161 | //the number of OTs that are performed. 162 | uint64_t numOTs = 100000; 163 | //bitlength of the values that are transferred - NOTE that when bitlength is not 1 or a multiple of 8, the endianness has to be observed 164 | uint32_t bitlength = 8; 165 | 166 | uint32_t runs = 1; 167 | 168 | uint32_t nsndvals = 2; 169 | 170 | //Use elliptic curve cryptography in the base-OTs 171 | m_eFType = ECC_FIELD; 172 | //The symmetric security parameter (80, 112, 128) 173 | uint32_t m_nSecParam = 128; 174 | 175 | //Number of threads that will be used in OT extension 176 | m_nNumOTThreads = 1; 177 | 178 | //Specifies which OT flavor should be used 179 | snd_ot_flavor stype = Snd_OT; 180 | rec_ot_flavor rtype = Rec_OT; 181 | 182 | 183 | m_nBaseOTs = 190; 184 | m_nChecks = 380; 185 | 186 | m_bUseMinEntCorAssumption = false; 187 | 188 | m_eProt = IKNP; 189 | 190 | read_test_options(&argc, &argv, &m_nPID, &numOTs, &bitlength, &m_nSecParam, &addr, &port, &m_eProt, &stype, &rtype, 191 | &m_nNumOTThreads, &m_nBaseOTs, &m_nChecks, &nsndvals, &m_bUseMinEntCorAssumption, &runs); 192 | 193 | /*int32_t read_test_options(int32_t* argcp, char*** argvp, uint32_t* role, uint64_t* numots, uint32_t* bitlen, 194 | uint32_t* secparam, std::string* address, uint16_t* port, ot_ext_prot* protocol, snd_ot_flavor* sndflav, 195 | rec_ot_flavor* rcvflav, uint32_t* nthreads, uint32_t* nbaseots, uint32_t* nchecks, bool* usemecr, uint32_t* runs) {*/ 196 | 197 | crypto *crypt = new crypto(m_nSecParam, (uint8_t*) m_cConstSeed[m_nPID]); 198 | CLock *glock = new CLock(); // pass this to sender and receiver constructors 199 | 200 | if(m_nPID == SERVER_ID) //Play as OT sender 201 | { 202 | InitOTSender(addr, port, crypt, glock); 203 | 204 | CBitVector delta; 205 | CBitVector** X = (CBitVector**) malloc(sizeof(CBitVector*) * nsndvals); 206 | 207 | 208 | //The masking function with which the values that are sent in the last communication step are processed 209 | m_fMaskFct = new XORMasking(bitlength, delta); 210 | 211 | //creates delta as an array with "numOTs" entries of "bitlength" bit-values and fills delta with random values 212 | delta.Create(numOTs, bitlength, crypt); 213 | 214 | //Create the X values as two arrays with "numOTs" entries of "bitlength" bit-values and resets them to 0 215 | for(uint32_t i = 0; i < nsndvals; i++) { 216 | X[i] = new CBitVector(); 217 | X[i]->Create(numOTs, bitlength); 218 | } 219 | 220 | #ifndef BATCH 221 | std::cout << getProt(m_eProt) << " Sender performing " << numOTs << " " << getSndFlavor(stype) << " / " << 222 | getRecFlavor(rtype) << " extensions on " << bitlength << " bit elements with " << m_nNumOTThreads << " threads, " << 223 | getFieldType(m_eFType) << " and" << (m_bUseMinEntCorAssumption ? "": " no" ) << " min-ent-corr-robustness " << 224 | runs << " times" << std::endl; 225 | #endif 226 | for(uint32_t i = 0; i < runs; i++) { 227 | ObliviouslySend(X, numOTs, bitlength, nsndvals, stype, rtype, crypt); 228 | } 229 | /*for(uint32_t i = 0; i < nsndvals; i++) { 230 | std::cout << "X" << i << ": "; 231 | X[i]->PrintHex(0, numOTs); 232 | }*/ 233 | } 234 | else //Play as OT receiver 235 | { 236 | InitOTReceiver(addr, port, crypt, glock); 237 | 238 | CBitVector choices, response; 239 | 240 | //The masking function with which the values that are sent in the last communication step are processed 241 | m_fMaskFct = new XORMasking(bitlength); 242 | 243 | //Create the bitvector choices as a bitvector with numOTs entries 244 | choices.Create(numOTs * ceil_log2(nsndvals), crypt); 245 | 246 | //Pre-generate the respose vector for the results 247 | response.Create(numOTs, bitlength); 248 | response.Reset(); 249 | 250 | /* 251 | * The inputs of the receiver in G_OT, C_OT and R_OT are the same. The only difference is the version 252 | * variable that has to match the version of the sender. 253 | */ 254 | #ifndef BATCH 255 | std::cout << getProt(m_eProt) << " Receiver performing " << numOTs << " " << getSndFlavor(stype) << " / " << 256 | getRecFlavor(rtype) << " extensions on " << bitlength << " bit elements with " << m_nNumOTThreads << " threads, " << 257 | getFieldType(m_eFType) << " and" << (m_bUseMinEntCorAssumption ? "": " no" ) << " min-ent-corr-robustness " << 258 | runs << " times" << std::endl; 259 | #endif 260 | for(uint32_t i = 0; i < runs; i++) { 261 | ObliviouslyReceive(&choices, &response, numOTs, bitlength, nsndvals, stype, rtype, crypt); 262 | } 263 | /*std::cout << "C: "; 264 | choices.PrintHex(0, numOTs); 265 | std::cout << "R: "; 266 | response.PrintHex(0, numOTs);*/ 267 | 268 | } 269 | 270 | Cleanup(); 271 | delete crypt; 272 | delete glock; 273 | 274 | return EXIT_SUCCESS; 275 | } 276 | 277 | 278 | int32_t read_test_options(int32_t* argcp, char*** argvp, uint32_t* role, uint64_t* numots, uint32_t* bitlen, 279 | uint32_t* secparam, std::string* address, uint16_t* port, ot_ext_prot* protocol, snd_ot_flavor* sndflav, 280 | rec_ot_flavor* rcvflav, uint32_t* nthreads, uint32_t* nbaseots, uint32_t* nchecks, uint32_t* N, bool* usemecr, 281 | uint32_t* runs) { 282 | 283 | uint32_t int_port = 0, int_prot = 0, int_snd_flav = 0, int_rec_flav = 0; 284 | bool printhelp = false; 285 | 286 | parsing_ctx options[] = { 287 | { (void*) role, T_NUM, "r", "Role: 0/1", true, false }, 288 | { (void*) numots, T_NUM, "n", "Number of OTs, default 10^6", false, false }, 289 | { (void*) bitlen, T_NUM, "b", "Bit-length of elements in OTs, default 8", false, false }, 290 | { (void*) secparam, T_NUM, "s", "Symmetric Security Bits, default: 128", false, false }, 291 | { (void*) address, T_STR, "a", "IP-address, default: localhost", false, false }, 292 | { (void*) &int_port, T_NUM, "p", "Port, default: 7766", false, false }, 293 | { (void*) &int_prot, T_NUM, "o", "Protocol, 0: IKNP, 1: ALSZ, 2: NNOB, 3: KK, default: IKNP", false, false }, 294 | { (void*) &int_snd_flav, T_NUM, "f", "Sender OT Functionality, 0: OT, 1: C_OT, 2: Snd_R_OT, 3: GC_OT, default: OT", false, false }, 295 | { (void*) &int_rec_flav, T_NUM, "v", "Receiver OT Functionality, 0: OT, 1: Rec_R_OT, default: OT", false, false }, 296 | { (void*) nthreads, T_NUM, "t", "Number of threads, default 1", false, false }, 297 | { (void*) nbaseots, T_NUM, "e", "Number of baseots for ALSZ, default 190", false, false }, 298 | { (void*) nchecks, T_NUM, "c", "Number of checks for ALSZ, default 380", false, false }, 299 | { (void*) usemecr, T_FLAG, "m", "Use Min-Entropy Correlation-Robustness Assumption, default: false", false, false }, 300 | { (void*) runs, T_NUM, "u", "Number of repetitions, default: 1", false, false }, 301 | { (void*) N, T_NUM, "N", "1-oo-N OT extension. Only works in combination with KK13 and needs to be a power of two, default: 2", false, false }, 302 | { (void*) &printhelp, T_FLAG, "h", "Print help", false, false } 303 | }; 304 | 305 | if (!parse_options(argcp, argvp, options, sizeof(options) / sizeof(parsing_ctx))) { 306 | print_usage(*argvp[0], options, sizeof(options) / sizeof(parsing_ctx)); 307 | std::cout << "Exiting" << std::endl; 308 | std::exit(EXIT_FAILURE); 309 | } 310 | 311 | if(printhelp) { 312 | print_usage(*argvp[0], options, sizeof(options) / sizeof(parsing_ctx)); 313 | std::cout << "Exiting" << std::endl; 314 | std::exit(EXIT_FAILURE); 315 | } 316 | 317 | assert(*role < 2); 318 | 319 | if (int_port != 0) { 320 | assert(int_port < 1 << (sizeof(uint16_t) * 8)); 321 | *port = (uint16_t) int_port; 322 | } 323 | 324 | if (int_prot != 0) { 325 | assert(int_prot > 0 && int_prot < PROT_LAST); 326 | *protocol = (ot_ext_prot) int_prot; 327 | } 328 | 329 | if (int_snd_flav != 0) { 330 | assert(int_snd_flav > 0 && int_snd_flav < Snd_OT_LAST); 331 | *sndflav = (snd_ot_flavor) int_snd_flav; 332 | } 333 | 334 | if (int_rec_flav != 0) { 335 | assert(int_rec_flav > 0 && int_rec_flav < Rec_OT_LAST); 336 | *rcvflav = (rec_ot_flavor) int_rec_flav; 337 | } 338 | 339 | if(*N != 2 && (*protocol) != KK) { 340 | std::cout << "The N option can only be used in combination with the KK13 OT. Resetting to N=2" << std::endl; 341 | *N = 2; 342 | } 343 | 344 | //delete options; 345 | 346 | return 1; 347 | } 348 | -------------------------------------------------------------------------------- /mains/otmain.h: -------------------------------------------------------------------------------- 1 | #ifndef _OTMAIN_H_ 2 | #define _OTMAIN_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../ot/iknp-ot-ext-snd.h" 8 | #include "../ot/iknp-ot-ext-rec.h" 9 | #include "../ot/alsz-ot-ext-snd.h" 10 | #include "../ot/alsz-ot-ext-rec.h" 11 | #include "../ot/nnob-ot-ext-snd.h" 12 | #include "../ot/nnob-ot-ext-rec.h" 13 | #include "../ot/kk-ot-ext-snd.h" 14 | #include "../ot/kk-ot-ext-rec.h" 15 | #include 16 | #include "../ot/xormasking.h" 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | //TODO only for debugging purpose!! 33 | static const char* m_cConstSeed[2] = {"437398417012387813714564100", "15657566154164561"}; 34 | 35 | uint16_t m_nPort = 7766; 36 | const std::string* m_nAddr; 37 | 38 | BOOL Init(crypto* crypt); 39 | BOOL Cleanup(); 40 | 41 | void InitOTSender(const std::string& address, const int port, crypto* crypt); 42 | void InitOTReceiver(const std::string &address, const int port, crypto* crypt); 43 | 44 | BOOL ObliviouslyReceive(CBitVector* choices, CBitVector* ret, int numOTs, int bitlength, uint32_t nsndvals, snd_ot_flavor stype, rec_ot_flavor rtype, crypto* crypt); 45 | BOOL ObliviouslySend(CBitVector** X, int numOTs, int bitlength, uint32_t nsndvals, snd_ot_flavor stype, rec_ot_flavor rtype, crypto* crypt); 46 | 47 | // Network Communication 48 | std::unique_ptr m_Socket; 49 | uint32_t m_nPID; // thread id 50 | field_type m_eFType; 51 | uint32_t m_nBitLength; 52 | MaskingFunction* m_fMaskFct; 53 | 54 | // Naor-Pinkas OT 55 | //BaseOT* bot; 56 | OTExtSnd *sender; 57 | OTExtRec *receiver; 58 | 59 | SndThread* sndthread; 60 | RcvThread* rcvthread; 61 | 62 | uint32_t m_nNumOTThreads; 63 | uint32_t m_nBaseOTs; 64 | uint32_t m_nChecks; 65 | 66 | bool m_bUseMinEntCorAssumption; 67 | ot_ext_prot m_eProt; 68 | 69 | double rndgentime; 70 | 71 | int32_t read_test_options(int32_t* argcp, char*** argvp, uint32_t* role, uint64_t* numots, uint32_t* bitlen, 72 | uint32_t* secparam, std::string* address, uint16_t* port, ot_ext_prot* protocol, snd_ot_flavor* sndflav, 73 | rec_ot_flavor* rcvflav, uint32_t* nthreads, uint32_t* nbaseots, uint32_t* nchecks, uint32_t* N, bool* usemecr, uint32_t* runs); 74 | 75 | #endif 76 | 77 | -------------------------------------------------------------------------------- /mains/test.cpp: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include 3 | #include 4 | #include 5 | 6 | //ot_ext_prot test_prots[] = {IKNP, KK, ALSZ, NNOB}; 7 | ot_ext_prot test_prots[] = {IKNP}; 8 | snd_ot_flavor test_sflavor[] = {Snd_OT, Snd_C_OT, Snd_GC_OT, Snd_R_OT}; 9 | rec_ot_flavor test_rflavor[] = {Rec_OT, Rec_R_OT}; 10 | uint64_t test_numots[] = {128, 3215, 100000}; 11 | uint64_t test_bitlen[] = {1, 3, 8, 191}; 12 | uint32_t test_nthreads[] = {1, 4}; 13 | field_type test_ftype[] = {P_FIELD, ECC_FIELD}; 14 | bool test_usemecr[] = {false}; 15 | 16 | BOOL Init() 17 | { 18 | uint32_t nparams = 8; 19 | uint32_t* ntestparams = (uint32_t*) malloc(nparams * sizeof(uint32_t)); 20 | //uint32_t* ctr = (uint32_t) calloc(nparams, sizeof(uint32_t)); 21 | 22 | ntestparams[0] = sizeof(test_prots)/sizeof(ot_ext_prot); 23 | ntestparams[1] = sizeof(test_sflavor)/sizeof(snd_ot_flavor); 24 | ntestparams[2] = sizeof(test_rflavor)/sizeof(rec_ot_flavor); 25 | ntestparams[3] = sizeof(test_numots)/sizeof(uint64_t); 26 | ntestparams[4] = sizeof(test_bitlen)/sizeof(uint64_t); 27 | ntestparams[5] = sizeof(test_nthreads)/sizeof(uint32_t); 28 | ntestparams[6] = sizeof(test_usemecr)/sizeof(bool); 29 | ntestparams[7] = sizeof(test_ftype)/sizeof(field_type); 30 | 31 | 32 | m_nTests = 1; 33 | gen_tests = 0; 34 | for(uint32_t i = 0; i < nparams; i++) { 35 | m_nTests *= ntestparams[i]; 36 | } 37 | //std::cout << "ntests = " << m_nTests << std::endl; 38 | //Init test options 39 | tests = (test_options*) malloc(sizeof(test_options) * (m_nTests+1)); 40 | test_options* test_ptr = tests; 41 | recursive_assign_test_params(ntestparams, 0, &test_ptr, nparams); 42 | 43 | free(ntestparams); 44 | 45 | return TRUE; 46 | } 47 | 48 | void recursive_assign_test_params(uint32_t* max, uint32_t depth, test_options** tops, uint32_t max_depth) { 49 | 50 | for(uint32_t i = 0; i < max[depth]; i++) { 51 | assign_param(i, depth, *tops); 52 | if(depth == max_depth-1) { 53 | memcpy((*tops)+1, *tops, sizeof(test_options)); 54 | (*tops)++; 55 | //std::cout << "another " << gen_tests++ << ", total: " << m_nTests << std::endl; 56 | } else { 57 | recursive_assign_test_params(max, depth+1, tops, max_depth); 58 | } 59 | } 60 | } 61 | 62 | void assign_param(uint32_t ctr, uint32_t depth, test_options* tops) { 63 | //tops->ftype = test_ftype[ctr % 2]; 64 | //tops->usemecr = test_ftype[ctr % (sizeof(test_usemecr)/sizeof(bool))]; 65 | switch(depth) { 66 | case 0: tops->prot = test_prots[ctr]; break; 67 | case 1: tops->sflavor = test_sflavor[ctr]; break; 68 | case 2: tops->rflavor = test_rflavor[ctr]; break; 69 | case 3: tops->numots = test_numots[ctr]; break; 70 | case 4: tops->bitlen = test_bitlen[ctr]; break; 71 | case 5: tops->nthreads = test_nthreads[ctr]; break; 72 | case 6: tops->usemecr = test_usemecr[ctr]; break; 73 | case 7: tops->ftype = test_ftype[ctr]; break; 74 | 75 | default: std::cerr << "Test case not recognized, abort" << std::endl; std::exit(EXIT_FAILURE); 76 | } 77 | } 78 | 79 | BOOL Cleanup() 80 | { 81 | delete sndthread; 82 | delete rcvthread; 83 | 84 | return true; 85 | } 86 | 87 | 88 | void InitSender(const std::string& address, const int port, CLock *glock) { 89 | m_nPort = (uint16_t) port; 90 | m_nAddr = &address; 91 | 92 | //Initialize values 93 | Init(); 94 | 95 | //Server listen 96 | m_Socket = Listen(address, port); 97 | if (!m_Socket) { 98 | std::cerr << "Listen failed on " << address << ":" << port << "\n"; 99 | std::exit(1); 100 | } 101 | 102 | sndthread = new SndThread(m_Socket.get(), glock); 103 | rcvthread = new RcvThread(m_Socket.get(), glock); 104 | 105 | sndthread->Start(); 106 | rcvthread->Start(); 107 | } 108 | 109 | void InitReceiver(const std::string& address, const int port, CLock *glock) { 110 | m_nPort = (uint16_t) port; 111 | m_nAddr = &address; 112 | 113 | //Initialize values 114 | Init(); 115 | 116 | //Client connect 117 | m_Socket = Connect(address, port); 118 | if (!m_Socket) { 119 | std::cerr << "Connect failed on " << address << ":" << port << "\n"; 120 | std::exit(1); 121 | } 122 | 123 | sndthread = new SndThread(m_Socket.get(), glock); 124 | rcvthread = new RcvThread(m_Socket.get(), glock); 125 | 126 | sndthread->Start(); 127 | rcvthread->Start(); 128 | } 129 | 130 | 131 | OTExtSnd* InitOTExtSnd(ot_ext_prot m_eProt, uint32_t nbaseots, uint32_t nchecks, bool enablemecr, field_type ftype, crypto* crypt) { 132 | uint32_t nsndvals = 2; 133 | OTExtSnd* sender; 134 | switch(m_eProt) { 135 | case ALSZ: sender = new ALSZOTExtSnd(crypt, rcvthread, sndthread, nbaseots, nchecks); break; 136 | case IKNP: sender = new IKNPOTExtSnd(crypt, rcvthread, sndthread); break; 137 | case NNOB: sender = new NNOBOTExtSnd(crypt, rcvthread, sndthread); break; 138 | default: sender = new ALSZOTExtSnd(crypt, rcvthread, sndthread, nbaseots, nchecks); break; 139 | } 140 | 141 | if(enablemecr) 142 | sender->EnableMinEntCorrRobustness(); 143 | sender->ComputeBaseOTs(ftype); 144 | return sender; 145 | } 146 | 147 | 148 | OTExtRec* InitOTExtRec(ot_ext_prot m_eProt, uint32_t nbaseots, uint32_t nchecks, bool enablemecr, field_type ftype, crypto* crypt) { 149 | uint32_t nsndvals = 2; 150 | OTExtRec* receiver; 151 | switch(m_eProt) { 152 | case ALSZ: receiver = new ALSZOTExtRec(crypt, rcvthread, sndthread, nbaseots, nchecks); break; 153 | case IKNP: receiver = new IKNPOTExtRec(crypt, rcvthread, sndthread); break; 154 | case NNOB: receiver = new NNOBOTExtRec(crypt, rcvthread, sndthread); break; 155 | default: receiver = new ALSZOTExtRec(crypt, rcvthread, sndthread, nbaseots, nchecks); break; 156 | } 157 | 158 | if(enablemecr) 159 | receiver->EnableMinEntCorrRobustness(); 160 | receiver->ComputeBaseOTs(ftype); 161 | return receiver; 162 | } 163 | 164 | int main(int argc, char** argv) 165 | { 166 | std::string addr = "127.0.0.1"; 167 | int port = 7766; 168 | 169 | if(argc != 2) 170 | { 171 | std::cout << "Please call with 0 if acting as server or 1 if acting as client" << std::endl; 172 | return EXIT_FAILURE; 173 | } 174 | 175 | //Determines whether the program is executed in the sender or receiver role 176 | m_nPID = atoi(argv[1]); 177 | std::cout << "Playing as role: " << m_nPID << std::endl; 178 | assert(m_nPID >= 0 && m_nPID <= 1); 179 | 180 | //The symmetric security parameter (80, 112, 128) 181 | uint32_t m_nSecParam = 128; 182 | 183 | crypto *crypt = new crypto(m_nSecParam, (uint8_t*) m_cConstSeed[m_nPID]); 184 | CLock *glock = new CLock(); // pass this to sender and receiver constructors 185 | 186 | uint32_t m_nBaseOTs = 190; 187 | uint32_t m_nChecks = 380; 188 | 189 | if(m_nPID == SERVER_ID) //Play as OT sender 190 | { 191 | InitSender(addr, port, glock); 192 | 193 | OTExtSnd* sender = NULL; 194 | for(uint32_t i = 0; i < m_nTests; i++) { 195 | sender = InitOTExtSnd(tests[i].prot, m_nBaseOTs, m_nChecks, tests[i].usemecr, tests[i].ftype, crypt); 196 | 197 | std::cout << "Test " << i << ": " << getProt(tests[i].prot) << " Sender " << tests[i].numots << " " << 198 | getSndFlavor(tests[i].sflavor) << " / " << getRecFlavor(tests[i].rflavor) << " on " << 199 | tests[i].bitlen << " bits with " << tests[i].nthreads << " threads, " << 200 | getFieldType(tests[i].ftype) << " and" << (tests[i].usemecr ? "": " no" ) << " MECR"<< std::endl; 201 | 202 | run_test_sender(tests[i].numots, tests[i].bitlen, tests[i].sflavor, tests[i].rflavor, tests[i].nthreads, crypt, sender); 203 | 204 | delete sender; 205 | } 206 | free(tests); 207 | } 208 | else //Play as OT receiver 209 | { 210 | InitReceiver(addr, port, glock); 211 | 212 | OTExtRec* receiver = NULL; 213 | for(uint32_t i = 0; i < m_nTests; i++) { 214 | receiver = InitOTExtRec(tests[i].prot, m_nBaseOTs, m_nChecks, tests[i].usemecr, tests[i].ftype, crypt); 215 | 216 | std::cout << "Test " << i << ": " << getProt(tests[i].prot) << " Receiver " << tests[i].numots << " " << 217 | getSndFlavor(tests[i].sflavor) << " / " << getRecFlavor(tests[i].rflavor) << " on " << 218 | tests[i].bitlen << " bits with " << tests[i].nthreads << " threads, " << 219 | getFieldType(tests[i].ftype) << " and" << (tests[i].usemecr ? "": " no" ) << " MECR"<< std::endl; 220 | 221 | run_test_receiver(tests[i].numots, tests[i].bitlen, tests[i].sflavor, tests[i].rflavor, tests[i].nthreads, crypt, receiver); 222 | 223 | delete receiver; 224 | } 225 | free(tests); 226 | 227 | } 228 | 229 | Cleanup(); 230 | delete crypt; 231 | delete glock; 232 | 233 | return EXIT_SUCCESS; 234 | } 235 | 236 | 237 | void run_test_sender(uint32_t numots, uint32_t bitlength, snd_ot_flavor stype, rec_ot_flavor rtype, uint32_t numthreads, 238 | crypto* crypt, OTExtSnd* sender) { 239 | CBitVector delta; 240 | uint32_t nsndvals = 2; 241 | CBitVector** X = (CBitVector**) malloc(sizeof(CBitVector*) * nsndvals); 242 | 243 | //The masking function with which the values that are sent in the last communication step are processed 244 | XORMasking* m_fMaskFct = new XORMasking(bitlength, delta); 245 | 246 | //creates delta as an array with "numOTs" entries of "bitlength" bit-values and fills delta with random values 247 | delta.Create(numots, bitlength, crypt); 248 | 249 | //Create X1 and X2 as two arrays with "numOTs" entries of "bitlength" bit-values and resets them to 0 250 | //X1.Create(numots, bitlength, crypt); 251 | //X2.Create(numots, bitlength, crypt); 252 | for(uint32_t i = 0; i < nsndvals; i++) { 253 | X[i] = new CBitVector(); 254 | X[i]->Create(numots, bitlength, crypt); 255 | } 256 | 257 | sender->send(numots, bitlength, nsndvals, X, stype, rtype, numthreads, m_fMaskFct); 258 | 259 | //X1.PrintHex(); 260 | //X2.PrintHex(); 261 | 262 | for(uint32_t i = 0; i < nsndvals; i++) { 263 | delete(X[i]); 264 | } 265 | free(X); 266 | //X1.delCBitVector(); 267 | //X2.delCBitVector(); 268 | delta.delCBitVector(); 269 | delete m_fMaskFct; 270 | } 271 | 272 | 273 | void run_test_receiver(uint32_t numots, uint32_t bitlength, snd_ot_flavor stype, rec_ot_flavor rtype, uint32_t numthreads, 274 | crypto* crypt, OTExtRec* receiver) { 275 | CBitVector choices, response; 276 | uint32_t nsndvals = 2; 277 | //The masking function with which the values that are sent in the last communication step are processed 278 | XORMasking* m_fMaskFct = new XORMasking(bitlength); 279 | 280 | //Create the bitvector choices as a bitvector with numOTs entries 281 | choices.Create(numots, crypt); 282 | 283 | //Pre-generate the respose vector for the results 284 | response.Create(numots, bitlength); 285 | response.Reset(); 286 | 287 | /* 288 | * The inputs of the receiver in G_OT, C_OT and R_OT are the same. The only difference is the version 289 | * variable that has to match the version of the sender. 290 | */ 291 | 292 | receiver->receive(numots, bitlength, nsndvals, &choices, &response, stype, rtype, numthreads, m_fMaskFct); 293 | delete m_fMaskFct; 294 | choices.delCBitVector(); 295 | response.delCBitVector(); 296 | } 297 | -------------------------------------------------------------------------------- /mains/test.h: -------------------------------------------------------------------------------- 1 | #ifndef _OTTEST_H_ 2 | #define _OTTEST_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../ot/iknp-ot-ext-snd.h" 8 | #include "../ot/iknp-ot-ext-rec.h" 9 | #include "../ot/alsz-ot-ext-snd.h" 10 | #include "../ot/alsz-ot-ext-rec.h" 11 | #include "../ot/nnob-ot-ext-snd.h" 12 | #include "../ot/nnob-ot-ext-rec.h" 13 | #include 14 | #include "../ot/xormasking.h" 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | uint16_t m_nPort = 7894; 28 | const std::string* m_nAddr; 29 | 30 | static const char* m_cConstSeed[2] = {"437398417012387813714564100", "15657566154164561"}; 31 | 32 | struct test_options { 33 | ot_ext_prot prot; 34 | uint64_t numots; 35 | uint64_t bitlen; 36 | snd_ot_flavor sflavor; 37 | rec_ot_flavor rflavor; 38 | uint32_t nthreads; 39 | field_type ftype; 40 | bool usemecr; 41 | }; 42 | 43 | test_options* tests; 44 | uint32_t m_nTests; 45 | uint32_t gen_tests; 46 | uint32_t m_nPID; 47 | 48 | void recursive_assign_test_params(uint32_t* max, uint32_t depth, test_options** tops, uint32_t max_depth); 49 | void assign_param(uint32_t ctr, uint32_t depth, test_options* tops); 50 | 51 | 52 | BOOL Init(); 53 | BOOL Cleanup(); 54 | BOOL Connect(); 55 | BOOL Listen(); 56 | 57 | void InitSender(const std::string& address, const int port, CLock *glock); 58 | void InitReceiver(const std::string& address, const int port, CLock *glock); 59 | 60 | OTExtSnd* InitOTExtSnd(ot_ext_prot m_eProt, uint32_t nbaseots, uint32_t nchecks, bool enablemecr, field_type ftype, crypto* crypt); 61 | OTExtRec* InitOTExtRec(ot_ext_prot m_eProt, uint32_t nbaseots, uint32_t nchecks, bool enablemecr, field_type ftype, crypto* crypt); 62 | 63 | void run_test_sender(uint32_t numots, uint32_t bitlength, snd_ot_flavor stype, rec_ot_flavor rtype, uint32_t numthreads, crypto* crypt, OTExtSnd* sender); 64 | void run_test_receiver(uint32_t numots, uint32_t bitlength, snd_ot_flavor stype, rec_ot_flavor rtype, uint32_t numthreads, crypto* crypt, OTExtRec* receiver); 65 | 66 | // Network Communication 67 | std::unique_ptr m_Socket; 68 | 69 | SndThread* sndthread; 70 | RcvThread* rcvthread; 71 | 72 | #endif 73 | 74 | -------------------------------------------------------------------------------- /ot/OTconstants.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file OTconstants.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief File containing all OT constants used throughout the source 17 | */ 18 | 19 | #ifndef _OT_CONSTANTS_H_ 20 | #define _OT_CONSTANTS_H_ 21 | 22 | #include 23 | 24 | #ifndef ABY_OT 25 | #define BATCH 26 | //#define USE_PIPELINED_AES_NI 27 | //#define SIMPLE_TRANSPOSE //activate the simple transpose, only required for benchmarking, not recommended 28 | 29 | #endif 30 | 31 | #define OT_ADMIN_CHANNEL MAX_NUM_COMM_CHANNELS-2 32 | #define OT_BASE_CHANNEL 0 33 | 34 | /** 35 | \enum ot_ext_prot 36 | \brief Specifies the different underlying OT extension protocols that are available 37 | */ 38 | enum ot_ext_prot { 39 | IKNP, ALSZ, NNOB, KK, PROT_LAST 40 | }; 41 | 42 | /** 43 | \enum snd_ot_flavor 44 | \brief Different OT flavors for the OT sender 45 | */ 46 | enum snd_ot_flavor { 47 | Snd_OT, Snd_C_OT, Snd_R_OT, Snd_GC_OT, Snd_OT_LAST 48 | }; 49 | 50 | /** 51 | \enum rec_ot_flavor 52 | \brief Different OT flavors for the OT receiver 53 | */ 54 | enum rec_ot_flavor { 55 | Rec_OT, Rec_R_OT, Rec_OT_LAST 56 | }; 57 | 58 | 59 | inline const char* getSndFlavor(snd_ot_flavor stype) { 60 | switch (stype) { 61 | case Snd_OT: return "Snd_OT"; 62 | case Snd_C_OT: return "Snd_C_OT"; 63 | case Snd_R_OT: return "Snd_R_OT"; 64 | case Snd_GC_OT: return "Snd_GC_OT"; 65 | default: return "unknown snd type"; 66 | } 67 | } 68 | 69 | inline const char* getRecFlavor(rec_ot_flavor rtype) { 70 | switch (rtype) { 71 | case Rec_OT: return "Rec_OT"; 72 | case Rec_R_OT: return "Rec_R_OT"; 73 | default: return "unknown rec type"; 74 | } 75 | } 76 | 77 | inline const char* getProt(ot_ext_prot prot) { 78 | switch (prot) { 79 | case IKNP: return "IKNP"; 80 | case ALSZ: return "ALSZ"; 81 | case NNOB: return "NNOB"; 82 | case KK: return "KK"; 83 | default: return "unknown protocol"; 84 | } 85 | } 86 | 87 | #endif /* _OT_CONSTANTS_H_ */ 88 | -------------------------------------------------------------------------------- /ot/alsz-ot-ext-rec.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file alsz-ot-rec.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief Malicious OT extension routine from ALSZ15 17 | */ 18 | 19 | #ifndef ALSZ_OT_EXT_REC_H_ 20 | #define ALSZ_OT_EXT_REC_H_ 21 | 22 | #include "ot-ext-rec.h" 23 | 24 | 25 | typedef struct alsz_rcv_check_ctx { 26 | uint64_t otid; 27 | uint64_t numblocks; 28 | uint8_t* T0; 29 | uint8_t* T1; 30 | } alsz_rcv_check_t; 31 | 32 | class ALSZOTExtRec : public OTExtRec { 33 | 34 | public: 35 | ALSZOTExtRec(crypto* crypt, RcvThread* rcvthread, SndThread* sndthread, 36 | uint32_t nbaseots, uint32_t nchecks, uint64_t num_ot_blocks=4096, bool verify_ot=true, bool use_fixed_key_aes_hashing=false) 37 | : OTExtRec(num_ot_blocks, verify_ot, use_fixed_key_aes_hashing) { 38 | InitRec(crypt, rcvthread, sndthread, nbaseots); 39 | m_nChecks = nchecks; 40 | m_bDoBaseOTs=false; 41 | //m_tBaseOTQ.resize(0);// = new vector;// = new vector(); 42 | } 43 | ; 44 | 45 | 46 | ~ALSZOTExtRec() {} ; 47 | 48 | BOOL receiver_routine(uint32_t threadid, uint64_t numOTs); 49 | void ComputeBaseOTs(field_type ftype); 50 | 51 | /*void setBaseOTs(base_ots_snd_t** baseOTKeys, uint32_t num_keys) { 52 | for(uint32_t i = 0; i < num_keys; i++) 53 | m_tBaseOTQ.push_back(baseOTKeys[i]); 54 | }*/ 55 | void computePKBaseOTs() { 56 | m_bDoBaseOTs = true; 57 | } 58 | 59 | private: 60 | alsz_rcv_check_t EnqueueSeed(uint8_t* T0, uint8_t* T1, uint64_t otid, uint64_t numblocks); 61 | void ComputeOWF(std::queue* check_buf_q, channel* check_chan); 62 | void ReceiveAndFillMatrix(uint64_t** rndmat, channel* mat_chan); 63 | 64 | //vector m_tBaseOTQ; 65 | bool m_bDoBaseOTs; 66 | }; 67 | 68 | #endif /* ALSZ_OT_EXT_REC_H_ */ 69 | -------------------------------------------------------------------------------- /ot/alsz-ot-ext-snd.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file alsz-ot-ext-snd.cpp 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief Malicious OT extension routine from ALSZ15 17 | */ 18 | 19 | #ifndef ALSZ_OT_EXT_SND_H_ 20 | #define ALSZ_OT_EXT_SND_H_ 21 | 22 | #include "ot-ext-snd.h" 23 | 24 | 25 | typedef struct alsz_snd_check_ctx { 26 | uint64_t otid; 27 | uint64_t numblocks; 28 | linking_t* perm; 29 | uint8_t* seed_chk_buf; 30 | uint8_t* rcv_chk_buf; 31 | CBitVector* choices; 32 | } alsz_snd_check_t; 33 | 34 | 35 | class ALSZOTExtSnd : public OTExtSnd { 36 | 37 | public: 38 | ALSZOTExtSnd(crypto* crypt, RcvThread* rcvthread, SndThread* sndthread, uint32_t nbaseots, 39 | uint32_t nchecks, uint64_t num_ot_blocks=4096, bool verify_ot=true, bool use_fixed_key_aes_hashing=false) 40 | : OTExtSnd(num_ot_blocks, verify_ot, use_fixed_key_aes_hashing) { 41 | InitSnd(crypt, rcvthread, sndthread, nbaseots); 42 | m_nChecks = nchecks; 43 | m_bDoBaseOTs = false; 44 | //m_tBaseOTQ.resize(0);// = new vector(); 45 | } 46 | ; 47 | 48 | ~ALSZOTExtSnd() {} ; 49 | 50 | BOOL sender_routine(uint32_t threadid, uint64_t numOTs); 51 | void ComputeBaseOTs(field_type ftype); 52 | //uint32_t ExtendBaseKeys(uint32_t threadid, uint64_t numOTs, base_ots_t*** out_keys); 53 | 54 | /*void setBaseOTs(base_ots_rcv_t** baseOTKeys, uint32_t num_keys) { 55 | for(uint32_t i = 0; i < num_keys; i++) 56 | m_tBaseOTQ.push_back(baseOTKeys[i]); 57 | }*/ 58 | void computePKBaseOTs() { 59 | m_bDoBaseOTs = true; 60 | } 61 | 62 | private: 63 | alsz_snd_check_t UpdateCheckBuf(uint8_t* tocheckseed, uint8_t* tocheckrcv, uint64_t otid, uint64_t numblocks, CBitVector* choices, channel* check_chan); 64 | void XORandOWF(uint8_t* idaptr, uint8_t* idbptr, uint64_t rowbytelen, uint8_t* tmpbuf, uint8_t* resbuf, uint8_t* hash_buf); 65 | void genRandomPermutation(linking_t* outperm, uint32_t nids, uint32_t nperms); 66 | BOOL CheckConsistency(std::queue* check_buf_q, channel* check_chan); 67 | void FillAndSendRandomMatrix(uint64_t **rndmat, channel* chan); 68 | 69 | bool m_bDoBaseOTs; 70 | 71 | }; 72 | 73 | #endif /* ALSZ_OT_EXT_SND_H_ */ 74 | -------------------------------------------------------------------------------- /ot/asharov-lindell.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file asharov-lindell.cpp 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | 20 | 21 | #include "asharov-lindell.h" 22 | 23 | 24 | /*#ifdef OTEXT_USE_GMP 25 | 26 | BOOL AsharovLindell::ReceiverIFC(int nSndVals, int nOTs, CBitVector& choices, CSocket& socket, BYTE* ret) 27 | { 28 | int nBufSize = nSndVals * m_NPState.field_size * nOTs; 29 | BYTE* pBuf = new BYTE[nBufSize]; //stores the answer bits of the receiver (d) in the Naor Pinkas Protocol 30 | 31 | mpz_t ztmp, ztmp2, pDec, div; 32 | mpz_t* h = new mpz_t[nOTs]; //h_i \in G 33 | mpz_t* beta = new mpz_t[nOTs]; // \beta_i \in Z_q 34 | 35 | mpz_init(ztmp); 36 | mpz_init(ztmp2); 37 | mpz_init(pDec); 38 | mpz_init(div); 39 | for (int i = 0; i < nOTs; i++) { 40 | mpz_init(h[i]); 41 | mpz_init(beta[i]); 42 | } 43 | 44 | mpz_sub_ui(ztmp2, m_NPState.p, 1); 45 | mpz_cdiv_q(div, ztmp2, m_NPState.q); 46 | 47 | 48 | for (int i = 0; i < nOTs; i++) { 49 | //sample random hi -- sample random element x in Zp, and then compute x^{(p-1)/q} mod p 50 | do 51 | { 52 | mpz_urandomb(ztmp, m_NPState.rnd_state, m_NPState.field_size * 8); 53 | mpz_mod(ztmp2, ztmp, m_NPState.p); 54 | mpz_powm(h[i], ztmp2, div, m_NPState.p); 55 | } while(!(mpz_cmp_ui(h[i], (unsigned long int) 1) ) ); 56 | //cout << h[i] << endl; 57 | //mpz_urandomb(ztmp, m_NPState.rnd_state, m_NPState.field_size * 8); 58 | //mpz_mod(ztmp2, ztmp, m_NPState.p); 59 | //mpz_mul(h[i], ztmp2, ztmp2); 60 | //mpz_mod(h[i], h[i], m_NPState.p); 61 | 62 | //sample random element betai 63 | mpz_urandomb(ztmp, m_NPState.rnd_state, m_NPState.field_size * 8); 64 | mpz_mod(beta[i], ztmp, m_NPState.q); 65 | 66 | } 67 | 68 | BYTE* pBufIdx = pBuf; 69 | 70 | //now, compute hi0, hi1 according to \sigma_i (m_r[i]) 71 | mpz_t h0, h1; 72 | mpz_init(h0); 73 | mpz_init(h1); 74 | FixedPointExp br(m_NPState.g, m_NPState.p, m_NPState.field_size * 8); 75 | 76 | for (int i = 0; i < nOTs; i++) { 77 | if (!choices.GetBit(i)) { 78 | br.powerMod(h0, beta[i]); 79 | mpz_set(h1, h[i]); 80 | } else { 81 | mpz_set(h0, h[i]); 82 | br.powerMod(h1, beta[i]); 83 | } 84 | 85 | // put hi0, hi1 86 | mpz_export_padded(pBufIdx, m_NPState.field_size, h0); 87 | pBufIdx += m_NPState.field_size; //use next buf positions 88 | mpz_export_padded(pBufIdx, m_NPState.field_size, h1); 89 | pBufIdx += m_NPState.field_size; //use next buf positions 90 | } 91 | 92 | socket.Send(pBuf, nBufSize); 93 | delete[] pBuf; 94 | 95 | //////////////////////////////////////////////////////////////////////////// 96 | // OT Step 2: 97 | // Recieve u, (v_i0,v_i1) for every i=1,...,m_nNumberOfInitialOT 98 | // For every i, compute ki = u^alphai and then xi^\sigma = vi^\sigma XOR KDF(ki^\sigma) 99 | //////////////////////////////////////////////////////////////////////////// 100 | 101 | nBufSize = m_NPState.field_size; 102 | pBuf = new BYTE[nBufSize]; 103 | 104 | socket.Receive(pBuf, nBufSize); 105 | 106 | //reading u 107 | mpz_t u; 108 | mpz_init(u); 109 | mpz_import(u, m_NPState.field_size, 1, sizeof(pBuf[0]), 0, 0, pBuf); 110 | 111 | BYTE* retPtr = ret; 112 | FixedPointExp ubr(u, m_NPState.p, m_NPState.field_size * 8); 113 | for (int k = 0; k < nOTs; k++) { 114 | ubr.powerMod(pDec, beta[k]); 115 | mpz_export_padded(pBuf, m_NPState.field_size, pDec); 116 | 117 | hashReturn(retPtr, pBuf, m_NPState.field_size, k); 118 | retPtr += SHA1_BYTES; 119 | } 120 | return true; 121 | } 122 | 123 | 124 | BOOL AsharovLindell::SenderIFC(int nSndVals, int nOTs, CSocket& socket, BYTE* ret) 125 | { 126 | //buffer for sending u 127 | int nBufSize = m_NPState.field_size; 128 | BYTE* pBuf = new BYTE[nBufSize]; 129 | 130 | mpz_t alpha, ztmp, u; 131 | mpz_init(alpha); 132 | mpz_init(u); 133 | mpz_init(ztmp); 134 | 135 | //random u 136 | mpz_urandomb(ztmp, m_NPState.rnd_state, m_NPState.field_size*8); 137 | mpz_mod(alpha, ztmp, m_NPState.q); 138 | mpz_powm(u, m_NPState.g, alpha, m_NPState.p); 139 | mpz_export_padded(pBuf, m_NPState.field_size, u); 140 | socket.Send(pBuf, nBufSize); 141 | 142 | //==================================================== 143 | // N-P sender: receive pk0 144 | delete pBuf; 145 | nBufSize = m_NPState.field_size * nOTs * nSndVals; 146 | pBuf = new BYTE[nBufSize]; 147 | socket.Receive(pBuf, nBufSize); //receive the d_j's 148 | 149 | mpz_t pH, pK; 150 | mpz_init(pH); 151 | mpz_init(pK); 152 | 153 | BYTE* pBufIdx = pBuf; 154 | BYTE* retPtr = ret; 155 | 156 | for(int k = 0; k < nSndVals * nOTs; k++) 157 | { 158 | //mpz_init(k1[k]); 159 | mpz_import(pH, m_NPState.field_size, 1, sizeof(pBufIdx[0]), 0, 0, pBufIdx); 160 | mpz_powm(pK, pH, alpha, m_NPState.p); 161 | mpz_export_padded(pBufIdx, m_NPState.field_size, pK); 162 | 163 | hashReturn(retPtr, pBufIdx, m_NPState.field_size, k/nSndVals); 164 | pBufIdx += m_NPState.field_size; 165 | retPtr += SHA1_BYTES; 166 | } 167 | 168 | return true; 169 | } 170 | #endif*/ 171 | 172 | void AsharovLindell::Receiver(uint32_t nSndVals, uint32_t nOTs, CBitVector* choices, channel* chan, BYTE* ret) 173 | { 174 | /*int coordSize = (m_SecParam+7)/8;//(state.field_size/8) + 4; 175 | int nBufSize = nSndVals * (coordSize+1) * nOTs; 176 | 177 | #ifdef USE_PRIME_FIELD 178 | ECn g, h0, h1, h[nOTs], u, pDec; 179 | #else 180 | EC2 g, h0, h1, h[nOTs], u, pDec; 181 | #endif 182 | Big ztmp, ztmp2, beta[nOTs], xtmp, ytmp; 183 | 184 | BYTE* pBuf = new BYTE[nBufSize]; //stores the answer bits of the receiver (d) in the Naor Pinkas Protocol 185 | 186 | 187 | Miracl_InitPoint(&g, *m_X, *m_Y); 188 | #ifdef USE_PRIME_FIELD 189 | ebrick bg, bu; 190 | #else 191 | ebrick2 bg, bu; 192 | #endif 193 | 194 | Miracl_InitBrick(&bg, &g); 195 | 196 | 197 | for (int i = 0, idx = 0; i < nOTs; i++) { 198 | //sample random hi -- sample random element x in Zp, and then compute x^2 mod p 199 | //ztmp = rand(m_SecParam, 2); 200 | //Miracl_mulbrick(&bg, ztmp.getbig(), xtmp.getbig(), ytmp.getbig()); 201 | //Miracl_InitPoint(h+i, xtmp, ytmp); 202 | SampleRandomPoint(h+i, m_SecParam); 203 | 204 | beta[i] = rand(m_SecParam, 2); 205 | } 206 | 207 | BYTE* pBufIdx = pBuf; 208 | 209 | //now, compute hi0, hi1 according to \sigma_i (m_r[i]) 210 | for (int i = 0, idx = 0; i < nOTs; i++) { 211 | if (!choices.GetBit(i)) 212 | { 213 | Miracl_mulbrick(&bg, beta[i].getbig(), xtmp.getbig(), ytmp.getbig()); 214 | Miracl_InitPoint(&h0, xtmp, ytmp); 215 | //ecurve_mult(beta[i].getbig(), g.get_point(), h0.get_point()); 216 | h1 = h[i]; 217 | } 218 | else 219 | { 220 | h0 = h[i]; 221 | Miracl_mulbrick(&bg, beta[i].getbig(), xtmp.getbig(), ytmp.getbig()); 222 | Miracl_InitPoint(&h1, xtmp, ytmp);//h1 = EC2(xtmp, ytmp); 223 | //ecurve_mult(beta[i].getbig(), g.get_point(), h1.get_point()); 224 | 225 | } 226 | 227 | // put hi0, hi1 228 | PointToByteArray(pBufIdx, coordSize, h0); 229 | pBufIdx += coordSize+1; 230 | PointToByteArray(pBufIdx, coordSize, h1); 231 | pBufIdx += coordSize+1; 232 | } 233 | 234 | socket.Send(pBuf, nBufSize); 235 | delete[] pBuf; 236 | 237 | //////////////////////////////////////////////////////////////////////////// 238 | // OT Step 2: 239 | // Recieve u, (v_i0,v_i1) for every i=1,...,m_nNumberOfInitialOT 240 | // For every i, compute ki = u^alphai and then xi^\sigma = vi^\sigma XOR KDF(ki^\sigma) 241 | //////////////////////////////////////////////////////////////////////////// 242 | 243 | nBufSize = coordSize +1; 244 | pBuf = new BYTE[nBufSize]; 245 | 246 | socket.Receive(pBuf, nBufSize); 247 | 248 | //reading u 249 | ByteArrayToPoint(&u, coordSize, pBuf); 250 | 251 | Miracl_InitBrick(&bu, &u); 252 | 253 | BYTE* retPtr = ret; 254 | for (int k = 0; k < nOTs; k++) 255 | { 256 | //ecurve_mult(beta[k].getbig(), u.get_point(), pDec.get_point()); 257 | Miracl_mulbrick(&bu, beta[k].getbig(), xtmp.getbig(), ytmp.getbig()); 258 | Miracl_InitPoint(&pDec, xtmp, ytmp);//pDec = EC2(xtmp, ytmp); 259 | PointToByteArray(pBuf, coordSize, pDec); 260 | hashReturn(retPtr, pBuf, coordSize+1, k); 261 | retPtr += SHA1_BYTES; 262 | } 263 | 264 | Miracl_brickend(&bu); 265 | Miracl_brickend(&bg); 266 | */ 267 | } 268 | 269 | 270 | void AsharovLindell::Sender(uint32_t nSndVals, uint32_t nOTs, channel* chan, BYTE* ret) 271 | { 272 | /* //buffer for sending u 273 | int coordSize = (m_SecParam+7)/8;//(state.field_size/8) + 4; 274 | int nBufSize = (coordSize+1); 275 | #ifdef USE_PRIME_FIELD 276 | ECn ztmp, u, g; 277 | #else 278 | EC2 ztmp, u, g; 279 | #endif 280 | Big alpha; 281 | 282 | BYTE* pBuf = new BYTE[nBufSize]; 283 | 284 | Miracl_InitPoint(&g, *m_X, *m_Y);//g = EC2(*m_X, *m_Y); 285 | 286 | //ebrick bg; 287 | //Miracl_InitBrick(&bg, &g); 288 | 289 | //random u 290 | alpha = rand(m_SecParam, 2); 291 | //mul_brick(&bx, alpha.getbig(), xtmp.getbig(), ytmp.getbig()); 292 | //u = ECn(xtmp, ytmp); 293 | u = g; 294 | u *= alpha; 295 | 296 | PointToByteArray(pBuf, coordSize, u); 297 | socket.Send(pBuf, nBufSize); 298 | 299 | //==================================================== 300 | // N-P sender: receive pk0 301 | delete pBuf; 302 | nBufSize = (coordSize +1) * nOTs * nSndVals; 303 | pBuf = new BYTE[nBufSize]; 304 | socket.Receive(pBuf, nBufSize); 305 | 306 | #ifdef USE_PRIME_FIELD 307 | ECn pH, pK; 308 | #else 309 | EC2 pH, pK; 310 | #endif 311 | BYTE* pBufIdx = pBuf; 312 | BYTE* retPtr = ret; 313 | 314 | for(int k = 0; k < nSndVals * nOTs; k++) 315 | { 316 | ByteArrayToPoint(&pH, coordSize, pBufIdx); 317 | #ifdef USE_PRIME_FIELD 318 | ecurve_mult(alpha.getbig(), pH.get_point(), pK.get_point()); 319 | #else 320 | ecurve2_mult(alpha.getbig(), pH.get_point(), pK.get_point()); 321 | #endif 322 | PointToByteArray(pBufIdx, coordSize, pK); 323 | 324 | hashReturn(retPtr, pBufIdx, coordSize+1, k/nSndVals); 325 | pBufIdx += coordSize+1; 326 | retPtr += SHA1_BYTES; 327 | } 328 | */ 329 | } 330 | 331 | -------------------------------------------------------------------------------- /ot/asharov-lindell.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file asharov-lindell.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | #ifndef ASHAROVLINDELL_H_ 20 | #define ASHAROVLINDELL_H_ 21 | 22 | #include "baseOT.h" 23 | 24 | class AsharovLindell : public BaseOT 25 | { 26 | public: 27 | ~AsharovLindell(){}; 28 | 29 | AsharovLindell(crypto* crypt, field_type ftype) : 30 | BaseOT(crypt, ftype) { 31 | } 32 | ; 33 | void Receiver(uint32_t nSndVals, uint32_t nOTs, CBitVector* choices, channel* chan, BYTE* ret); 34 | void Sender(uint32_t nSndVals, uint32_t nOTs, channel* chan, BYTE* ret); 35 | 36 | 37 | }; 38 | 39 | #endif /* ASHAROVLINDELL_H_ */ 40 | -------------------------------------------------------------------------------- /ot/baseOT.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file baseOT.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | 20 | #ifndef BASEOT_H_ 21 | #define BASEOT_H_ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #ifdef DEBUG_BASE_OT_HASH_RET 29 | #include 30 | #endif 31 | 32 | class channel; 33 | class CBitVector; 34 | 35 | 36 | class BaseOT { 37 | public: 38 | BaseOT(crypto* crypt, field_type ftype) { 39 | m_cCrypto = crypt; 40 | m_cPKCrypto = crypt->gen_field(ftype); 41 | } 42 | ; 43 | 44 | virtual ~BaseOT() { delete m_cPKCrypto; }; 45 | 46 | virtual void Sender(uint32_t nSndVals, uint32_t nOTs, channel* chan, uint8_t* ret) = 0; 47 | virtual void Receiver(uint32_t nSndVals, uint32_t uint32_t, CBitVector* choices, channel* chan, uint8_t* ret) = 0; 48 | 49 | protected: 50 | 51 | crypto* m_cCrypto; 52 | pk_crypto* m_cPKCrypto; 53 | 54 | void hashReturn(uint8_t* ret, uint32_t ret_len, uint8_t* val, uint32_t val_len, uint64_t ctr) { 55 | #ifdef DEBUG_BASE_OT_HASH_RET 56 | std::cout << ctr << " input : "; 57 | for(uint32_t i = 0; i < val_len; i++) { 58 | std::cout << (std::hex) << (uint32_t) val[i]; 59 | } 60 | std::cout << (std::dec) << std::endl; 61 | #endif 62 | m_cCrypto->hash_ctr(ret, ret_len, val, val_len, ctr); 63 | #ifdef DEBUG_BASE_OT_HASH_RET 64 | std::cout << ctr << " output: "; 65 | for(uint32_t i = 0; i < ret_len; i++) { 66 | std::cout << (std::hex) << (uint32_t) ret[i]; 67 | } 68 | std::cout << (std::dec) << std::endl; 69 | #endif 70 | } 71 | 72 | }; 73 | 74 | #endif /* BASEOT_H_ */ 75 | -------------------------------------------------------------------------------- /ot/iknp-ot-ext-rec.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file iknp-ot-ext-rec.cpp 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | 20 | #include "iknp-ot-ext-rec.h" 21 | #include "naor-pinkas.h" 22 | #include 23 | #include 24 | 25 | 26 | BOOL IKNPOTExtRec::receiver_routine(uint32_t id, uint64_t myNumOTs) { 27 | uint64_t myStartPos = id * myNumOTs; 28 | uint64_t wd_size_bits = m_nBlockSizeBits; 29 | 30 | myNumOTs = std::min(myNumOTs + myStartPos, m_nOTs) - myStartPos; 31 | uint64_t lim = myStartPos + myNumOTs; 32 | 33 | uint64_t processedOTBlocks = std::min(num_ot_blocks, ceil_divide(myNumOTs, wd_size_bits)); 34 | uint64_t OTsPerIteration = processedOTBlocks * wd_size_bits; 35 | uint64_t OTwindow = num_ot_blocks * wd_size_bits; 36 | uint64_t** rndmat; 37 | channel* chan = new channel(OT_BASE_CHANNEL+id, m_cRcvThread, m_cSndThread); 38 | 39 | // A temporary part of the T matrix 40 | CBitVector T(wd_size_bits * OTsPerIteration); 41 | 42 | // The send buffer 43 | #ifdef GENERATE_T_EXPLICITELY 44 | CBitVector vSnd(m_nBaseOTs * OTsPerIteration * 2); 45 | #else 46 | CBitVector vSnd(m_nBaseOTs * OTsPerIteration); 47 | #endif 48 | 49 | // A temporary buffer that stores the resulting seeds from the hash buffer 50 | //TODO: Check for some maximum size 51 | CBitVector seedbuf(OTwindow * m_cCrypt->get_aes_key_bytes() * 8); 52 | 53 | uint64_t otid = myStartPos; 54 | 55 | std::queue mask_queue; 56 | 57 | CBitVector maskbuf; 58 | maskbuf.Create(m_nBitLength * OTwindow); 59 | 60 | if(m_eSndOTFlav == Snd_GC_OT) { 61 | uint8_t* rnd_seed = chan->blocking_receive(); 62 | initRndMatrix(&rndmat, m_nBitLength, m_nBaseOTs); 63 | fillRndMatrix(rnd_seed, rndmat, m_nBitLength, m_nBaseOTs, m_cCrypt); 64 | free(rnd_seed); 65 | } 66 | 67 | #ifdef OTTiming 68 | double totalMtxTime = 0, totalTnsTime = 0, totalHshTime = 0, totalRcvTime = 0, totalSndTime = 0, totalChkTime = 0, totalMaskTime = 0; 69 | timespec tempStart, tempEnd; 70 | #endif 71 | 72 | while (otid < lim) { 73 | processedOTBlocks = std::min(num_ot_blocks, ceil_divide(lim - otid, wd_size_bits)); 74 | OTsPerIteration = processedOTBlocks * wd_size_bits; 75 | //nSize = bits_in_bytes(m_nBaseOTs * OTsPerIteration); 76 | 77 | #ifdef ZDEBUG 78 | std::cout << "Receiver thread " << id << " processing block " << otid << 79 | " with length: " << OTsPerIteration << ", and limit: " << lim << std::endl; 80 | #endif 81 | 82 | 83 | #ifdef OTTiming 84 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 85 | #endif 86 | BuildMatrices(&T, &vSnd, otid, processedOTBlocks, m_tBaseOTKeys.front()); 87 | #ifdef OTTiming 88 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 89 | totalMtxTime += getMillies(tempStart, tempEnd); 90 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 91 | #endif 92 | MaskBaseOTs(&T, &vSnd, otid, processedOTBlocks); 93 | #ifdef OTTiming 94 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 95 | totalMaskTime += getMillies(tempStart, tempEnd); 96 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 97 | #endif 98 | T.Transpose(wd_size_bits, OTsPerIteration); 99 | #ifdef OTTiming 100 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 101 | totalTnsTime += getMillies(tempStart, tempEnd); 102 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 103 | #endif 104 | HashValues(&T, &seedbuf, &maskbuf, otid, std::min(lim - otid, OTsPerIteration), rndmat); 105 | #ifdef OTTiming 106 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 107 | totalHshTime += getMillies(tempStart, tempEnd); 108 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 109 | #endif 110 | SendMasks(&vSnd, chan, otid, OTsPerIteration); 111 | #ifdef OTTiming 112 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 113 | totalSndTime += getMillies(tempStart, tempEnd); 114 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 115 | #endif 116 | SetOutput(&maskbuf, otid, OTsPerIteration, &mask_queue, chan);//ReceiveAndUnMask(chan); 117 | 118 | //counter += std::min(lim - OT_ptr, OTsPerIteration); 119 | otid += std::min(lim - otid, OTsPerIteration); 120 | #ifdef OTTiming 121 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 122 | totalRcvTime += getMillies(tempStart, tempEnd); 123 | #endif 124 | 125 | vSnd.Reset(); 126 | T.Reset(); 127 | } 128 | //sndthread->signal_end(id); 129 | 130 | if(m_eSndOTFlav != Snd_R_OT && m_eSndOTFlav != Snd_GC_OT) { 131 | //finevent->Wait(); 132 | #ifdef ABY_OT 133 | while(!(mask_queue.empty())) { 134 | #else 135 | while(chan->is_alive() && !(mask_queue.empty())) { 136 | #endif 137 | ReceiveAndUnMask(chan, &mask_queue); 138 | } 139 | } 140 | 141 | #ifdef ZDEBUG 142 | std::cout << "Receiver thread " << id << " finished " << std::endl; 143 | #endif 144 | 145 | 146 | chan->synchronize_end(); 147 | 148 | if(m_eSndOTFlav==Snd_GC_OT) 149 | freeRndMatrix(rndmat, m_nBaseOTs); 150 | #ifdef OTTiming 151 | std::cout << "Receiver time benchmark for performing " << myNumOTs << " OTs on " << m_nBitLength << " bit strings" << std::endl; 152 | std::cout << "Time needed for: " << std::endl; 153 | std::cout << "\t Matrix Generation:\t" << totalMtxTime << " ms" << std::endl; 154 | std::cout << "\t Base OT Masking:\t" << totalMaskTime << " ms" << std::endl; 155 | std::cout << "\t Sending Matrix:\t" << totalSndTime << " ms" << std::endl; 156 | std::cout << "\t Transposing Matrix:\t" << totalTnsTime << " ms" << std::endl; 157 | std::cout << "\t Hashing Matrix:\t" << totalHshTime << " ms" << std::endl; 158 | std::cout << "\t Receiving Values:\t" << totalRcvTime << " ms" << std::endl; 159 | #endif 160 | 161 | T.delCBitVector(); 162 | vSnd.delCBitVector(); 163 | seedbuf.delCBitVector(); 164 | maskbuf.delCBitVector(); 165 | delete chan; 166 | 167 | return TRUE; 168 | } 169 | 170 | 171 | void IKNPOTExtRec::ComputeBaseOTs(field_type ftype) { 172 | m_cBaseOT = new NaorPinkas(m_cCrypt, ftype); 173 | ComputePKBaseOTs(); 174 | delete m_cBaseOT; 175 | } 176 | -------------------------------------------------------------------------------- /ot/iknp-ot-ext-rec.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file iknp-ot-ext-rec.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | #ifndef IKNP_OT_EXTENSION_RECEIVER_H_ 20 | #define IKNP_OT_EXTENSION_RECEIVER_H_ 21 | 22 | #include "ot-ext-rec.h" 23 | 24 | 25 | class IKNPOTExtRec : public OTExtRec { 26 | 27 | public: 28 | IKNPOTExtRec(crypto* crypt, RcvThread* rcvthread, SndThread* sndthread, uint64_t num_ot_blocks=4096, bool verify_ot=true, bool use_fixed_key_aes_hashing=false) 29 | : OTExtRec(num_ot_blocks, verify_ot, use_fixed_key_aes_hashing) { 30 | InitRec(crypt, rcvthread, sndthread, crypt->get_seclvl().symbits); 31 | } 32 | ; 33 | 34 | 35 | virtual ~IKNPOTExtRec() {} ; 36 | 37 | BOOL receiver_routine(uint32_t threadid, uint64_t numOTs); 38 | void ComputeBaseOTs(field_type ftype); 39 | }; 40 | 41 | #endif /* OT_EXTENSION_RECEIVER_H_ */ 42 | -------------------------------------------------------------------------------- /ot/iknp-ot-ext-snd.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file iknp-ot-ext-snd.cpp 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | #include "iknp-ot-ext-snd.h" 20 | #include "naor-pinkas.h" 21 | #include 22 | #include 23 | 24 | //BOOL OTsender(int nSndVals, int nOTs, int startpos, CSocket& sock, CBitVector& U, AES_KEY* vKeySeeds, CBitVector* values, BYTE* seed) 25 | BOOL IKNPOTExtSnd::sender_routine(uint32_t id, uint64_t myNumOTs) { 26 | uint64_t myStartPos = id * myNumOTs; 27 | uint64_t wd_size_bits = m_nBlockSizeBits; 28 | uint64_t processedOTBlocks = std::min(num_ot_blocks, ceil_divide(myNumOTs, wd_size_bits)); 29 | uint64_t OTsPerIteration = processedOTBlocks * wd_size_bits; 30 | channel* chan = new channel(OT_BASE_CHANNEL+id, m_cRcvThread, m_cSndThread); 31 | uint64_t** rndmat; 32 | 33 | myNumOTs = std::min(myNumOTs + myStartPos, m_nOTs) - myStartPos; 34 | uint64_t lim = myStartPos + myNumOTs; 35 | 36 | // The vector with the received bits 37 | #ifdef GENERATE_T_EXPLICITELY 38 | CBitVector vRcv(2 * m_nBaseOTs * OTsPerIteration); 39 | #else 40 | CBitVector vRcv(m_nBaseOTs * OTsPerIteration); 41 | #endif 42 | 43 | // Holds the reply that is sent back to the receiver 44 | uint32_t numsndvals = 2; 45 | CBitVector* vSnd; 46 | 47 | CBitVector* seedbuf = new CBitVector[m_nSndVals]; 48 | for (uint32_t u = 0; u < m_nSndVals; u++) 49 | seedbuf[u].Create(OTsPerIteration * m_cCrypt->get_aes_key_bytes() * 8); 50 | #ifdef ZDEBUG 51 | std::cout << "seedbuf size = " <gen_rnd(rnd_seed, m_nSymSecParam); 71 | chan->send(rnd_seed, m_nSymSecParam); 72 | initRndMatrix(&rndmat, m_nBitLength, m_nBaseOTs); 73 | fillRndMatrix(rnd_seed, rndmat, m_nBitLength, m_nBaseOTs, m_cCrypt); 74 | free(rnd_seed); 75 | } 76 | 77 | while (otid < lim) //do while there are still transfers missing 78 | { 79 | processedOTBlocks = std::min(num_ot_blocks, ceil_divide(lim - otid, wd_size_bits)); 80 | OTsPerIteration = processedOTBlocks * wd_size_bits; 81 | 82 | #ifdef ZDEBUG 83 | std::cout << "Sender thread " << id << " processing block " << otid << 84 | " with length: " << OTsPerIteration << ", and limit: " << lim << std::endl; 85 | #endif 86 | 87 | #ifdef OTTiming 88 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 89 | #endif 90 | ReceiveMasks(&vRcv, chan, OTsPerIteration); 91 | 92 | #ifdef OTTiming 93 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 94 | totalRcvTime += getMillies(tempStart, tempEnd); 95 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 96 | #endif 97 | BuildQMatrix(&Q, otid, processedOTBlocks, m_tBaseOTKeys.front()); 98 | #ifdef OTTiming 99 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 100 | totalMtxTime += getMillies(tempStart, tempEnd); 101 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 102 | #endif 103 | UnMaskBaseOTs(&Q, &vRcv, m_tBaseOTChoices.front(), processedOTBlocks); 104 | #ifdef OTTiming 105 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 106 | totalUnMaskTime += getMillies(tempStart, tempEnd); 107 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 108 | #endif 109 | Q.Transpose(wd_size_bits, OTsPerIteration); 110 | #ifdef OTTiming 111 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 112 | totalTnsTime += getMillies(tempStart, tempEnd); 113 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 114 | #endif 115 | HashValues(&Q, seedbuf, vSnd, m_tBaseOTChoices.front(), otid, std::min(lim - otid, OTsPerIteration), rndmat); 116 | #ifdef OTTiming 117 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 118 | totalHshTime += getMillies(tempStart, tempEnd); 119 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 120 | #endif 121 | MaskAndSend(vSnd, otid, std::min(lim - otid, OTsPerIteration), chan); 122 | #ifdef OTTiming 123 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 124 | totalSndTime += getMillies(tempStart, tempEnd); 125 | #endif 126 | otid += std::min(lim - otid, OTsPerIteration); 127 | Q.Reset(); 128 | } 129 | 130 | #ifdef ZDEBUG 131 | std::cout << "Sender thread " << id << " finished " << std::endl; 132 | #endif 133 | 134 | vRcv.delCBitVector(); 135 | chan->synchronize_end(); 136 | 137 | Q.delCBitVector(); 138 | delete[] seedbuf; 139 | delete[] vSnd; 140 | 141 | if(m_eSndOTFlav==Snd_GC_OT) 142 | freeRndMatrix(rndmat, m_nBaseOTs); 143 | 144 | #ifdef OTTiming 145 | std::cout << "Sender time benchmark for performing " << myNumOTs << " OTs on " << m_nBitLength << " bit strings" << std::endl; 146 | std::cout << "Time needed for: " << std::endl; 147 | std::cout << "\t Matrix Generation:\t" << totalMtxTime << " ms" << std::endl; 148 | std::cout << "\t Unmasking values:\t" << totalUnMaskTime << " ms" << std::endl; 149 | std::cout << "\t Sending Matrix:\t" << totalSndTime << " ms" << std::endl; 150 | std::cout << "\t Transposing Matrix:\t" << totalTnsTime << " ms" << std::endl; 151 | std::cout << "\t Hashing Matrix:\t" << totalHshTime << " ms" << std::endl; 152 | std::cout << "\t Receiving Values:\t" << totalRcvTime << " ms" << std::endl; 153 | #endif 154 | 155 | delete chan; 156 | 157 | return TRUE; 158 | } 159 | 160 | 161 | void IKNPOTExtSnd::ComputeBaseOTs(field_type ftype) { 162 | m_cBaseOT = new NaorPinkas(m_cCrypt, ftype); 163 | ComputePKBaseOTs(); 164 | delete m_cBaseOT; 165 | } 166 | -------------------------------------------------------------------------------- /ot/iknp-ot-ext-snd.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file iknp-ot-ext-snd.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | #ifndef IKNP_OT_EXT_SENDER_H_ 20 | #define IKNP_OT_EXT_SENDER_H_ 21 | 22 | #include "ot-ext-snd.h" 23 | 24 | class IKNPOTExtSnd : public OTExtSnd { 25 | 26 | public: 27 | IKNPOTExtSnd(crypto* crypt, RcvThread* rcvthread, SndThread* sndthread, uint64_t num_ot_blocks=4096, bool verify_ot=true, bool use_fixed_key_aes_hashing=false) 28 | : OTExtSnd(num_ot_blocks, verify_ot, use_fixed_key_aes_hashing) { 29 | InitSnd(crypt, rcvthread, sndthread, crypt->get_seclvl().symbits); 30 | } 31 | ; 32 | 33 | 34 | virtual ~IKNPOTExtSnd() { }; 35 | 36 | BOOL sender_routine(uint32_t threadid, uint64_t numOTs); 37 | void ComputeBaseOTs(field_type ftype); 38 | }; 39 | 40 | 41 | 42 | #endif /* IKNP_OT_EXT_SENDER_H_ */ 43 | -------------------------------------------------------------------------------- /ot/kk-ot-ext-rec.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file kk-ot-ext-rec.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | 20 | #ifndef KK_OT_EXTENSION_RECEIVER_H_ 21 | #define KK_OT_EXTENSION_RECEIVER_H_ 22 | 23 | #include "ot-ext-rec.h" 24 | #include "kk-ot-ext.h" 25 | 26 | class KKOTExtRec : public OTExtRec, public KKOTExt { 27 | 28 | public: 29 | KKOTExtRec(crypto* crypt, RcvThread* rcvthread, SndThread* sndthread, uint64_t num_ot_blocks=4096, bool verify_ot=true, bool use_fixed_key_aes_hashing=false) 30 | : OTExtRec(num_ot_blocks, verify_ot, use_fixed_key_aes_hashing) { 31 | uint32_t numbaseots = 2*crypt->get_seclvl().symbits;//, pad_to_power_of_two(nSndVals)); 32 | 33 | //assert(pad_to_power_of_two(nSndVals) == nSndVals); //TODO right now only supports power of two nSndVals 34 | assert(numbaseots == 256); //TODO: right now only 256 base OTs work due to the size of the code 35 | InitRec(crypt, rcvthread, sndthread, 2*crypt->get_seclvl().symbits); 36 | 37 | 38 | //Initialize the code words 39 | InitAndReadCodeWord(&m_vCodeWords); 40 | } 41 | ; 42 | 43 | 44 | virtual ~KKOTExtRec() { 45 | //TODO 46 | //free(m_vKeySeedMtx); 47 | } 48 | ; 49 | 50 | BOOL receiver_routine(uint32_t threadid, uint64_t numOTs); 51 | void ComputeBaseOTs(field_type ftype); 52 | 53 | private: 54 | void GenerateChoiceCodes(CBitVector* choicecodes, CBitVector* vSnd, CBitVector* T, uint32_t startpos, uint32_t len); 55 | void KKSetOutput(CBitVector* maskbuf, uint64_t otid, uint64_t otlen, std::queue* mask_queue, channel* chan); 56 | void KKHashValues(CBitVector* T, CBitVector* seedbuf, CBitVector* maskbuf, uint64_t OT_ptr, uint64_t OT_len, uint64_t** mat_mul); 57 | void KKMaskBaseOTs(CBitVector* T, CBitVector* SndBuf, uint64_t numblocks); 58 | void KKReceiveAndUnMask(channel* chan, std::queue* mask_queue); 59 | //uint64_t** m_vCodeWords; 60 | }; 61 | 62 | #endif /* KK_OT_EXTENSION_RECEIVER_H_ */ 63 | -------------------------------------------------------------------------------- /ot/kk-ot-ext-snd.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file kk-ot-ext-snd.cpp 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | #include "kk-ot-ext-snd.h" 20 | #include "naor-pinkas.h" 21 | #include 22 | #include 23 | #include 24 | 25 | BOOL KKOTExtSnd::sender_routine(uint32_t id, uint64_t myNumOTs) { 26 | assert(m_eSndOTFlav != Snd_GC_OT); //not working for GC_OT 27 | assert(m_nSndVals <= m_nBaseOTs); 28 | set_internal_sndvals(m_nSndVals, m_nBitLength); 29 | 30 | // uint32_t choicecodebitlen = ceil_log2(m_nint_sndvals); 31 | uint32_t int_choicecodebits = ceil_log2(m_nint_sndvals); 32 | uint32_t ext_choicecodebits = ceil_log2(m_nSndVals); 33 | uint32_t diff_choicecodes = int_choicecodebits / ext_choicecodebits; 34 | uint64_t myStartPos = id * myNumOTs; 35 | uint64_t myStartPos1ooN = ceil_divide(myStartPos, diff_choicecodes); 36 | 37 | uint64_t wd_size_bits = m_nBlockSizeBits; 38 | uint64_t processedOTBlocks = std::min(num_ot_blocks, ceil_divide(myNumOTs, wd_size_bits)); 39 | uint64_t OTsPerIteration = processedOTBlocks * wd_size_bits; 40 | channel* chan = new channel(OT_BASE_CHANNEL+id, m_cRcvThread, m_cSndThread); 41 | uint64_t** rndmat; 42 | uint64_t processedOTs; 43 | 44 | myNumOTs = std::min(myNumOTs + myStartPos, m_nOTs) - myStartPos; 45 | //TODO some re-formating of myNumOTs due to 1ooN OT 46 | uint64_t lim = myStartPos1ooN + ceil_divide(myNumOTs, diff_choicecodes); 47 | 48 | if(myStartPos1ooN * diff_choicecodes> m_nOTs) { 49 | std::cerr << "Thread " << id << " not doing any work to align to window size " << std::endl; 50 | return true; 51 | } 52 | 53 | // The vector with the received bits 54 | #ifdef GENERATE_T_EXPLICITELY 55 | CBitVector vRcv(2 * m_nBaseOTs * OTsPerIteration); 56 | #else 57 | CBitVector vRcv(m_nBaseOTs * OTsPerIteration); 58 | #endif 59 | 60 | // Holds the reply that is sent back to the receiver 61 | CBitVector* vSnd; 62 | 63 | CBitVector* seedbuf = new CBitVector[m_nint_sndvals]; 64 | for (uint32_t u = 0; u < m_nint_sndvals; u++) 65 | seedbuf[u].Create(OTsPerIteration * m_cCrypt->get_aes_key_bytes() * 8); 66 | #ifdef ZDEBUG 67 | std::cout << "seedbuf size = " <gen_rnd(rnd_seed, m_nSymSecParam); 87 | chan->send(rnd_seed, m_nSymSecParam); 88 | initRndMatrix(&rndmat, m_nBitLength, m_nBaseOTs); 89 | fillRndMatrix(rnd_seed, rndmat, m_nBitLength, m_nBaseOTs, m_cCrypt); 90 | free(rnd_seed); 91 | } 92 | 93 | while (otid < lim) //do while there are still transfers missing 94 | { 95 | processedOTBlocks = std::min(num_ot_blocks, ceil_divide(lim - otid, wd_size_bits)); 96 | OTsPerIteration = processedOTBlocks * wd_size_bits; 97 | processedOTs = std::min(lim - otid, OTsPerIteration); 98 | 99 | #ifdef ZDEBUG 100 | std::cout << "Processing block " << nProgress << " with length: " << OTsPerIteration << ", and limit: " << lim << std::endl; 101 | #endif 102 | 103 | #ifdef OTTiming 104 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 105 | #endif 106 | ReceiveMasks(&vRcv, chan, OTsPerIteration, 0); 107 | 108 | #ifdef OTTiming 109 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 110 | totalRcvTime += getMillies(tempStart, tempEnd); 111 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 112 | #endif 113 | BuildQMatrix(&Q, otid, processedOTBlocks, m_tBaseOTKeys.front()); 114 | #ifdef OTTiming 115 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 116 | totalMtxTime += getMillies(tempStart, tempEnd); 117 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 118 | #endif 119 | UnMaskBaseOTs(&Q, &vRcv, m_tBaseOTChoices.front(), processedOTBlocks); 120 | #ifdef OTTiming 121 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 122 | totalUnMaskTime += getMillies(tempStart, tempEnd); 123 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 124 | #endif 125 | Q.Transpose(wd_size_bits, OTsPerIteration); 126 | #ifdef OTTiming 127 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 128 | totalTnsTime += getMillies(tempStart, tempEnd); 129 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 130 | #endif 131 | KKHashValues(Q, seedbuf, vSnd, otid, processedOTs, rndmat); 132 | #ifdef OTTiming 133 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 134 | totalHshTime += getMillies(tempStart, tempEnd); 135 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 136 | #endif 137 | KKMaskAndSend(vSnd, otid, processedOTs, chan); 138 | #ifdef OTTiming 139 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 140 | totalSndTime += getMillies(tempStart, tempEnd); 141 | #endif 142 | otid += processedOTs; 143 | Q.Reset(); 144 | } 145 | 146 | vRcv.delCBitVector(); 147 | chan->synchronize_end(); 148 | 149 | Q.delCBitVector(); 150 | 151 | for (uint32_t i = 0; i < m_nint_sndvals; i++) { 152 | vSnd[i].delCBitVector(); 153 | seedbuf[i].delCBitVector(); 154 | } 155 | #ifndef ABY_OT 156 | delete[] vSnd; 157 | delete[] seedbuf; 158 | #endif 159 | if(m_eSndOTFlav==Snd_GC_OT) 160 | freeRndMatrix(rndmat, m_nBaseOTs); 161 | 162 | #ifdef OTTiming 163 | std::cout << "Sender time benchmark for performing " << myNumOTs << " OTs (" << lim-myStartPos1ooN << 164 | " 1ooN) on " << m_nBitLength << " bit strings" << std::endl; 165 | std::cout << "Time needed for: " << std::endl; 166 | std::cout << "\t Matrix Generation:\t" << totalMtxTime << " ms" << std::endl; 167 | std::cout << "\t Unmasking values:\t" << totalUnMaskTime << " ms" << std::endl; 168 | std::cout << "\t Sending Matrix:\t" << totalSndTime << " ms" << std::endl; 169 | std::cout << "\t Transposing Matrix:\t" << totalTnsTime << " ms" << std::endl; 170 | std::cout << "\t Hashing Matrix:\t" << totalHshTime << " ms" << std::endl; 171 | std::cout << "\t Receiving Values:\t" << totalRcvTime << " ms" << std::endl; 172 | #endif 173 | 174 | delete chan; 175 | 176 | return TRUE; 177 | } 178 | 179 | 180 | void KKOTExtSnd::ComputeBaseOTs(field_type ftype) { 181 | m_cBaseOT = new NaorPinkas(m_cCrypt, ftype); 182 | ComputePKBaseOTs(); 183 | delete m_cBaseOT; 184 | } 185 | 186 | 187 | 188 | void KKOTExtSnd::KKHashValues(CBitVector& Q, CBitVector* seedbuf, CBitVector* snd_buf, uint64_t OT_ptr, uint64_t OT_len, uint64_t** mat_mul) { 189 | uint32_t rowbytelen = bits_in_bytes(m_nBaseOTs); 190 | uint32_t hashinbytelen = rowbytelen + sizeof(uint64_t); 191 | uint32_t hashoutbitlen = ceil_log2(m_nint_sndvals); 192 | // uint64_t wd_size_bytes = m_nBlockSizeBytes;//1 << (ceil_log2(m_nBaseOTs) - 3); 193 | uint32_t u; 194 | uint32_t aes_key_bytes = m_cCrypt->get_aes_key_bytes(); 195 | 196 | uint32_t int_choicecodebits = ceil_log2(m_nint_sndvals); 197 | uint32_t ext_choicecodebits = ceil_log2(m_nSndVals); 198 | uint32_t diff_choicecodes = int_choicecodebits / ext_choicecodebits; 199 | 200 | uint64_t* Qptr = (uint64_t*) Q.GetArr(); 201 | 202 | uint8_t** sbp = (uint8_t**) malloc(sizeof(uint8_t*) * m_nint_sndvals); 203 | uint8_t* inbuf = (uint8_t*) calloc(hashinbytelen, 1); 204 | uint8_t* resbuf = (uint8_t*) calloc(m_cCrypt->get_hash_bytes(), 1); 205 | uint8_t* hash_buf = (uint8_t*) calloc(m_cCrypt->get_hash_bytes(), 1); 206 | 207 | uint64_t* tmpbuf = (uint64_t*) calloc(PadToMultiple(bits_in_bytes(m_nBitLength), sizeof(uint64_t)), 1); 208 | uint8_t* tmpbufb = (uint8_t*) calloc(bits_in_bytes(m_nBitLength), 1); 209 | 210 | #ifdef USE_PIPELINED_AES_NI 211 | AES_KEY tk_aeskey; 212 | block inblock, outblock; 213 | tk_aeskey.rounds = 14; 214 | uint32_t maskbytesize = rowbytelen * m_nint_sndvals; 215 | CBitVector refmask(maskbytesize * 8); 216 | for(u = 0; u < m_nint_sndvals; u++) { 217 | refmask.Copy(m_tBaseOTChoices.front()->GetArr(), u*rowbytelen, rowbytelen); 218 | refmask.ANDBytes((uint8_t*) m_vCodeWords[u], u*rowbytelen, rowbytelen); 219 | } 220 | CBitVector mask(maskbytesize * 8); 221 | uint64_t* global_OT_ptr = (uint64_t*) inbuf; 222 | *global_OT_ptr = OT_ptr + m_nCounter; 223 | #else 224 | CBitVector mask(m_nCodeWordBits); 225 | uint64_t global_OT_ptr = OT_ptr + m_nCounter; 226 | 227 | #endif 228 | 229 | 230 | for (u = 0; u < m_nint_sndvals; u++) 231 | sbp[u] = seedbuf[u].GetArr(); 232 | 233 | 234 | #ifdef USE_PIPELINED_AES_NI 235 | for (uint64_t i = 0; i < OT_len; (*global_OT_ptr)++, i++, Qptr += 2) { 236 | mask.Copy(refmask.GetArr(), 0, maskbytesize); 237 | for (u = 0; u < m_nint_sndvals; u++) { 238 | mask.XORBytes(Q.GetArr() + i * rowbytelen, u*rowbytelen, rowbytelen); 239 | 240 | AES_256_Key_Expansion(mask.GetArr() + u*rowbytelen, &tk_aeskey); 241 | inblock = _mm_loadu_si128((__m128i const*)(resbuf)); 242 | AES_encryptC(&inblock, &outblock, &tk_aeskey); 243 | _mm_storeu_si128((__m128i *)(sbp[u]), outblock); 244 | 245 | sbp[u]+=aes_key_bytes; 246 | } 247 | } 248 | #else 249 | for (uint64_t i = 0; i < OT_len; global_OT_ptr++, i++, Qptr += 2) { 250 | 251 | 252 | for (u = 0; u < m_nint_sndvals; u++) { 253 | mask.Copy(m_tBaseOTChoices.front()->GetArr(), 0, rowbytelen); 254 | mask.ANDBytes((uint8_t*) m_vCodeWords[u], 0, rowbytelen); 255 | mask.XORBytes(Q.GetArr() + i * rowbytelen, rowbytelen); 256 | 257 | #ifdef DEBUG_OT_HASH_IN 258 | std::cout << "Hash-In for i = " << global_OT_ptr << ", u = " << u << ": " << (std::hex); 259 | for(uint32_t p = 0; p < rowbytelen; p++) 260 | std::cout << std::setw(2) << std::setfill('0') << (uint32_t) mask.GetArr()[p]; 261 | std::cout << (std::dec) << std::endl; 262 | //std::cout << "Using codeword " << (std::hex) << m_vCodeWords[u][0] << m_vCodeWords[u][1] << (std::hex) << m_vCodeWords[u][2] << m_vCodeWords[u][3] << (std::dec) << std::endl; 263 | 264 | #endif 265 | 266 | if(m_eSndOTFlav != Snd_GC_OT) { 267 | memcpy(inbuf, &global_OT_ptr, sizeof(uint64_t)); 268 | //memcpy(inbuf+sizeof(uint64_t), Q.GetArr() + i * wd_size_bytes, rowbytelen); 269 | memcpy(inbuf+sizeof(uint64_t), mask.GetArr(), rowbytelen); 270 | m_cCrypt->hash_buf(resbuf, aes_key_bytes, inbuf, hashinbytelen, hash_buf); 271 | memcpy(sbp[u], resbuf, aes_key_bytes); 272 | //snd_buf[u].SetBits(resbuf, i * hashoutbitlen, hashoutbitlen); 273 | } else { 274 | //TODO: mecr has not been tested with KK-OT!! 275 | BitMatrixMultiplication(tmpbufb, bits_in_bytes(hashoutbitlen), mask.GetArr(), m_nBaseOTs, mat_mul, tmpbuf); 276 | //BitMatrixMultiplication(tmpbufb, bits_in_bytes(m_nBitLength), Q.GetArr() + i * wd_size_bytes, m_nBaseOTs, mat_mul, tmpbuf); 277 | //m_vValues[u].SetBits(tmpbufb, (OT_ptr + i)* m_nBitLength, m_nBitLength); 278 | snd_buf[u].SetBits(tmpbufb, i * hashoutbitlen, hashoutbitlen); 279 | //m_vTempOTMasks.SetBytes(tmpbufb, (uint64_t) (OT_ptr + i) * aes_key_bytes, (uint64_t) aes_key_bytes); 280 | //m_vValues[u].SetBytes(Q.GetArr() + i * wd_size_bytes, (OT_ptr + i)* wd_size_bytes, rowbytelen); 281 | } 282 | 283 | #ifdef DEBUG_OT_HASH_OUT 284 | std::cout << "Hash-Out for i = " << global_OT_ptr << ", u = " << u << ": " << (std::hex); 285 | for(uint32_t p = 0; p < aes_key_bytes; p++) 286 | std::cout << std::setw(2) << std::setfill('0') << (uint32_t) sbp[u][p]; 287 | std::cout << (std::dec) << std::endl; 288 | #endif 289 | sbp[u]+=m_cCrypt->get_aes_key_bytes(); 290 | } 291 | } 292 | #endif 293 | 294 | //TODO: difference is in here!! (could be solved by giving the bit-length as parameter in the function call) 295 | for (uint32_t u = 0; u < m_nint_sndvals; u++) { 296 | m_fMaskFct->expandMask(&snd_buf[u], seedbuf[u].GetArr(), 0, OT_len, m_nBitLength * diff_choicecodes, m_cCrypt); 297 | //std::cout << "Mask " << u << ": "; 298 | //snd_buf[u].PrintHex(); 299 | } 300 | 301 | //m_vValues[0].PrintHex(); 302 | //m_vValues[1].PrintHex(); 303 | 304 | free(resbuf); 305 | free(inbuf); 306 | free(sbp); 307 | free(hash_buf); 308 | free(tmpbuf); 309 | free(tmpbufb); 310 | } 311 | 312 | 313 | void KKOTExtSnd::KKMaskAndSend(CBitVector* snd_buf, uint64_t OT_ptr, uint64_t OT_len, channel* chan) { 314 | //m_fMaskFct->Mask(OT_ptr, OT_len, m_vValues, snd_buf, m_eSndOTFlav); 315 | 316 | uint32_t int_choicecodebits = ceil_log2(m_nint_sndvals); 317 | uint32_t ext_choicecodebits = ceil_log2(m_nSndVals); 318 | uint32_t diff_choicecodes = int_choicecodebits / ext_choicecodebits; 319 | uint64_t valsize = bits_in_bytes(OT_len * m_nBitLength * diff_choicecodes); 320 | uint64_t bufsize = 0; 321 | uint8_t* buf = nullptr; 322 | uint32_t startval = 0; 323 | uint32_t endval = 0; 324 | uint32_t offset = m_nint_sndvals; 325 | 326 | 327 | if(m_eSndOTFlav == Snd_OT) { 328 | bufsize = valsize * m_nint_sndvals; 329 | startval = 0; 330 | endval = m_nint_sndvals; 331 | } else if (m_eSndOTFlav == Snd_C_OT) { 332 | bufsize = valsize * (m_nint_sndvals - 1); 333 | startval = 1; 334 | endval = m_nint_sndvals; 335 | //hack: extract the delta from the masking function and set m_vValues[0] randomly and m_vValues[1] = m_vValues[0] \oplus Delta 336 | // snd_buf[1] is modified and has to be XORed with m_vValues[1] to revert to the original value 337 | m_fMaskFct->Mask(OT_ptr*diff_choicecodes, OT_len*diff_choicecodes, m_vValues, snd_buf, m_eSndOTFlav); 338 | snd_buf[1].XORBits(m_vValues[1]->GetArr() + bits_in_bytes(OT_ptr*diff_choicecodes*m_nBitLength), 0, OT_len*diff_choicecodes * m_nBitLength); 339 | } else if(m_eSndOTFlav == Snd_R_OT) { 340 | bufsize = valsize * (m_nint_sndvals - m_nSndVals); 341 | startval = 1; 342 | endval = m_nint_sndvals - 1; 343 | offset = endval / (m_nSndVals-1); 344 | for(uint32_t i = 0, ctr = 0; i < m_nSndVals && ctr < m_nint_sndvals; i++, ctr+=offset) { 345 | m_vValues[i]->SetBytes(snd_buf[ctr].GetArr(), bits_in_bytes(OT_ptr * diff_choicecodes * m_nBitLength), valsize); 346 | } 347 | //Define the X0 values as the output of 0 and the X(m_nSndVals-1) values as output of m_nint_sndvals-1 (only 1 values) 348 | //m_vValues[0]->SetBytes(snd_buf[0].GetArr(), bits_in_bytes(OT_ptr * diff_choicecodes * m_nBitLength), valsize); 349 | //m_vValues[m_nSndVals - 1]->SetBytes(snd_buf[m_nint_sndvals-1].GetArr(), bits_in_bytes(OT_ptr * diff_choicecodes * m_nBitLength), valsize); 350 | } 351 | 352 | buf = (uint8_t*) malloc(bufsize); 353 | CBitVector tmpmask(valsize * 8); 354 | CBitVector* snd_buf_ptr; 355 | 356 | //m_vValues[0]->SetBytes(snd_buf[0].GetArr(), bits_in_bytes(OT_ptr * choicecodebits * m_nBitLength), valsize); 357 | //m_vValues[1]->SetBytes(snd_buf[m_nint_sndvals-1].GetArr(), bits_in_bytes(OT_ptr * choicecodebits * m_nBitLength), valsize); 358 | 359 | #ifdef DEBUG_KK_OTBREAKDOWN 360 | std::cout << std::endl; 361 | for(uint32_t i = 0; i < m_nSndVals; i++) { 362 | std::cout << "X" << i<< ": "; 363 | m_vValues[i]->PrintHex(0, valsize); 364 | } 365 | #endif 366 | 367 | uint8_t* tmpbuf = (uint8_t*) malloc(bits_in_bytes(m_nBitLength)); 368 | uint32_t valaddr; 369 | for(uint32_t i = startval, ctr = 0; i < endval; i++) {//iteration from 1 to N 370 | if(ceil_divide(i, offset) * offset != i || i == 0) { 371 | tmpmask.Reset(); 372 | for(uint32_t j = 0; j < diff_choicecodes; j++) { //iteration over all bit positions 373 | //write the value of snd_buf[0] or snd_buf[1] in every choicecodebits position 374 | valaddr = ((i>>(j*ext_choicecodebits)) & (m_nSndVals-1)); 375 | snd_buf_ptr = m_vValues[valaddr]; 376 | //std::cout << "Taking value " << ((i>>(j*ext_choicecodebits)) & (m_nSndVals-1)) << " for i = " << i << std::endl; 377 | 378 | for(uint32_t o = 0; o < OT_len; o++) { //iterations over all OTs 379 | //reset tmpbuf 380 | memset(tmpbuf, 0, bits_in_bytes(m_nBitLength)); 381 | //get the bits of the required OT. TODO: adapt the j when the quotient is not an int 382 | snd_buf_ptr->GetBits(tmpbuf, (OT_ptr+o)*diff_choicecodes*m_nBitLength+j*m_nBitLength, m_nBitLength); 383 | //write the copied bits into tmpmask for later XORing 384 | tmpmask.SetBits(tmpbuf, o*diff_choicecodes*m_nBitLength+j*m_nBitLength, m_nBitLength); 385 | } 386 | } 387 | #ifdef DEBUG_KK_OTBREAKDOWN 388 | std::cout << "Val " << i << ": "; 389 | tmpmask.PrintHex(0, valsize); 390 | std::cout << "Mask " << i << ": "; 391 | snd_buf[i].PrintHex(0, valsize); 392 | #endif 393 | tmpmask.XORBytes(snd_buf[i].GetArr(), 0, valsize); 394 | #ifdef DEBUG_KK_OTBREAKDOWN 395 | std::cout << "Res " << i << ": "; 396 | tmpmask.PrintHex(0, valsize); 397 | #endif 398 | 399 | memcpy(buf + ctr * valsize, tmpmask.GetArr(), valsize); 400 | ctr++; 401 | } 402 | } 403 | 404 | chan->send_id_len(buf, bufsize, OT_ptr, OT_len); 405 | free(buf); 406 | free(tmpbuf); 407 | tmpmask.delCBitVector(); 408 | } 409 | -------------------------------------------------------------------------------- /ot/kk-ot-ext-snd.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file kk-ot-ext-snd.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | #ifndef KK_OT_EXT_SENDER_H_ 20 | #define KK_OT_EXT_SENDER_H_ 21 | 22 | #include "ot-ext-snd.h" 23 | #include "kk-ot-ext.h" 24 | 25 | class KKOTExtSnd : public OTExtSnd, public KKOTExt { 26 | 27 | public: 28 | KKOTExtSnd(crypto* crypt, RcvThread* rcvthread, SndThread* sndthread, uint64_t num_ot_blocks=4096, bool verify_ot=true, bool use_fixed_key_aes_hashing=false) 29 | : OTExtSnd(num_ot_blocks, verify_ot, use_fixed_key_aes_hashing) { 30 | uint32_t numbaseots = 2*crypt->get_seclvl().symbits; 31 | 32 | //assert(pad_to_power_of_two(nSndVals) == nSndVals); //TODO right now only supports power of two nSndVals 33 | assert(numbaseots == 256); //TODO: right now only 256 base OTs work due to the size of the code 34 | InitSnd(crypt, rcvthread, sndthread, 2*crypt->get_seclvl().symbits); 35 | //Initialize the code words 36 | InitAndReadCodeWord(&m_vCodeWords); 37 | } 38 | ; 39 | 40 | 41 | virtual ~KKOTExtSnd() { 42 | } 43 | ; 44 | 45 | BOOL sender_routine(uint32_t threadid, uint64_t numOTs); 46 | void ComputeBaseOTs(field_type ftype); 47 | 48 | private: 49 | void KKHashValues(CBitVector& Q, CBitVector* seedbuf, CBitVector* snd_buf, uint64_t OT_ptr, uint64_t OT_len, uint64_t** mat_mul); 50 | void KKMaskAndSend(CBitVector* snd_buf, uint64_t OT_ptr, uint64_t OT_len, channel* chan); 51 | //uint64_t** m_vCodeWords; 52 | }; 53 | 54 | 55 | 56 | #endif /* KK_OT_EXT_SENDER_H_ */ 57 | -------------------------------------------------------------------------------- /ot/kk-ot-ext.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file kk-ot-ext.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #ifndef KK_OT_EXT_H_ 24 | #define KK_OT_EXT_H_ 25 | 26 | class KKOTExt { 27 | public: 28 | virtual ~KKOTExt() { 29 | for(size_t i = 0; i < m_nCodeWordBits; i++) { 30 | free(m_vCodeWords[i]); 31 | } 32 | free(m_vCodeWords); 33 | } 34 | 35 | protected: 36 | void set_internal_sndvals(uint32_t ext_sndvals, uint32_t bitlen) { 37 | uint32_t min_int; 38 | double tmp_cost, min_cost, tmp_log; 39 | assert(ext_sndvals <= 256); 40 | min_cost = DBL_MAX; 41 | for(uint32_t i = ext_sndvals; i <= 256; i*=ext_sndvals) { 42 | tmp_log = ((double) ceil_log2(i)) / ((double) ceil_log2(ext_sndvals)); 43 | tmp_cost = (256 + i * bitlen * tmp_log) / tmp_log; 44 | //cout << "cost for i = " << i << ": " << tmp_cost << ", log fact = " << tmp_log << ", min_cost = " << min_cost << endl; 45 | if(tmp_cost < min_cost) { 46 | min_int = i; 47 | min_cost = tmp_cost; 48 | } 49 | } 50 | m_nint_sndvals = min_int; 51 | //cout << "Internally computing 1-out-of-" << m_nint_sndvals << " for external " << ext_sndvals << endl; 52 | } 53 | uint32_t m_nint_sndvals; 54 | uint64_t** m_vCodeWords; 55 | }; 56 | 57 | #endif /* KK_OT_EXT_H_ */ 58 | -------------------------------------------------------------------------------- /ot/maskingfunction.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file maskingfunction.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief Masking Function implementation. 17 | */ 18 | 19 | #ifndef MASKINGFUNCTION_H_ 20 | #define MASKINGFUNCTION_H_ 21 | 22 | #include 23 | #include 24 | #include "OTconstants.h" 25 | 26 | class MaskingFunction { 27 | 28 | public: 29 | MaskingFunction() { 30 | } 31 | ; 32 | virtual ~MaskingFunction() { 33 | } 34 | ; 35 | 36 | virtual void Mask(uint32_t progress, uint32_t len, CBitVector** values, CBitVector* snd_buf, snd_ot_flavor protocol) = 0; 37 | virtual void UnMask(uint32_t progress, uint32_t len, CBitVector* choices, CBitVector* output, CBitVector* rcv_buf, CBitVector* tmpmask, snd_ot_flavor version) = 0; 38 | virtual void expandMask(CBitVector* out, BYTE* sbp, uint32_t offset, uint32_t processedOTs, uint32_t bitlength, crypto* crypt) = 0; 39 | 40 | protected: 41 | 42 | }; 43 | 44 | #endif /* MASKINGFUNCTION_H_ */ 45 | -------------------------------------------------------------------------------- /ot/naor-pinkas.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file naor-pinkas.cpp 3 | \author 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see ._______________ 16 | \brief naor-pinkas implementation. 17 | */ 18 | 19 | #include "naor-pinkas.h" 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | void NaorPinkas::Receiver(uint32_t nSndVals, uint32_t nOTs, CBitVector* choices, channel* chan, uint8_t* ret) { 27 | 28 | fe* PK0 = m_cPKCrypto->get_fe(); 29 | fe** PK_sigma = (fe**) malloc(sizeof(fe*) * nOTs); 30 | fe** pDec = (fe**) malloc(sizeof(fe*) * nOTs); 31 | num** pK = (num**) malloc(sizeof(num*) * nOTs); 32 | 33 | fe** pC = (fe**) malloc(sizeof(fe*) * nSndVals); 34 | fe* g = m_cPKCrypto->get_generator(); 35 | 36 | 37 | uint8_t* retPtr; 38 | uint32_t u, k, choice, hash_bytes, fe_bytes; 39 | hash_bytes = m_cCrypto->get_hash_bytes(); 40 | fe_bytes = m_cPKCrypto->fe_byte_size(); 41 | 42 | brickexp *bg, *bc; 43 | bg = m_cPKCrypto->get_brick(g); 44 | 45 | // uint8_t* pBuf = (uint8_t*) malloc(nOTs * fe_bytes); 46 | // uint32_t nBufSize = nSndVals * fe_bytes; 47 | 48 | 49 | //calculate the generator of the group 50 | for (k = 0; k < nOTs; k++) { 51 | PK_sigma[k] = m_cPKCrypto->get_fe(); 52 | pK[k] = m_cPKCrypto->get_rnd_num(); 53 | 54 | bg->pow(PK_sigma[k], pK[k]); 55 | } 56 | 57 | uint8_t* pBuf = chan->blocking_receive(); 58 | uint8_t* pBufIdx = pBuf; 59 | 60 | for (u = 0; u < nSndVals; u++) { 61 | pC[u] = m_cPKCrypto->get_fe(); 62 | pC[u]->import_from_bytes(pBufIdx); 63 | pBufIdx += fe_bytes; 64 | } 65 | 66 | bc = m_cPKCrypto->get_brick(pC[0]); 67 | 68 | //==================================================== 69 | // N-P receiver: send pk0 70 | free(pBuf); 71 | pBuf = (uint8_t*) malloc(nOTs * fe_bytes); 72 | pBufIdx = pBuf; 73 | for (k = 0; k < nOTs; k++) { 74 | choice = choices->GetBit((int32_t) k); 75 | if (choice != 0) { 76 | PK0->set_div(pC[choice], PK_sigma[k]); 77 | } else { 78 | PK0->set(PK_sigma[k]); 79 | } 80 | PK0->export_to_bytes(pBufIdx); 81 | pBufIdx += fe_bytes; 82 | } 83 | 84 | //socket->Send(pBuf, nOTs * fe_bytes); 85 | chan->send(pBuf, nOTs * fe_bytes); 86 | 87 | free(pBuf); 88 | pBuf = (uint8_t*) malloc(fe_bytes); 89 | retPtr = ret; 90 | 91 | for (k = 0; k < nOTs; k++) { 92 | pDec[k] = m_cPKCrypto->get_fe(); 93 | bc->pow(pDec[k], pK[k]); 94 | pDec[k]->export_to_bytes(pBuf); 95 | 96 | hashReturn(retPtr, hash_bytes, pBuf, fe_bytes, k); 97 | retPtr += hash_bytes; 98 | 99 | } 100 | 101 | delete bc; 102 | delete bg; 103 | 104 | free(pBuf); 105 | for(uint32_t i = 0; i < nOTs; i++) { 106 | delete PK_sigma[i]; 107 | delete pDec[i]; 108 | delete pK[i]; 109 | } 110 | free(PK_sigma); 111 | free(pDec); 112 | free(pK); 113 | 114 | for(uint32_t i = 0; i < nSndVals; i++) { 115 | delete pC[i]; 116 | } 117 | free(pC); 118 | 119 | delete PK0; 120 | delete g; 121 | 122 | } 123 | 124 | void NaorPinkas::Sender(uint32_t nSndVals, uint32_t nOTs, channel* chan, uint8_t* ret) { 125 | num *alpha, *PKr, *tmp; 126 | fe **pCr, **pC, *fetmp, *PK0r, *g, **pPK0; 127 | uint8_t* pBuf, *pBufIdx; 128 | uint32_t hash_bytes, fe_bytes, nBufSize, u, k; 129 | 130 | hash_bytes = m_cCrypto->get_hash_bytes(); 131 | fe_bytes = m_cPKCrypto->fe_byte_size(); 132 | 133 | alpha = m_cPKCrypto->get_rnd_num(); 134 | PKr = m_cPKCrypto->get_num(); 135 | 136 | pCr = (fe**) malloc(sizeof(fe*) * nSndVals); 137 | pC = (fe**) malloc(sizeof(fe*) * nSndVals); 138 | 139 | PK0r = m_cPKCrypto->get_fe(); 140 | pC[0] = m_cPKCrypto->get_fe(); 141 | g = m_cPKCrypto->get_generator(); 142 | 143 | //random C1 144 | pC[0]->set_pow(g, alpha); 145 | 146 | //random C(i+1) 147 | for (u = 1; u < nSndVals; u++) { 148 | pC[u] = m_cPKCrypto->get_fe(); 149 | tmp = m_cPKCrypto->get_rnd_num(); 150 | pC[u]->set_pow(g, tmp); 151 | delete tmp; 152 | } 153 | 154 | //==================================================== 155 | // Export the generated C_1-C_nSndVals to a uint8_t vector and send them to the receiver 156 | nBufSize = nSndVals * fe_bytes; 157 | pBuf = (uint8_t*) malloc(nBufSize); 158 | pBufIdx = pBuf; 159 | for (u = 0; u < nSndVals; u++) { 160 | pC[u]->export_to_bytes(pBufIdx); 161 | pBufIdx += fe_bytes; 162 | } 163 | chan->send(pBuf, nBufSize); 164 | 165 | //==================================================== 166 | // compute C^R 167 | for (u = 1; u < nSndVals; u++) { 168 | pCr[u] = m_cPKCrypto->get_fe(); 169 | pCr[u]->set_pow(pC[u], alpha); 170 | } 171 | //==================================================== 172 | 173 | free(pBuf); 174 | // N-P sender: receive pk0 175 | nBufSize = fe_bytes * nOTs; 176 | pBuf = chan->blocking_receive();//pBuf, nBufSize); 177 | 178 | pBufIdx = pBuf; 179 | 180 | pPK0 = (fe**) malloc(sizeof(fe*) * nOTs); 181 | for (k = 0; k < nOTs; k++) { 182 | pPK0[k] = m_cPKCrypto->get_fe(); 183 | pPK0[k]->import_from_bytes(pBufIdx); 184 | pBufIdx += fe_bytes; 185 | } 186 | 187 | //==================================================== 188 | // Write all nOTs * nSndVals possible values to ret 189 | free(pBuf); 190 | pBuf = (uint8_t*) malloc(sizeof(uint8_t) * fe_bytes * nSndVals); 191 | uint8_t* retPtr = ret; 192 | fetmp = m_cPKCrypto->get_fe(); 193 | 194 | for (k = 0; k < nOTs; k++) { 195 | pBufIdx = pBuf; 196 | for (u = 0; u < nSndVals; u++) { 197 | 198 | if (u == 0) { 199 | // pk0^r 200 | PK0r->set_pow(pPK0[k], alpha); 201 | PK0r->export_to_bytes(pBufIdx); 202 | 203 | } else { 204 | // pk^r 205 | fetmp->set_div(pCr[u], PK0r); 206 | fetmp->export_to_bytes(pBufIdx); 207 | } 208 | hashReturn(retPtr, hash_bytes, pBufIdx, fe_bytes, k); 209 | pBufIdx += fe_bytes; 210 | retPtr += hash_bytes; 211 | } 212 | 213 | } 214 | 215 | free(pBuf); 216 | 217 | for(uint32_t i = 0; i < nSndVals; i++) { 218 | delete pC[i]; 219 | if(i > 0) 220 | delete pCr[i]; 221 | } 222 | free(pCr); 223 | free(pC); 224 | 225 | for(uint32_t i = 0; i < nOTs; i++) { 226 | delete pPK0[i]; 227 | } 228 | free(pPK0); 229 | 230 | 231 | delete alpha; 232 | delete PKr; 233 | delete fetmp; 234 | delete PK0r; 235 | delete g; 236 | } 237 | -------------------------------------------------------------------------------- /ot/naor-pinkas.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file naor-pinkas.h 3 | \author 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see ._______________ 16 | \brief naor-pinkas implementation. 17 | */ 18 | 19 | #ifndef __Naor_Pinkas_H_ 20 | #define __Naor_Pinkas_H_ 21 | 22 | #include "baseOT.h" 23 | 24 | class NaorPinkas : public BaseOT { 25 | 26 | public: 27 | 28 | NaorPinkas(crypto* crypt, field_type ftype) : 29 | BaseOT(crypt, ftype) { 30 | } 31 | ; 32 | 33 | void Receiver(uint32_t nSndVals, uint32_t nOTs, CBitVector* choices, channel* chan, BYTE* ret); 34 | void Sender(uint32_t nSndVals, uint32_t nOTs, channel* chan, BYTE* ret); 35 | 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /ot/naor-pinkas_noro.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file naor-pinkas_noro.cpp 3 | \author 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | #include "naor-pinkas_noro.h" 20 | 21 | /*#ifdef OTEXT_USE_GMP 22 | 23 | BOOL NaorPinkasNoRO::ReceiverIFC(int nSndVals, int nOTs, CBitVector& choices, CSocket& socket, BYTE* ret) 24 | { 25 | //needs to store x 26 | int nBufSize = m_NPState.field_size; 27 | BYTE* pBuf = new BYTE[nBufSize]; 28 | 29 | 30 | mpz_t a, b[nOTs], x, y, z0, z1, ztmp, w; 31 | 32 | mpz_init(ztmp); 33 | mpz_init(a); 34 | mpz_init(x); 35 | mpz_init(z0); 36 | mpz_init(z1); 37 | mpz_init(w); 38 | mpz_init(y); 39 | 40 | //Fixed Point Exponentiation of the generator g 41 | FixedPointExp brg(m_NPState.g, m_NPState.p, m_NPState.field_size*8); 42 | 43 | //Fix a and precompute g^a 44 | mpz_urandomb(ztmp, m_NPState.rnd_state, m_NPState.field_size*8); 45 | mpz_mod(a, ztmp, m_NPState.q); 46 | brg.powerMod(x, a); 47 | 48 | //export and send x 49 | mpz_export_padded(pBuf, m_NPState.field_size, x); 50 | socket.Send(pBuf, nBufSize); 51 | 52 | delete pBuf; 53 | nBufSize = 3*nOTs*m_NPState.field_size; 54 | pBuf = new BYTE[nBufSize]; 55 | 56 | //Fixed Point Exponentiation of x = g^a 57 | FixedPointExp brx(x, m_NPState.p, m_NPState.field_size*8); 58 | 59 | BYTE* pBufIdx = pBuf; 60 | for(int k = 0; k < nOTs; k++) 61 | { 62 | //randomly sample b and compute y 63 | mpz_init(b[k]); 64 | mpz_urandomb(ztmp, m_NPState.rnd_state, m_NPState.field_size*8); 65 | mpz_mod(b[k], ztmp, m_NPState.q); 66 | brg.powerMod(y, b[k]); 67 | 68 | //compute z0 and z1, depending on the choice bits 69 | mpz_urandomb(ztmp, m_NPState.rnd_state, m_NPState.field_size*8); 70 | mpz_mod(ztmp, ztmp, m_NPState.q); 71 | if(!choices.GetBit(k)) 72 | { 73 | brx.powerMod(z0, b[k]); 74 | brg.powerMod(z1, ztmp); 75 | 76 | } else 77 | { 78 | brg.powerMod(z0, ztmp); 79 | brx.powerMod(z1, b[k]); 80 | } 81 | 82 | //export - first y, then z0, and lastly z1 83 | mpz_export_padded(pBufIdx, m_NPState.field_size, y); 84 | pBufIdx += m_NPState.field_size; 85 | mpz_export_padded(pBufIdx, m_NPState.field_size, z0); 86 | pBufIdx += m_NPState.field_size; 87 | mpz_export_padded(pBufIdx, m_NPState.field_size, z1); 88 | pBufIdx += m_NPState.field_size; 89 | } 90 | 91 | int nRecvBufSize = 2 * nOTs * m_NPState.field_size; 92 | BYTE* pRecvBuf = new BYTE[nRecvBufSize]; 93 | socket.Receive(pRecvBuf, nRecvBufSize); 94 | 95 | 96 | socket.Send(pBuf, nBufSize); 97 | 98 | BYTE* retPtr = ret; 99 | pBufIdx = pRecvBuf; 100 | for(int k = 0; k < nOTs; k++) 101 | { 102 | //if the choice bit is zero take the first value, else the second 103 | mpz_import(w, m_NPState.field_size, 1, sizeof(pBuf[0]), 0, 0, pBufIdx+(choices.GetBit(k) * m_NPState.field_size)); 104 | 105 | //compute w_sigma^b 106 | mpz_powm(ztmp, w, b[k], m_NPState.p); 107 | 108 | //export result and hash 109 | mpz_export_padded(pBufIdx, m_NPState.field_size, ztmp); 110 | hashReturn(retPtr, pBufIdx, m_NPState.field_size, k); 111 | 112 | retPtr += SHA1_BYTES; 113 | 114 | //Skip the next two values 115 | pBufIdx += 2*m_NPState.field_size; 116 | } 117 | 118 | return true; 119 | } 120 | 121 | BOOL NaorPinkasNoRO::SenderIFC(int nSndVals, int nOTs, CSocket& socket, BYTE* ret) 122 | { 123 | //needs to store x, nOTs*y, nOTs*z0, and nOTs*z1 124 | int nBufSize = m_NPState.field_size; 125 | 126 | BYTE* pBuf = new BYTE[nBufSize]; 127 | 128 | mpz_t w0, w1, s0[nOTs], s1[nOTs], r0[nOTs], r1[nOTs], R0, R1, x, y, Y, Z0, Z1, z0, z1, ztmp, w; 129 | 130 | mpz_init(ztmp); 131 | mpz_init(x); 132 | mpz_init(y); 133 | mpz_init(z0); 134 | mpz_init(z1); 135 | mpz_init(w0); 136 | mpz_init(w1); 137 | mpz_init(R0); 138 | mpz_init(R1); 139 | mpz_init(Y); 140 | mpz_init(Z0); 141 | mpz_init(Z1); 142 | 143 | //Fixed Point Exponentiation of the generator g and precompute all possible values 144 | FixedPointExp brg(m_NPState.g, m_NPState.p, m_NPState.field_size*8); 145 | 146 | socket.Receive(pBuf, nBufSize); 147 | //import x and compute fixed Point Exponentiation of x 148 | mpz_import(x, m_NPState.field_size, 1, sizeof(pBuf[0]), 0, 0, pBuf); 149 | FixedPointExp brx(x, m_NPState.p, m_NPState.field_size*8); 150 | 151 | delete pBuf; 152 | nBufSize = 2*nOTs * m_NPState.field_size; 153 | pBuf = new BYTE[nBufSize]; 154 | 155 | BYTE* pBufIdx = pBuf; 156 | for(int k = 0; k < nOTs; k++) 157 | { 158 | mpz_init(r0[k]); 159 | mpz_init(r1[k]); 160 | mpz_init(s0[k]); 161 | mpz_init(s1[k]); 162 | 163 | mpz_urandomb(ztmp, m_NPState.rnd_state, m_NPState.field_size*8); 164 | mpz_mod(s0[k], ztmp, m_NPState.q); 165 | mpz_urandomb(ztmp, m_NPState.rnd_state, m_NPState.field_size*8); 166 | mpz_mod(s1[k], ztmp, m_NPState.q); 167 | 168 | mpz_urandomb(ztmp, m_NPState.rnd_state, m_NPState.field_size*8); 169 | mpz_mod(r0[k], ztmp, m_NPState.q); 170 | mpz_urandomb(ztmp, m_NPState.rnd_state, m_NPState.field_size*8); 171 | mpz_mod(r1[k], ztmp, m_NPState.q); 172 | 173 | //compute w0 and export it 174 | brx.powerMod(ztmp, s0[k]); 175 | brg.powerMod(R0, r0[k]); 176 | mpz_mul(w0, ztmp, R0); 177 | mpz_mod(w0, w0, m_NPState.p); 178 | mpz_export_padded(pBufIdx, m_NPState.field_size, w0); 179 | pBufIdx += m_NPState.field_size; 180 | 181 | //compute w1 and export it 182 | brx.powerMod(ztmp, s1[k]); 183 | brg.powerMod(R1, r1[k]); 184 | mpz_mul(w1, ztmp, R1); 185 | mpz_mod(w1, w1, m_NPState.p); 186 | mpz_export_padded(pBufIdx, m_NPState.field_size, w1); 187 | pBufIdx += m_NPState.field_size; 188 | } 189 | 190 | //Send data off 191 | socket.Send(pBuf, nBufSize); 192 | 193 | delete pBuf; 194 | nBufSize = 3*nOTs * m_NPState.field_size; 195 | pBuf = new BYTE[nBufSize]; 196 | 197 | //Receive new data 198 | socket.Receive(pBuf, nBufSize); 199 | 200 | BYTE* retPtr = ret; 201 | pBufIdx = pBuf; 202 | for(int k = 0; k < nOTs; k++) 203 | { 204 | //get y, z0, and z1 205 | mpz_import(y, m_NPState.field_size, 1, sizeof(pBuf[0]), 0, 0, pBufIdx); 206 | pBufIdx += m_NPState.field_size; 207 | mpz_import(z0, m_NPState.field_size, 1, sizeof(pBuf[0]), 0, 0, pBufIdx); 208 | pBufIdx += m_NPState.field_size; 209 | mpz_import(z1, m_NPState.field_size, 1, sizeof(pBuf[0]), 0, 0, pBufIdx); 210 | 211 | //compute first possible hash 212 | mpz_powm(Y, y, r0[k], m_NPState.p); 213 | mpz_powm(Z0, z0, s0[k], m_NPState.p); 214 | mpz_mul(ztmp, Y, Z0); 215 | mpz_mod(ztmp, ztmp, m_NPState.p); 216 | //powmod2(ztmp, y, r0[k], z0, s0[k], m_NPState.p); 217 | 218 | //export result and hash 219 | mpz_export_padded(pBufIdx, m_NPState.field_size, ztmp); 220 | hashReturn(retPtr, pBufIdx, m_NPState.field_size, k); 221 | retPtr += SHA1_BYTES; 222 | 223 | 224 | //compute second possible hash 225 | mpz_powm(Y, y, r1[k], m_NPState.p); 226 | mpz_powm(Z1, z1, s1[k], m_NPState.p); 227 | mpz_mul(ztmp, Y, Z1); 228 | mpz_mod(ztmp, ztmp, m_NPState.p); 229 | //powmod2(ztmp, y, r1[k], z1, s1[k], m_NPState.p); 230 | 231 | //export result and hash 232 | mpz_export_padded(pBufIdx, m_NPState.field_size, ztmp); 233 | hashReturn(retPtr, pBufIdx, m_NPState.field_size, k); 234 | retPtr += SHA1_BYTES; 235 | 236 | 237 | pBufIdx += m_NPState.field_size; 238 | } 239 | 240 | 241 | return true; 242 | } 243 | #endif*/ 244 | 245 | 246 | void NaorPinkasNoRO::Receiver(uint32_t nSndVals, uint32_t nOTs, CBitVector* choices, channel* chan, BYTE* ret) 247 | { 248 | /*num *a, **b, *btmp; //Big a, b[nOTs], btmp, xtmp, ytmp; 249 | fe *g, *x, *y, *w, *z0, *z1, *tmp; //EC2 g, x, y, w, z0, z1; 250 | brickexp *bg, *bx;//ebrick2 bg, bx; 251 | 252 | uint32_t hashbytes = m_cCrypto->get_hash_bytes(); 253 | uint32_t febytelen = m_cPKCrypto->fe_byte_size(); 254 | 255 | g = m_cPKCrypto->get_generator();// Miracl_InitPoint(&g, *m_X, *m_Y);//g = EC2(*m_X ,*m_Y); 256 | b = (num**) malloc(sizeof(num*) * nOTs); 257 | bg = m_cPKCrypto->get_brick(g); //Miracl_InitBrick(&bg, &g); 258 | 259 | x = m_cPKCrypto->get_fe(); 260 | y = m_cPKCrypto->get_fe(); 261 | w = m_cPKCrypto->get_fe(); 262 | z0 = m_cPKCrypto->get_fe(); 263 | z1 = m_cPKCrypto->get_fe(); 264 | tmp = m_cPKCrypto->get_fe(); 265 | 266 | //needs to store x 267 | uint32_t nBufSize = febytelen; //(coordSize + 1); 268 | uint8_t* pBuf = (uint8_t*) malloc(nBufSize); 269 | 270 | //Fix a and precompute g^a 271 | a = m_cPKCrypto->get_rnd_num();//rand(m_SecParam, 2); 272 | bg->pow(x, a);//Miracl_mulbrick(&bg, a.getbig(), xtmp.getbig(), ytmp.getbig()); 273 | //Miracl_InitPoint(&x, xtmp, ytmp);//x = EC2(xtmp, ytmp); 274 | //epoint2_set(xtmp.getbig(), ytmp.getbig(), 0, x.get_point());//x.get(xtmp, ytmp); 275 | //x = g; 276 | //x *= a; 277 | 278 | //export and send x 279 | x->export_to_bytes(pBuf);//PointToByteArray(pBuf, coordSize, x); 280 | sock->Send(pBuf, nBufSize); 281 | 282 | free(pBuf);//delete pBuf; 283 | nBufSize = 3*nOTs*febytelen;// *(coordSize + 1); 284 | pBuf = (uint8_t*) malloc(nBufSize);//new BYTE[nBufSize]; 285 | 286 | bx = m_cPKCrypto->get_brick(x);//Miracl_InitBrick(&bx, &x); 287 | 288 | uint8_t* pBufIdx = pBuf; 289 | 290 | for(uint32_t k = 0; k < nOTs; k++) 291 | { 292 | //randomly sample b and compute y 293 | b[k] = m_cPKCrypto->get_rnd_num();//rand(m_SecParam, 2); 294 | bg->pow(y, b[k]);//Miracl_mulbrick(&bg, b[k].getbig(), xtmp.getbig(), ytmp.getbig()); 295 | //Miracl_InitPoint(&y, xtmp, ytmp);//y = EC2(xtmp, ytmp);//epoint2_set(xtmp.getbig(), ytmp.getbig(), 0, y.get_point());//y = ECn(xtmp, ytmp); 296 | 297 | //compute z0 and z1, depending on the choice bits 298 | btmp = m_cPKCrypto->get_rnd_num();//rand(m_SecParam, 2); 299 | 300 | if(!choices.GetBit(k)) 301 | { 302 | bx->pow(z0, b[k]);//Miracl_mulbrick(&bx, b[k].getbig(), xtmp.getbig(), ytmp.getbig()); 303 | //Miracl_InitPoint(&z0, xtmp, ytmp);//z0 = EC2(xtmp, ytmp);//epoint2_set(xtmp.getbig(), ytmp.getbig(), 0, z0.get_point());//z0 = ECn(xtmp, ytmp); 304 | bg->pow(z1, btmp);//Miracl_mulbrick(&bg, btmp.getbig(), xtmp.getbig(), ytmp.getbig()); 305 | //Miracl_InitPoint(&z1, xtmp, ytmp);//z1 = EC2(xtmp, ytmp);//epoint2_set(xtmp.getbig(), ytmp.getbig(), 0, z1.get_point());//z1 = ECn(xtmp, ytmp); 306 | } 307 | else 308 | { 309 | bg->pow(z0, btmp);//Miracl_mulbrick(&bg, btmp.getbig(), xtmp.getbig(), ytmp.getbig()); 310 | //Miracl_InitPoint(&z0, xtmp, ytmp);//z0 = EC2(xtmp, ytmp);//epoint2_set(xtmp.getbig(), ytmp.getbig(), 0, z0.get_point());//z0 = ECn(xtmp, ytmp);//z0.get(xtmp, ytmp); 311 | bx->pow(z1, b[k]);//Miracl_mulbrick(&bx, b[k].getbig(), xtmp.getbig(), ytmp.getbig()); 312 | //Miracl_InitPoint(&z1, xtmp, ytmp);//z1 = EC2(xtmp, ytmp);//epoint2_set(xtmp.getbig(), ytmp.getbig(), 0, z1.get_point());//z1 = ECn(xtmp, ytmp); 313 | } 314 | 315 | //export - first y, then z0, and lastly z1 316 | y->export_to_bytes(pBufIdx);//PointToByteArray(pBufIdx, coordSize, y); 317 | pBufIdx += febytelen;//(coordSize + 1); 318 | z0->export_to_bytes(pBufIdx);//PointToByteArray(pBufIdx, coordSize, z0); 319 | pBufIdx += febytelen;//(coordSize + 1); 320 | z1->export_to_bytes(pBufIdx);//PointToByteArray(pBufIdx, coordSize, z1); 321 | pBufIdx += febytelen;//(coordSize + 1); 322 | //printepoint(g); 323 | //printepoint(x); 324 | //cout << "g: " << g << ", x: " << x << ", y: " << y << ", z0: " << z0 << ", z1: " << z1 << endl; 325 | } 326 | 327 | uint32_t nRecvBufSize = 2 * nOTs * febytelen;//(coordSize + 1); 328 | uint8_t* pRecvBuf = (uint8_t*) malloc(nRecvBufSize); 329 | sock->Receive(pRecvBuf, nRecvBufSize); 330 | 331 | sock->Send(pBuf, nBufSize); 332 | 333 | uint8_t* retPtr = ret; 334 | pBufIdx = pRecvBuf; 335 | 336 | uint8_t* cpybuf = (uint8_t*) malloc(febytelen); 337 | for(uint32_t k = 0; k < nOTs; k++) 338 | { 339 | //if the choice bit is zero take the first value, else the second 340 | tmp->import_from_bytes(pBufIdx+(choices.GetBit(k) * febytelen));//ByteArrayToPoint(&w, coordSize, pBufIdx+(choices.GetBit(k) * (coordSize+1))); 341 | //w->print(); 342 | //b[k]->print(); 343 | 344 | //compute w_sigma^b 345 | //ecurve2_mult(b[k].getbig(), w.get_point(), w.get_point()); 346 | // *(fe2ec2(w)) *= *(num2Big(b[k])); 347 | w->set_pow(tmp, b[k]);//w *= b[k]; 348 | //w->print(); 349 | //export result and hash 350 | w->export_to_bytes(cpybuf);//PointToByteArray(pBufIdx, coordSize, w); 351 | hashReturn(retPtr, hashbytes, cpybuf, febytelen, k); 352 | 353 | retPtr += hashbytes; 354 | 355 | //Skip the next two values 356 | pBufIdx += 2*febytelen; 357 | 358 | } 359 | delete bx;//Miracl_brickend(&bx);//ebrick2_end(&bx); 360 | delete bg;//Miracl_brickend(&bg);//ebrick2_end(&bg); 361 | 362 | free(cpybuf); 363 | free(pRecvBuf); 364 | free(pBuf); 365 | free(b);*/ 366 | } 367 | 368 | 369 | 370 | 371 | void NaorPinkasNoRO::Sender(uint32_t nSndVals, uint32_t nOTs, channel* chan, BYTE* ret) 372 | { 373 | /*num **s0, **s1, **r0, **r1, *w;//Big s0[nOTs], s1[nOTs], r0[nOTs], r1[nOTs], w, xtmp, ytmp; 374 | fe *g, *w0, *w1, *R0, *R1, *x, *y, *Y, *Z0, *Z1, *z0, *z1, *ztmp;//EC2 g, w0, w1, R0, R1, x, y, Y, Z0, Z1, z0, z1, ztmp; 375 | brickexp *bg, *bx;//ebrick2 bg, bx; 376 | 377 | uint32_t hashbytelen = m_cCrypto->get_hash_bytes(); 378 | uint32_t febytelen = m_cPKCrypto->fe_byte_size(); 379 | //int coordSize = (m_SecParam+7)/8; 380 | //cout << "coordsize = " << coordSize << endl; 381 | 382 | s0 = (num**) malloc(sizeof(num*) * nOTs); 383 | s1 = (num**) malloc(sizeof(num*) * nOTs); 384 | r0 = (num**) malloc(sizeof(num*) * nOTs); 385 | r1 = (num**) malloc(sizeof(num*) * nOTs); 386 | 387 | 388 | w0 = m_cPKCrypto->get_fe(); 389 | w1 = m_cPKCrypto->get_fe(); 390 | R0 = m_cPKCrypto->get_fe(); 391 | R1 = m_cPKCrypto->get_fe(); 392 | z0 = m_cPKCrypto->get_fe(); 393 | z1 = m_cPKCrypto->get_fe(); 394 | Z0 = m_cPKCrypto->get_fe(); 395 | Z1 = m_cPKCrypto->get_fe(); 396 | x = m_cPKCrypto->get_fe(); 397 | y = m_cPKCrypto->get_fe(); 398 | Y = m_cPKCrypto->get_fe(); 399 | ztmp = m_cPKCrypto->get_fe(); 400 | 401 | g = m_cPKCrypto->get_generator();// Miracl_InitPoint(&g, *m_X, *m_Y);//g = EC2(*m_X, *m_Y); 402 | bg = m_cPKCrypto->get_brick(g); //Miracl_InitBrick(&bg, &g); 403 | 404 | //needs to store x, nOTs*y, nOTs*z0, and nOTs*z1 405 | uint32_t nBufSize = febytelen;//coordSize + 1; 406 | uint8_t* pBuf = (uint8_t*) malloc(nBufSize); 407 | 408 | sock->Receive(pBuf, nBufSize); 409 | //import x and compute fixed Point Exponentiation of x 410 | x->import_from_bytes(pBuf);//ByteArrayToPoint(&x, coordSize, pBuf); 411 | 412 | bx = m_cPKCrypto->get_brick(x);//Miracl_InitBrick(&bx, &x); 413 | 414 | free(pBuf); 415 | nBufSize = 2*nOTs * febytelen;//(coordSize+1); 416 | pBuf = (uint8_t*) malloc(nBufSize); 417 | 418 | uint8_t* pBufIdx = pBuf; 419 | 420 | for(uint32_t k = 0; k < nOTs; k++) 421 | { 422 | s0[k] = m_cPKCrypto->get_rnd_num();//rand(m_SecParam, 2); 423 | s1[k] = m_cPKCrypto->get_rnd_num();//rand(m_SecParam, 2); 424 | r0[k] = m_cPKCrypto->get_rnd_num();//rand(m_SecParam, 2); 425 | r1[k] = m_cPKCrypto->get_rnd_num();//rand(m_SecParam, 2); 426 | 427 | //compute w0 and export it 428 | bx->pow(ztmp, s0[k]);//Miracl_mulbrick(&bx, s0[k].getbig(), xtmp.getbig(), ytmp.getbig()); 429 | //Miracl_InitPoint(&ztmp, xtmp, ytmp);//ztmp = EC2(xtmp, ytmp); 430 | bg->pow(R0, r0[k]);//Miracl_mulbrick(&bg, r0[k].getbig(), xtmp.getbig(), ytmp.getbig()); 431 | //Miracl_InitPoint(&R0, xtmp, ytmp);//R0 = EC2(xtmp, ytmp); 432 | w0->set(ztmp);//w0 = ztmp; 433 | w0->set_mul(w0, R0);//w0 += R0; 434 | w0->export_to_bytes(pBufIdx);//PointToByteArray(pBufIdx, coordSize, w0); 435 | pBufIdx += febytelen;//coordSize + 1; 436 | 437 | //compute w1 and export it 438 | bx->pow(ztmp, s1[k]);//Miracl_mulbrick(&bx, s1[k].getbig(), xtmp.getbig(), ytmp.getbig()); 439 | //Miracl_InitPoint(&ztmp, xtmp, ytmp);//ztmp = EC2(xtmp, ytmp); 440 | bg->pow(R1, r1[k]);//Miracl_mulbrick(&bg, r1[k].getbig(), xtmp.getbig(), ytmp.getbig()); 441 | //Miracl_InitPoint(&R1, xtmp, ytmp);//R1 = EC2(xtmp, ytmp); 442 | w1->set(ztmp);//w1 = ztmp; 443 | w1->set_mul(w1, R1);//w1 += R1; 444 | 445 | w1->export_to_bytes(pBufIdx);//PointToByteArray(pBufIdx, coordSize, w1); 446 | pBufIdx += febytelen;//coordSize + 1; 447 | } 448 | 449 | //Send data off 450 | sock->Send(pBuf, nBufSize); 451 | 452 | free(pBuf); 453 | nBufSize = 3*nOTs * febytelen;//(coordSize +1); 454 | pBuf = (uint8_t*) malloc(nBufSize); 455 | 456 | //Receive new data 457 | sock->Receive(pBuf, nBufSize); 458 | 459 | uint8_t* retPtr = ret; 460 | pBufIdx = pBuf; 461 | for(uint32_t k = 0; k < nOTs; k++) 462 | { 463 | //get y, z0, and z1 464 | y->import_from_bytes(pBufIdx);//ByteArrayToPoint(&y, coordSize, pBufIdx); 465 | pBufIdx += febytelen;//coordSize+1; 466 | z0->import_from_bytes(pBufIdx);//ByteArrayToPoint(&z0, coordSize, pBufIdx); 467 | pBufIdx += febytelen;//coordSize+1; 468 | z1->import_from_bytes(pBufIdx);//ByteArrayToPoint(&z1, coordSize, pBufIdx); 469 | pBufIdx += febytelen;//coordSize+1; 470 | 471 | //compute first possible hash 472 | //cout << "r0: " << r0[k] << ", y: " << y << ", s0: " << s0[k] << ", z0: " << z0 << ", ztmp: " << ztmp << endl; 473 | ztmp->set_double_pow_mul(y, r0[k], z0, s0[k]); //ecurve2_mult2(r0[k].getbig(), y.get_point(), s0[k].getbig(), z0.get_point(), ztmp.get_point()); 474 | //#endif 475 | //cout << "r0: " << r0[k] << ", y: " << y << ", s0: " << s0[k] << ", z0: " << z0 << ", ztmp: " << ztmp << endl; 476 | //export result and hash 477 | ztmp->export_to_bytes(pBuf);//PointToByteArray(pBuf, coordSize, ztmp); 478 | hashReturn(retPtr, hashbytelen, pBuf, febytelen, k); 479 | retPtr += hashbytelen; 480 | 481 | //compute second possible hash 482 | ztmp->set_double_pow_mul(y, r1[k], z1, s1[k]);//ecurve2_mult2(r1[k].getbig(), y.get_point(), s1[k].getbig(), z1.get_point(), ztmp.get_point()); 483 | //export result and hash 484 | ztmp->export_to_bytes(pBuf);//PointToByteArray(pBuf, coordSize, ztmp); 485 | hashReturn(retPtr, hashbytelen, pBuf, febytelen, k); 486 | retPtr += hashbytelen; 487 | } 488 | 489 | delete(bx);////Miracl_brickend(&bx);//ebrick2_end(&bx); 490 | delete(bg);//Miracl_brickend(&bg);//ebrick2_end(&bg); 491 | free(pBuf); 492 | free(s0); 493 | free(s1); 494 | free(r0); 495 | free(r1);*/ 496 | } 497 | 498 | -------------------------------------------------------------------------------- /ot/naor-pinkas_noro.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file naor-pinkas_noro.h 3 | \author 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief The Naor-Pinkas OT protocols that does not require a random oracle 17 | */ 18 | 19 | #ifndef __Naor_Pinkas_NORO_H_ 20 | #define __Naor_Pinkas_NORO_H_ 21 | 22 | #include "baseOT.h" 23 | 24 | class NaorPinkasNoRO : public BaseOT 25 | { 26 | 27 | public: 28 | 29 | ~NaorPinkasNoRO(){}; 30 | 31 | NaorPinkasNoRO(crypto* crypt, field_type ftype) : 32 | BaseOT(crypt, ftype) { 33 | } 34 | void Receiver(uint32_t nSndVals, uint32_t nOTs, CBitVector* choices, channel* chan, BYTE* ret); 35 | void Sender(uint32_t nSndVals, uint32_t nOTs, channel* chan, BYTE* ret); 36 | 37 | 38 | 39 | }; 40 | 41 | 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /ot/nnob-ot-ext-rec.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file nnob-ot-ext-rec.cpp 3 | \author 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see ._______________ 16 | \brief 17 | */ 18 | 19 | 20 | #include 21 | #include "nnob-ot-ext-rec.h" 22 | #include "simpleot.h" 23 | #include 24 | #include 25 | 26 | 27 | BOOL NNOBOTExtRec::receiver_routine(uint32_t id, uint64_t myNumOTs) { 28 | uint64_t myStartPos = id * myNumOTs; 29 | uint64_t wd_size_bits = m_nBlockSizeBits; 30 | 31 | myNumOTs = std::min(myNumOTs + myStartPos, m_nOTs) - myStartPos; 32 | uint64_t lim = myStartPos + myNumOTs; 33 | 34 | uint64_t processedOTBlocks = std::min(num_ot_blocks, ceil_divide(myNumOTs, wd_size_bits)); 35 | uint64_t OTsPerIteration = processedOTBlocks * wd_size_bits; 36 | uint64_t OTwindow = num_ot_blocks * wd_size_bits; 37 | uint64_t** rndmat; 38 | bool use_mat_chan = (m_eSndOTFlav == Snd_GC_OT || m_bUseMinEntCorRob); 39 | uint32_t nchans = 2; 40 | if(use_mat_chan) { 41 | nchans = 3; 42 | } 43 | 44 | channel* ot_chan = new channel(OT_BASE_CHANNEL+nchans*id, m_cRcvThread, m_cSndThread); 45 | channel* check_chan = new channel(OT_BASE_CHANNEL+nchans*id+1, m_cRcvThread, m_cSndThread); 46 | channel* mat_chan; 47 | if(use_mat_chan) { 48 | mat_chan = new channel(nchans*id+2, m_cRcvThread, m_cSndThread); 49 | } 50 | 51 | // A temporary part of the T matrix 52 | CBitVector T(wd_size_bits * OTsPerIteration); 53 | 54 | // The send buffer 55 | CBitVector vSnd(m_nBaseOTs * OTsPerIteration); 56 | 57 | // A temporary buffer that stores the resulting seeds from the hash buffer 58 | //TODO: Check for some maximum size 59 | CBitVector seedbuf(OTwindow * m_cCrypt->get_aes_key_bytes() * 8); 60 | 61 | uint64_t otid = myStartPos; 62 | std::queue check_buf; 63 | 64 | std::queue mask_queue; 65 | CBitVector maskbuf; 66 | maskbuf.Create(m_nBitLength * OTwindow); 67 | 68 | //TODO only do when successfull checks 69 | if(m_eSndOTFlav == Snd_GC_OT) { 70 | initRndMatrix(&rndmat, m_nBitLength, m_nBaseOTs); 71 | } 72 | 73 | #ifdef OTTiming 74 | double totalMtxTime = 0, totalTnsTime = 0, totalHshTime = 0, totalRcvTime = 0, totalSndTime = 0, 75 | totalChkTime = 0, totalMaskTime = 0, totalEnqueueTime = 0; 76 | timespec tempStart, tempEnd; 77 | #endif 78 | 79 | while (otid < lim) { 80 | processedOTBlocks = std::min(num_ot_blocks, ceil_divide(lim - otid, wd_size_bits)); 81 | OTsPerIteration = processedOTBlocks * wd_size_bits; 82 | //nSize = bits_in_bytes(m_nBaseOTs * OTsPerIteration); 83 | 84 | #ifdef OTTiming 85 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 86 | #endif 87 | BuildMatrices(&T, &vSnd, otid, processedOTBlocks, m_tBaseOTKeys.front()); 88 | #ifdef OTTiming 89 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 90 | totalMtxTime += getMillies(tempStart, tempEnd); 91 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 92 | #endif 93 | check_buf.push(EnqueueSeed(T.GetArr(), otid, processedOTBlocks)); 94 | #ifdef OTTiming 95 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 96 | totalEnqueueTime += getMillies(tempStart, tempEnd); 97 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 98 | #endif 99 | MaskBaseOTs(&T, &vSnd, otid, processedOTBlocks); 100 | #ifdef OTTiming 101 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 102 | totalMaskTime += getMillies(tempStart, tempEnd); 103 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 104 | #endif 105 | SendMasks(&vSnd, ot_chan, otid, OTsPerIteration); 106 | //ot_chan->send_id_len(vSnd.GetArr(), nSize, otid, OTsPerIteration); 107 | #ifdef OTTiming 108 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 109 | totalSndTime += getMillies(tempStart, tempEnd); 110 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 111 | #endif 112 | ReceiveAndFillMatrix(rndmat, mat_chan); 113 | ReceiveAndXORCorRobVector(&T, OTsPerIteration, mat_chan); 114 | 115 | T.Transpose(wd_size_bits, OTsPerIteration); 116 | #ifdef OTTiming 117 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 118 | totalTnsTime += getMillies(tempStart, tempEnd); 119 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 120 | #endif 121 | 122 | HashValues(&T, &seedbuf, &maskbuf, otid, std::min(lim - otid, OTsPerIteration), rndmat); 123 | #ifdef OTTiming 124 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 125 | totalHshTime += getMillies(tempStart, tempEnd); 126 | clock_gettime(CLOCK_MONOTONIC, &tempStart); 127 | #endif 128 | if(check_chan->data_available()) { 129 | ComputeOWF(&check_buf, check_chan); 130 | } 131 | //if(ot_chan->data_available()) { 132 | // ReceiveAndUnMask(ot_chan); 133 | //} 134 | SetOutput(&maskbuf, otid, OTsPerIteration, &mask_queue, ot_chan); 135 | 136 | otid += std::min(lim - otid, OTsPerIteration); 137 | #ifdef OTTiming 138 | clock_gettime(CLOCK_MONOTONIC, &tempEnd); 139 | totalRcvTime += getMillies(tempStart, tempEnd); 140 | #endif 141 | 142 | vSnd.Reset(); 143 | T.Reset(); 144 | } 145 | 146 | while(!check_buf.empty()) { 147 | if(check_chan->data_available()) { 148 | ComputeOWF(&check_buf, check_chan); 149 | } 150 | } 151 | 152 | 153 | if(m_eSndOTFlav != Snd_R_OT) { 154 | //finevent->Wait(); 155 | #ifdef ABY_OT 156 | while(!(mask_queue.empty())) { 157 | #else 158 | while(ot_chan->is_alive() && !(mask_queue.empty())) { 159 | #endif 160 | ReceiveAndUnMask(ot_chan, &mask_queue); 161 | } 162 | } 163 | ot_chan->synchronize_end(); 164 | check_chan->synchronize_end(); 165 | delete ot_chan; 166 | delete check_chan; 167 | 168 | T.delCBitVector(); 169 | vSnd.delCBitVector(); 170 | seedbuf.delCBitVector(); 171 | maskbuf.delCBitVector(); 172 | 173 | if(use_mat_chan) { 174 | mat_chan->synchronize_end(); 175 | delete mat_chan; 176 | } 177 | 178 | if(m_eSndOTFlav==Snd_GC_OT) { 179 | freeRndMatrix(rndmat, m_nBaseOTs); 180 | } 181 | 182 | #ifdef OTTiming 183 | std::cout << "Receiver time benchmark for performing " << myNumOTs << " OTs on " << m_nBitLength << " bit strings" << std::endl; 184 | std::cout << "Time needed for: " << std::endl; 185 | std::cout << "\t Matrix Generation:\t" << totalMtxTime << " ms" << std::endl; 186 | std::cout << "\t Enqueuing Seeds:\t" << totalEnqueueTime << " ms" << std::endl; 187 | std::cout << "\t Base OT Masking:\t" << totalMaskTime << " ms" << std::endl; 188 | std::cout << "\t Sending Matrix:\t" << totalSndTime << " ms" << std::endl; 189 | std::cout << "\t Transposing Matrix:\t" << totalTnsTime << " ms" << std::endl; 190 | std::cout << "\t Hashing Matrix:\t" << totalHshTime << " ms" << std::endl; 191 | std::cout << "\t Receiving Values:\t" << totalRcvTime << " ms" << std::endl; 192 | #endif 193 | 194 | 195 | return TRUE; 196 | } 197 | 198 | 199 | void NNOBOTExtRec::ReceiveAndFillMatrix(uint64_t** rndmat, channel* mat_chan) { 200 | if(m_eSndOTFlav == Snd_GC_OT) { 201 | uint8_t* rnd_seed = mat_chan->blocking_receive(); 202 | //initRndMatrix(&rndmat, m_nBitLength, m_nBaseOTs); 203 | fillRndMatrix(rnd_seed, rndmat, m_nBitLength, m_nBaseOTs, m_cCrypt); 204 | free(rnd_seed); 205 | } 206 | } 207 | 208 | nnob_rcv_check_t NNOBOTExtRec::EnqueueSeed(uint8_t* T0, uint64_t otid, uint64_t numblocks) { 209 | uint64_t expseedbytelen = m_nBaseOTs * numblocks * m_nBlockSizeBytes; 210 | nnob_rcv_check_t seedstr; 211 | 212 | seedstr.otid = otid; 213 | seedstr.numblocks = numblocks; 214 | seedstr.T0 = (uint8_t*) malloc(expseedbytelen); 215 | 216 | memcpy(seedstr.T0, T0, expseedbytelen); 217 | 218 | return seedstr; 219 | } 220 | 221 | 222 | 223 | void NNOBOTExtRec::ComputeOWF(std::queue* check_buf_q, channel* check_chan) {//linking_t* permbits, int nchecks, int otid, int processedOTs, BYTE* outhashes) { 224 | 225 | //Obtain T0 and T1 from the SeedPointers 226 | uint32_t receiver_hashes = 1; 227 | 228 | uint64_t tmpid, tmpnblocks; 229 | linking_t* perm; 230 | uint8_t* rcv_buf_perm = check_chan->blocking_receive_id_len((uint8_t**) &perm, &tmpid, &tmpnblocks); 231 | uint8_t* rcv_buf_permchoices = check_chan->blocking_receive(); 232 | uint8_t* sender_permchoicebitptr = rcv_buf_permchoices; 233 | 234 | nnob_rcv_check_t check_buf = check_buf_q->front(); 235 | 236 | check_buf_q->pop(); 237 | 238 | assert(tmpid == check_buf.otid); 239 | assert(tmpnblocks == check_buf.numblocks); 240 | 241 | //the bufsize has to be padded to a multiple of the PRF-size since we will omit boundary checks there 242 | uint32_t i, j; 243 | uint64_t bufrowbytelen = m_nBlockSizeBytes * check_buf.numblocks;//seedptr->expstrbitlen>>3;//(CEIL_DIVIDE(processedOTs, wd_size_bits) * wd_size_bits) >>3; 244 | uint64_t checkbytelen = std::min(bufrowbytelen, bits_in_bytes(m_nOTs - check_buf.otid)); 245 | //contains the T-matrix 246 | uint8_t* T0 = check_buf.T0; 247 | //contains the T-matrix XOR the receive bits 248 | //uint8_t* T1 = check_buf.T1; 249 | 250 | uint32_t outhashbytelen = m_nChecks * OWF_BYTES * receiver_hashes; 251 | uint8_t* outhashes = (uint8_t*) malloc(outhashbytelen); 252 | 253 | #ifdef AES_OWF 254 | AES_KEY_CTX aesowfkey; 255 | MPC_AES_KEY_INIT(&aesowfkey); 256 | #else 257 | uint8_t* hash_buf = (uint8_t*) malloc(SHA512_DIGEST_LENGTH); 258 | #endif 259 | uint8_t* tmpbuf = (uint8_t*) malloc(bufrowbytelen); 260 | uint8_t **ka = (uint8_t**) malloc(2 * sizeof(uint8_t*)); 261 | uint8_t **kb = (uint8_t**) malloc(2 * sizeof(uint8_t*)); 262 | uint8_t *kaptr, *kbptr; 263 | uint8_t* outptr = outhashes; 264 | 265 | uint8_t* receiver_choicebits = m_vChoices->GetArr() + ceil_divide(check_buf.otid, 8); 266 | CBitVector tmp; 267 | tmp.AttachBuf(tmpbuf, bufrowbytelen*8); 268 | 269 | //Compute all hashes for the permutations given Ta, Tb and the choice bits 270 | for(i = 0; i < m_nChecks; i++, sender_permchoicebitptr++) { 271 | ka[0] = T0 + perm[i].ida * bufrowbytelen; 272 | kb[0] = T0 + perm[i].idb * bufrowbytelen; 273 | 274 | #ifdef DEBUG_MALICIOUS 275 | std::cout << (std::dec) << i << "-th check: between " << perm[i].ida << ", and " << perm[i].idb << std::endl; 276 | #endif 277 | for(j = 0; j < receiver_hashes; j++, outptr+=OWF_BYTES) { 278 | kaptr = ka[0]; 279 | kbptr = kb[0]; 280 | 281 | assert((*sender_permchoicebitptr) == 0 || (*sender_permchoicebitptr == 1)); 282 | 283 | tmp.SetXOR(kaptr, kbptr, 0, bufrowbytelen); 284 | if(*sender_permchoicebitptr == 1) { 285 | tmp.XORBytesReverse(receiver_choicebits, 0, checkbytelen); 286 | } 287 | 288 | #ifdef DEBUG_NNOB_CHECKS_INPUT 289 | std::cout << "XOR-OWF Input:\t" << (std::hex); 290 | for(uint32_t t = 0; t < checkbytelen; t++) { 291 | std::cout << std::setw(2) << std::setfill('0') << (uint32_t) tmpbuf[t]; 292 | } 293 | std::cout << (std::dec) << std::endl; 294 | #endif 295 | #ifdef AES_OWF 296 | owf(&aesowfkey, rowbytelen, tmpbuf, outhashes); 297 | #else 298 | //m_cCrypt->hash_buf(outptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf); 299 | sha512_hash(outptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf); 300 | #endif 301 | #ifdef DEBUG_NNOB_CHECKS_OUTPUT 302 | std::cout << "XOR-OWF Output:\t" << (std::hex); 303 | for(uint32_t t = 0; t < OWF_BYTES; t++) { 304 | std::cout << (uint32_t) outptr[t]; 305 | } 306 | std::cout << (std::dec) << std::endl; 307 | #endif 308 | } 309 | } 310 | check_chan->send_id_len(outhashes, outhashbytelen, check_buf.otid, check_buf.numblocks); 311 | 312 | free(rcv_buf_perm); 313 | free(rcv_buf_permchoices); 314 | //free(tmpbuf); 315 | free(ka); 316 | free(kb); 317 | free(check_buf.T0); 318 | //free(check_buf.T1); 319 | free(outhashes); 320 | #ifndef AES_OWF 321 | free(hash_buf); 322 | #endif 323 | } 324 | 325 | void NNOBOTExtRec::ComputeBaseOTs(field_type ftype) { 326 | if(m_bDoBaseOTs) { 327 | m_cBaseOT = new SimpleOT(m_cCrypt, ftype); 328 | ComputePKBaseOTs(); 329 | delete m_cBaseOT; 330 | } else { 331 | //recursive call 332 | } 333 | } 334 | -------------------------------------------------------------------------------- /ot/nnob-ot-ext-rec.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file nnob-ot-ext-rec.h 3 | \author 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see ._______________ 16 | \brief Malicious OT extension routine from NNOB12 17 | */ 18 | 19 | #ifndef NNOB_OT_EXT_REC_H_ 20 | #define NNOB_OT_EXT_REC_H_ 21 | 22 | #include "ot-ext-rec.h" 23 | 24 | 25 | 26 | typedef struct nnob_rcv_check_ctx { 27 | uint64_t otid; 28 | uint64_t numblocks; 29 | uint8_t* T0; 30 | } nnob_rcv_check_t; 31 | 32 | class NNOBOTExtRec : public OTExtRec { 33 | 34 | public: 35 | NNOBOTExtRec(crypto* crypt, RcvThread* rcvthread, SndThread* sndthread, bool dobaseots=true, uint64_t num_ot_blocks=4096, bool verify_ot=true, bool use_fixed_key_aes_hashing=false) 36 | : OTExtRec(num_ot_blocks, verify_ot, use_fixed_key_aes_hashing) { 37 | uint32_t nbaseots = ceil_divide(crypt->get_seclvl().symbits * 8, 3); 38 | InitRec(crypt, rcvthread, sndthread, nbaseots); 39 | m_nChecks = nbaseots/2; 40 | m_bDoBaseOTs=dobaseots; 41 | } 42 | ; 43 | 44 | 45 | ~NNOBOTExtRec() { 46 | } 47 | ; 48 | 49 | BOOL receiver_routine(uint32_t threadid, uint64_t numOTs); 50 | void ComputeBaseOTs(field_type ftype); 51 | 52 | private: 53 | nnob_rcv_check_t EnqueueSeed(uint8_t* T0, uint64_t otid, uint64_t numblocks); 54 | void ComputeOWF(std::queue* check_buf_q, channel* check_chan); 55 | void ReceiveAndFillMatrix(uint64_t** rndmat, channel* mat_chan); 56 | bool m_bDoBaseOTs; 57 | }; 58 | 59 | #endif /* NNOB_OT_EXT_REC_H_ */ 60 | -------------------------------------------------------------------------------- /ot/nnob-ot-ext-snd.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file nnob-ot-ext-snd.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief Malicious OT extension routine from NNOB12 17 | */ 18 | 19 | #ifndef NNOB_OT_EXT_SND_H_ 20 | #define NNOB_OT_EXT_SND_H_ 21 | 22 | #include "ot-ext-snd.h" 23 | 24 | typedef struct nnob_snd_check_ctx { 25 | uint64_t otid; 26 | uint64_t numblocks; 27 | linking_t* perm; 28 | uint8_t* chk_buf; 29 | uint8_t* permchoicebits; 30 | } nnob_snd_check_t; 31 | 32 | class NNOBOTExtSnd : public OTExtSnd { 33 | 34 | public: 35 | NNOBOTExtSnd( crypto* crypt, RcvThread* rcvthread, SndThread* sndthread, bool dobaseots=true, uint64_t num_ot_blocks=4096, bool verify_ot=true, bool use_fixed_key_aes_hashing=false) 36 | : OTExtSnd(num_ot_blocks, verify_ot, use_fixed_key_aes_hashing) { 37 | uint32_t nbaseots = ceil_divide(crypt->get_seclvl().symbits * 8, 3); 38 | InitSnd(crypt, rcvthread, sndthread, nbaseots); 39 | m_nChecks = nbaseots / 2; 40 | m_bDoBaseOTs = dobaseots; 41 | } 42 | ; 43 | 44 | 45 | ~NNOBOTExtSnd() { 46 | } 47 | ; 48 | 49 | BOOL sender_routine(uint32_t threadid, uint64_t numOTs); 50 | void ComputeBaseOTs(field_type ftype); 51 | 52 | 53 | private: 54 | nnob_snd_check_t* UpdateCheckBuf(uint8_t* tocheckseed, uint8_t* tocheckrcv, uint64_t otid, uint64_t numblocks, channel* check_chan); 55 | void XORandOWF(uint8_t* idaptr, uint8_t* idbptr, uint64_t rowbytelen, uint8_t* tmpbuf, uint8_t* resbuf, uint8_t* hash_buf); 56 | void genRandomMapping(linking_t* outperm, uint32_t nids); 57 | BOOL CheckConsistency(std::queue* check_buf_q, channel* check_chan); 58 | void FillAndSendRandomMatrix(uint64_t **rndmat, channel* chan); 59 | 60 | bool m_bDoBaseOTs; 61 | }; 62 | 63 | #endif /* NNOB_OT_EXT_SND_H_ */ 64 | -------------------------------------------------------------------------------- /ot/ot-ext-rec.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file ot-ext-rec.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | #ifndef OT_EXTENSION_RECEIVER_H_ 20 | #define OT_EXTENSION_RECEIVER_H_ 21 | 22 | #include "ot-ext.h" 23 | 24 | class channel; 25 | class CBitVector; 26 | 27 | class OTExtRec : public OTExt { 28 | 29 | public: 30 | 31 | OTExtRec(uint64_t num_ot_blocks, bool verify_ot, bool use_fixed_key_aes_hashing) 32 | : OTExt(num_ot_blocks, verify_ot, use_fixed_key_aes_hashing) {}; 33 | virtual ~OTExtRec(){ 34 | // TODO: nsndvals is currently hardcoeded in OTExtRec::ComputePKBaseOTs() 35 | // maybe add it as a private attribute to class OTExt and move the 36 | // following loop to its destructor? 37 | uint32_t nsndvals = 2; 38 | for(uint32_t i = 0; i < m_tBaseOTKeys.size(); i++) { 39 | for(uint32_t j = 0; j < m_nBaseOTs * nsndvals; j++) { 40 | m_cCrypt->clean_aes_key(&m_tBaseOTKeys[i][j]); 41 | } 42 | free(m_tBaseOTKeys[i]); 43 | } 44 | }; 45 | BOOL receive(uint64_t numOTs, uint64_t bitlength, uint64_t nsndvals, CBitVector* choices, CBitVector* ret, 46 | snd_ot_flavor stype, rec_ot_flavor rtype, uint32_t numThreads, MaskingFunction* maskfct); 47 | 48 | virtual void ComputeBaseOTs(field_type ftype) = 0; 49 | protected: 50 | 51 | BOOL start_receive(uint32_t numThreads); 52 | 53 | virtual BOOL receiver_routine(uint32_t threadid, uint64_t numOTs) = 0; 54 | 55 | void InitRec(crypto* crypt, RcvThread* rcvthread, SndThread* sndthread, uint32_t nbaseOTs) { 56 | Init(crypt, rcvthread, sndthread, nbaseOTs); 57 | } 58 | ; 59 | 60 | //void ReceiveAndProcess(uint32_t numThreads); 61 | void BuildMatrices(CBitVector* T, CBitVector* SndBuf, uint64_t ctr, uint64_t numblocks, OT_AES_KEY_CTX* seedkeyptr); 62 | void MaskBaseOTs(CBitVector* T, CBitVector* SndBuf, uint64_t OTid, uint64_t numblocks); 63 | void SendMasks(CBitVector* Sndbuf, channel* chan, uint64_t OTid, uint64_t processedOTs, uint64_t rem_row = 1); 64 | void HashValues(CBitVector* T, CBitVector* seedbuf, CBitVector* maskbuf, uint64_t ctr, uint64_t lim, uint64_t** mat); 65 | void SetOutput(CBitVector* maskbuf, uint64_t otid, uint64_t otlen, std::queue* mask_queue, channel* chan); 66 | void ReceiveAndUnMask(channel* chan, std::queue* mask_queue); 67 | void ReceiveAndXORCorRobVector(CBitVector* T, uint64_t OT_len, channel* chan); 68 | BOOL verifyOT(uint64_t myNumOTs); 69 | 70 | //void CleanupReceiver() { Cleanup(); };//TODO check if necessary and implement 71 | 72 | CBitVector* m_vChoices; 73 | CBitVector* m_vRet; 74 | //CBitVector m_vTempOTMasks; 75 | 76 | void ComputePKBaseOTs(); 77 | 78 | class OTReceiverThread: public CThread { 79 | public: 80 | OTReceiverThread(uint32_t threadid, uint64_t nOTs, OTExtRec* ext) { 81 | receiverID = threadid; 82 | numOTs = nOTs; 83 | callback = ext; 84 | success = false; 85 | } 86 | ; 87 | ~OTReceiverThread() { 88 | } 89 | ; 90 | void ThreadMain() { 91 | success = callback->receiver_routine(receiverID, numOTs); 92 | } 93 | ; 94 | private: 95 | uint32_t receiverID; 96 | uint64_t numOTs; 97 | OTExtRec* callback; 98 | BOOL success; 99 | }; 100 | }; 101 | 102 | #endif /* OT_EXTENSION_RECEIVER_H_ */ 103 | -------------------------------------------------------------------------------- /ot/ot-ext-snd.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file ot-ex-snd.cpp 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "ot-ext-snd.h" 25 | #include "baseOT.h" 26 | #include 27 | #include 28 | #ifdef OTTiming 29 | #include 30 | #endif 31 | 32 | BOOL OTExtSnd::send(uint64_t numOTs, uint64_t bitlength, uint64_t nsndvals, CBitVector** X, snd_ot_flavor stype, 33 | rec_ot_flavor rtype, uint32_t numThreads, MaskingFunction* maskfct) { 34 | m_nOTs = numOTs; 35 | m_nBitLength = bitlength; 36 | m_nSndVals = nsndvals; 37 | m_vValues = X; 38 | //m_vValues[0] = x0; 39 | //m_vValues[1] = x1; 40 | m_eSndOTFlav = stype; 41 | m_eRecOTFlav = rtype; 42 | m_fMaskFct = maskfct; 43 | 44 | assert(pad_to_power_of_two(m_nSndVals) == m_nSndVals); 45 | 46 | return start_send(numThreads); 47 | } 48 | 49 | //Initialize and start numThreads OTSenderThread 50 | BOOL OTExtSnd::start_send(uint32_t numThreads) { 51 | if (m_nOTs == 0) 52 | return true; 53 | 54 | if(numThreads * m_nBlockSizeBits > m_nOTs && numThreads > 1) { 55 | std::cerr << "Decreasing nthreads from " << numThreads << " to " << std::max(m_nOTs / m_nBlockSizeBits, (uint64_t) 1) << " to fit window size\n"; 56 | numThreads = std::max(m_nOTs / m_nBlockSizeBits, (uint64_t) 1); 57 | } 58 | 59 | //The total number of OTs that is performed has to be a multiple of numThreads*Z_REGISTER_BITS 60 | uint32_t wd_size_bits = m_nBlockSizeBits;//pad_to_power_of_two(m_nBaseOTs);//1 << (ceil_log2(m_nBaseOTs)); 61 | //uint64_t numOTs = ceil_divide(PadToMultiple(m_nOTs, wd_size_bits), numThreads); 62 | uint64_t internal_numOTs = PadToMultiple(ceil_divide(m_nOTs, numThreads), wd_size_bits); 63 | std::vector sThreads(numThreads); 64 | 65 | for (uint32_t i = 0; i < numThreads; i++) { 66 | sThreads[i] = new OTSenderThread(i, internal_numOTs, this); 67 | sThreads[i]->Start(); 68 | } 69 | 70 | for (uint32_t i = 0; i < numThreads; i++) { 71 | sThreads[i]->Wait(); 72 | } 73 | 74 | m_nCounter += m_nOTs; 75 | 76 | for (uint32_t i = 0; i < numThreads; i++) { 77 | delete sThreads[i]; 78 | } 79 | 80 | if (verify_ot) { 81 | verifyOT(m_nOTs); 82 | } 83 | 84 | return true; 85 | } 86 | 87 | 88 | void OTExtSnd::BuildQMatrix(CBitVector* T, uint64_t OT_ptr, uint64_t numblocks, OT_AES_KEY_CTX* seedkeyptr) { 89 | BYTE* Tptr = T->GetArr(); 90 | uint8_t* ctr_buf = (uint8_t*) calloc (AES_BYTES, sizeof(uint8_t)); 91 | uint64_t* counter = (uint64_t*) ctr_buf; 92 | uint64_t wd_size_bytes = m_nBlockSizeBytes;//pad_to_power_of_two(m_nBaseOTs/8);//1 << (ceil_log2(m_nBaseOTs) - 3); 93 | uint64_t rowbytelen = wd_size_bytes * numblocks; 94 | 95 | //AES_KEY_CTX* seedptr = m_vBaseOTKeys; 96 | uint64_t global_OT_ptr = OT_ptr + m_nCounter; 97 | 98 | uint64_t iters = rowbytelen / AES_BYTES; 99 | 100 | 101 | #ifdef USE_PIPELINED_AES_NI 102 | intrin_sequential_gen_rnd8(ctr_buf, global_OT_ptr, Tptr, iters, m_nBaseOTs, seedkeyptr); 103 | #else 104 | for (uint64_t k = 0, b; k < m_nBaseOTs; k++) { 105 | *counter = global_OT_ptr; 106 | for (b = 0; b < iters; b++, (*counter)++, Tptr += AES_BYTES) { 107 | m_cCrypt->encrypt(seedkeyptr + k, Tptr, ctr_buf, AES_BYTES); 108 | #ifdef DEBUG_MALICIOUS 109 | std::cout << "k = " << k << ": "<< (std::hex) << ((uint64_t*) Tptr)[0] << ((uint64_t*) Tptr)[1] << (std::hex) << std::endl; 110 | #endif 111 | } 112 | #ifdef DEBUG_OT_SEED_EXPANSION 113 | std::cout << "Xs[" << k << "]: " << (std::hex); 114 | for(uint64_t i = 0; i < AES_BYTES * iters; i++) { 115 | std::cout << std::setw(2) << std::setfill('0') << (uint32_t) (Tptr-AES_BYTES*iters)[i]; 116 | } 117 | std::cout << (std::dec) << " (" << (*counter)-iters << ")" <GetArr(); 128 | #ifdef GENERATE_T_EXPLICITELY 129 | uint64_t blocksizebytes = m_nBaseOTs * rowbytelen; 130 | #endif 131 | 132 | for (uint64_t k = 0; k < m_nBaseOTs; k++, rcvbufptr += rowbytelen) { 133 | #ifdef GENERATE_T_EXPLICITELY 134 | if (U->GetBit(k) == 0) { 135 | T->XORBytes(rcvbufptr, k * rowbytelen, rowbytelen); 136 | } else { 137 | T->XORBytes(rcvbufptr + blocksizebytes, k * rowbytelen, rowbytelen); 138 | } 139 | #else 140 | if (U->GetBit(k)) { 141 | T->XORBytes(rcvbufptr, k * rowbytelen, rowbytelen); 142 | } 143 | #endif 144 | 145 | } 146 | } 147 | 148 | void OTExtSnd::ReceiveMasks(CBitVector* vRcv, channel* chan, uint64_t processedOTs, uint64_t rec_r_ot_startpos) { 149 | //uint64_t nSize = bits_in_bytes(m_nBaseOTs * processedOTs); 150 | uint64_t tmpctr, tmpotlen; 151 | uint32_t startpos = 0; 152 | uint8_t *rcvbuftmpptr, *rcvbufptr; 153 | 154 | rcvbufptr = chan->blocking_receive_id_len(&rcvbuftmpptr, &tmpctr, &tmpotlen); 155 | 156 | if(m_eRecOTFlav == Rec_R_OT) { 157 | startpos = rec_r_ot_startpos; 158 | #ifdef GENERATE_T_EXPLICITELY 159 | vRcv->SetBytesToZero(0, 2* bits_in_bytes(processedOTs)); 160 | #else 161 | vRcv->SetBytesToZero(0, bits_in_bytes(processedOTs)); 162 | #endif 163 | } 164 | #ifdef GENERATE_T_EXPLICITELY 165 | if(m_eRecOTFlav == Rec_R_OT) { 166 | vRcv->SetBytes(rcvbuftmpptr, bits_in_bytes(processedOTs), bits_in_bytes((m_nBaseOTs -startpos) * processedOTs));//AttachBuf(rcvbuftmpptr, bits_in_bytes(m_nBaseOTs * OTsPerIteration)); 167 | vRcv->SetBytes(rcvbuftmpptr + bits_in_bytes((m_nBaseOTs -startpos) * processedOTs), bits_in_bytes(m_nBaseOTs * processedOTs), bits_in_bytes((m_nBaseOTs -startpos) * processedOTs)); 168 | } else { 169 | vRcv->SetBytes(rcvbuftmpptr, 0, 2 * bits_in_bytes(m_nBaseOTs* processedOTs));//AttachBuf(rcvbuftmpptr, bits_in_bytes(m_nBaseOTs * OTsPerIteration)); 170 | } 171 | #else 172 | vRcv->SetBytes(rcvbuftmpptr, bits_in_bytes(startpos * processedOTs), bits_in_bytes((m_nBaseOTs - startpos) * processedOTs));//AttachBuf(rcvbuftmpptr, bits_in_bytes(m_nBaseOTs * OTsPerIteration)); 173 | #endif 174 | free(rcvbufptr); 175 | } 176 | 177 | void OTExtSnd::GenerateSendAndXORCorRobVector(CBitVector* Q, uint64_t OT_len, channel* chan) { 178 | if(m_bUseMinEntCorRob) { 179 | uint64_t len = bits_in_bytes(m_nBaseOTs * OT_len); 180 | uint8_t* rndvec = (uint8_t*) malloc(len); 181 | m_cCrypt->gen_rnd(rndvec, len); 182 | Q->XORBytes(rndvec, len); 183 | chan->send(rndvec, len); 184 | free(rndvec); 185 | } 186 | } 187 | 188 | 189 | void OTExtSnd::HashValues(CBitVector* Q, CBitVector* seedbuf, CBitVector* snd_buf, CBitVector* U, 190 | uint64_t OT_ptr, uint64_t OT_len, uint64_t** mat_mul) { 191 | // uint64_t numhashiters = ceil_divide(m_nBitLength, m_cCrypt->get_hash_bytes()); 192 | uint32_t rowbytelen = bits_in_bytes(m_nBaseOTs); 193 | uint32_t hashinbytelen = rowbytelen + sizeof(uint64_t); 194 | uint64_t wd_size_bytes = m_nBlockSizeBytes;//1 << (ceil_log2(m_nBaseOTs) - 3); 195 | uint32_t u; 196 | uint32_t aes_key_bytes = m_cCrypt->get_aes_key_bytes(); 197 | 198 | 199 | uint64_t* Qptr = (uint64_t*) Q->GetArr(); 200 | uint64_t* Uptr = (uint64_t*) U->GetArr(); 201 | 202 | uint8_t** sbp = (uint8_t**) malloc(sizeof(uint8_t*) * m_nSndVals); 203 | uint8_t* inbuf = (uint8_t*) calloc(hashinbytelen, 1); 204 | uint8_t* resbuf = (uint8_t*) calloc(m_cCrypt->get_hash_bytes(), 1); 205 | uint8_t* hash_buf = (uint8_t*) calloc(m_cCrypt->get_hash_bytes(), 1); 206 | 207 | uint64_t* tmpbuf = (uint64_t*) calloc(PadToMultiple(bits_in_bytes(m_nBitLength), sizeof(uint64_t)), 1); 208 | uint8_t* tmpbufb = (uint8_t*) calloc(bits_in_bytes(m_nBitLength), 1); 209 | 210 | uint64_t global_OT_ptr = OT_ptr + m_nCounter; 211 | 212 | for (u = 0; u < m_nSndVals; u++) 213 | sbp[u] = seedbuf[u].GetArr(); 214 | 215 | for (uint64_t i = 0; i < OT_len; global_OT_ptr++, i++, Qptr += 2) { 216 | for (u = 0; u < m_nSndVals; u++) { 217 | 218 | #ifdef HIGH_SPEED_ROT_LT 219 | if(u == 1) { 220 | Qptr[0]^=Uptr[0]; 221 | Qptr[1]^=Uptr[1]; 222 | } 223 | #else 224 | if (u == 1) 225 | Q->XORBytes((uint8_t*) Uptr, i * wd_size_bytes, rowbytelen); 226 | #endif 227 | 228 | #ifdef DEBUG_OT_HASH_IN 229 | std::cout << "Hash-In for i = " << global_OT_ptr << ", u = " << u << ": " << (std::hex); 230 | for(uint32_t p = 0; p < rowbytelen; p++) 231 | std::cout << std::setw(2) << std::setfill('0') << (uint32_t) (Q.GetArr() + i * wd_size_bytes)[p]; 232 | std::cout << (std::dec) << std::endl; 233 | #endif 234 | 235 | if(m_eSndOTFlav != Snd_GC_OT) { 236 | if (use_fixed_key_aes_hashing) { 237 | FixedKeyHashing(m_kCRFKey, sbp[u], (BYTE*) Qptr, hash_buf, i, ceil_divide(m_nSymSecParam, 8), m_cCrypt); 238 | } else { 239 | memcpy(inbuf, &global_OT_ptr, sizeof(uint64_t)); 240 | memcpy(inbuf+sizeof(uint64_t), Q->GetArr() + i * wd_size_bytes, rowbytelen); 241 | m_cCrypt->hash_buf(resbuf, aes_key_bytes, inbuf, hashinbytelen, hash_buf); 242 | memcpy(sbp[u], resbuf, aes_key_bytes); 243 | } 244 | } else { 245 | 246 | BitMatrixMultiplication(tmpbufb, bits_in_bytes(m_nBitLength), Q->GetArr() + i * wd_size_bytes, m_nBaseOTs, mat_mul, tmpbuf); 247 | //m_vValues[u].SetBits(tmpbufb, (OT_ptr + i)* m_nBitLength, m_nBitLength); 248 | snd_buf[u].SetBits(tmpbufb, i * m_nBitLength, m_nBitLength); 249 | //m_vTempOTMasks.SetBytes(tmpbufb, (uint64_t) (OT_ptr + i) * aes_key_bytes, (uint64_t) aes_key_bytes); 250 | //m_vValues[u].SetBytes(Q.GetArr() + i * wd_size_bytes, (OT_ptr + i)* wd_size_bytes, rowbytelen); 251 | 252 | } 253 | 254 | #ifdef DEBUG_OT_HASH_OUT 255 | std::cout << "Hash-Out for i = " << global_OT_ptr << ", u = " << u << ": " << (std::hex); 256 | for(uint32_t p = 0; p < aes_key_bytes; p++) 257 | std::cout << std::setw(2) << std::setfill('0') << (uint32_t) sbp[u][p]; 258 | std::cout << (std::dec) << std::endl; 259 | #endif 260 | sbp[u] += aes_key_bytes; 261 | 262 | } 263 | } 264 | //m_vValues[0].PrintHex(); 265 | //m_vValues[1].PrintHex(); 266 | 267 | #ifndef HIGH_SPEED_ROT_LT 268 | if(m_eSndOTFlav != Snd_GC_OT) { 269 | //Two calls to expandMask, both writing into snd_buf 270 | for (uint32_t u = 0; u < m_nSndVals; u++) 271 | m_fMaskFct->expandMask(&(snd_buf[u]), seedbuf[u].GetArr(), 0, OT_len, m_nBitLength, m_cCrypt); 272 | } 273 | #endif 274 | 275 | free(resbuf); 276 | free(inbuf); 277 | free(sbp); 278 | free(hash_buf); 279 | free(tmpbuf); 280 | free(tmpbufb); 281 | } 282 | 283 | void OTExtSnd::MaskAndSend(CBitVector* snd_buf, uint64_t OT_ptr, uint64_t OT_len, channel* chan) { 284 | m_fMaskFct->Mask(OT_ptr, OT_len, m_vValues, snd_buf, m_eSndOTFlav); 285 | 286 | if (m_eSndOTFlav == Snd_R_OT || m_eSndOTFlav == Snd_GC_OT) 287 | return; 288 | 289 | uint64_t bufsize = bits_in_bytes(OT_len * m_nBitLength); 290 | uint8_t* buf = nullptr; 291 | if (m_eSndOTFlav == Snd_OT) { 292 | buf = (uint8_t*) malloc(2*bufsize); 293 | memcpy(buf, snd_buf[0].GetArr(), bufsize); 294 | memcpy(buf+ bufsize, snd_buf[1].GetArr(), bufsize); 295 | bufsize *= 2; 296 | } else if (m_eSndOTFlav == Snd_C_OT) { 297 | buf = (uint8_t*) malloc(bufsize); 298 | memcpy(buf, snd_buf[1].GetArr(), bufsize); 299 | } 300 | 301 | chan->send_id_len(buf, bufsize, OT_ptr, OT_len); 302 | free(buf); 303 | } 304 | 305 | 306 | BOOL OTExtSnd::verifyOT(uint64_t NumOTs) { 307 | std::cout << "Verifying 1oo"<< m_nSndVals << " OT" << std::endl; 308 | uint64_t processedOTBlocks, OTsPerIteration; 309 | uint64_t nSnd; 310 | uint8_t* resp; 311 | 312 | std::unique_ptr chan = std::make_unique(OT_ADMIN_CHANNEL, m_cRcvThread, m_cSndThread); 313 | 314 | for (uint64_t i = 0; i < NumOTs; i += OTsPerIteration) { 315 | processedOTBlocks = std::min(num_ot_blocks, ceil_divide(NumOTs - i, AES_BITS)); 316 | OTsPerIteration = std::min(processedOTBlocks * AES_BITS, NumOTs - i); 317 | nSnd = ceil_divide(OTsPerIteration * m_nBitLength, 8); 318 | 319 | for(uint64_t j = 0; j < m_nSndVals; j++) { 320 | chan->send_id_len(m_vValues[j]->GetArr() + bits_in_bytes(i * m_nBitLength), nSnd, i, OTsPerIteration); 321 | } 322 | 323 | resp = chan->blocking_receive(); 324 | 325 | if (*resp == 0x00) { 326 | std::cerr << "\033[1;31mError: Receiver notified us of failed OT verification.\033[0m" << std::endl; 327 | free(resp); 328 | chan->synchronize_end(); 329 | return false; 330 | } 331 | free(resp); 332 | } 333 | 334 | std::cout << "OT Verification successful" << std::flush << std::endl; 335 | chan->synchronize_end(); 336 | 337 | return true; 338 | } 339 | 340 | 341 | void OTExtSnd::ComputePKBaseOTs() { 342 | channel* chan = new channel(OT_ADMIN_CHANNEL, m_cRcvThread, m_cSndThread); 343 | uint8_t* pBuf = (uint8_t*) malloc(m_cCrypt->get_hash_bytes() * m_nBaseOTs); 344 | uint8_t* keyBuf = (uint8_t*) malloc(m_cCrypt->get_aes_key_bytes() * m_nBaseOTs); 345 | 346 | uint32_t nsndvals = 2; 347 | 348 | CBitVector* U = new CBitVector(); 349 | U->Create(m_nBaseOTs, m_cCrypt); 350 | //m_vU.Copy(U.GetArr(), 0, bits_in_bytes(nbaseOTs)); 351 | //fill zero into the remaining positions - is needed if nbaseots is not a multiple of 8 352 | for (uint32_t i = m_nBaseOTs; i < PadToMultiple(m_nBaseOTs, 8); i++) 353 | U->SetBit(i, 0); 354 | OT_AES_KEY_CTX* tmpkeybuf = (OT_AES_KEY_CTX*) malloc(sizeof(OT_AES_KEY_CTX) * m_nBaseOTs); 355 | 356 | #ifdef OTTiming 357 | timespec np_begin, np_end; 358 | clock_gettime(CLOCK_MONOTONIC, &np_begin); 359 | #endif 360 | 361 | m_cBaseOT->Receiver(nsndvals, m_nBaseOTs, U, chan, pBuf); 362 | 363 | 364 | #ifdef OTTiming 365 | clock_gettime(CLOCK_MONOTONIC, &np_end); 366 | printf("Time for performing the base-OTs: %f seconds\n", getMillies(np_begin, np_end)); 367 | #endif 368 | 369 | //Key expansion 370 | uint8_t* pBufIdx = pBuf; 371 | for(uint32_t i=0; iget_aes_key_bytes(), pBufIdx, m_cCrypt->get_aes_key_bytes()); 374 | pBufIdx+=m_cCrypt->get_hash_bytes(); 375 | } 376 | 377 | free(pBuf); 378 | 379 | InitPRFKeys(tmpkeybuf, keyBuf, m_nBaseOTs); 380 | 381 | 382 | m_tBaseOTKeys.push_back(tmpkeybuf); 383 | m_tBaseOTChoices.push_back(U); 384 | 385 | 386 | free(keyBuf); 387 | chan->synchronize_end(); 388 | 389 | delete chan; 390 | } 391 | -------------------------------------------------------------------------------- /ot/ot-ext-snd.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file ot-ext-snd.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief 17 | */ 18 | 19 | #ifndef OT_EXTENSION_SENDER_H_ 20 | #define OT_EXTENSION_SENDER_H_ 21 | 22 | #include "ot-ext.h" 23 | #include 24 | 25 | class channel; 26 | 27 | class OTExtSnd : public OTExt { 28 | 29 | public: 30 | OTExtSnd(uint64_t num_ot_blocks, bool verify_ot, bool use_fixed_key_aes_hashing) 31 | : OTExt(num_ot_blocks, verify_ot, use_fixed_key_aes_hashing) {}; 32 | 33 | virtual ~OTExtSnd() { 34 | for(size_t i = 0; i < m_tBaseOTChoices.size(); i++) { 35 | delete m_tBaseOTChoices[i]; 36 | } 37 | // TODO: This could be done in OTExt destructor; 38 | // see also comment in OTExtSnd destructor 39 | for(uint32_t i = 0; i < m_tBaseOTKeys.size(); i++) { 40 | for(uint32_t j = 0; j < m_nBaseOTs; j++) { 41 | m_cCrypt->clean_aes_key(&m_tBaseOTKeys[i][j]); 42 | } 43 | free(m_tBaseOTKeys[i]); 44 | } 45 | // do not free(m_vValues), since it is passed from the outside to send() 46 | }; 47 | 48 | BOOL send(uint64_t numOTs, uint64_t bitlength, uint64_t nsndvals, CBitVector** X, snd_ot_flavor stype, 49 | rec_ot_flavor rtype, uint32_t numThreads, MaskingFunction* maskfct); 50 | 51 | virtual void ComputeBaseOTs(field_type ftype) = 0; 52 | protected: 53 | void InitSnd(crypto* crypt, RcvThread* rcvthread, SndThread* sndthread, uint32_t nbaseOTs) { 54 | Init(crypt, rcvthread, sndthread, nbaseOTs); 55 | 56 | m_tBaseOTChoices.resize(0); 57 | } 58 | ; 59 | 60 | BOOL start_send(uint32_t numThreads); 61 | virtual BOOL sender_routine(uint32_t threadid, uint64_t numOTs) = 0; 62 | 63 | BOOL OTSenderRoutine(uint32_t id, uint32_t myNumOTs); 64 | 65 | void BuildQMatrix(CBitVector* T, uint64_t ctr, uint64_t blocksize, OT_AES_KEY_CTX* seedkeyptr); 66 | void UnMaskBaseOTs(CBitVector* T, CBitVector* RcvBuf, CBitVector* U, uint64_t numblocks); 67 | void MaskAndSend(CBitVector* snd_buf, uint64_t progress, uint64_t processedOTs, channel* chan); 68 | //void SendBlocks(uint32_t numThreads); 69 | void ReceiveMasks(CBitVector* vRcv, channel* chan, uint64_t processedOTs, uint64_t rec_r_ot_startpos=1); 70 | void GenerateSendAndXORCorRobVector(CBitVector* Q, uint64_t OT_len, channel* chan); 71 | void HashValues(CBitVector* Q, CBitVector* seedbuf, CBitVector* snd_buf, CBitVector* Uptr, uint64_t ctr, uint64_t processedOTs, uint64_t** mat); 72 | BOOL verifyOT(uint64_t myNumOTs); 73 | 74 | void ComputePKBaseOTs(); 75 | 76 | //CBitVector m_vU; 77 | CBitVector** m_vValues; 78 | 79 | BYTE* m_vSeed; 80 | 81 | std::vector m_tBaseOTChoices; 82 | 83 | 84 | class OTSenderThread: public CThread { 85 | public: 86 | OTSenderThread(uint32_t id, uint64_t nOTs, OTExtSnd* ext) { 87 | senderID = id; 88 | numOTs = nOTs; 89 | callback = ext; 90 | success = false; 91 | } 92 | ; 93 | ~OTSenderThread() { 94 | } 95 | ; 96 | void ThreadMain() { 97 | success = callback->sender_routine(senderID, numOTs); 98 | } 99 | ; 100 | private: 101 | uint32_t senderID; 102 | uint64_t numOTs; 103 | OTExtSnd* callback; 104 | BOOL success; 105 | }; 106 | 107 | }; 108 | 109 | 110 | 111 | 112 | #endif /* OT_EXTENSION_SENDER_H_ */ 113 | -------------------------------------------------------------------------------- /ot/ot-ext.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file ot-ext.cpp 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief Methods for the OT Extension routine 17 | */ 18 | 19 | #include "ot-ext.h" 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ot/ot-ext.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file ot-ext.h 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief Methods for the OT Extension routine 17 | */ 18 | 19 | #ifndef __OT_EXTENSION_H_ 20 | #define __OT_EXTENSION_H_ 21 | 22 | //internal OT options 23 | //#define OTTiming 24 | //#define AES_OWF 25 | //#define GENERATE_T_EXPLICITELY //send two instead of only one message, only required for benchmarking, not recommended 26 | //#define DEBUG_OT_HASH_IN 27 | //#define DEBUG_OT_HASH_OUT 28 | //#define DEBUG_OT_SEED_EXPANSION 29 | //#define DEBUG_BASE_OT_HASH_RET 30 | //#define DEBUG_RECEIVE_THREAD 31 | //#define DEBUG_SEND_THREAD 32 | //#define HIGH_SPEED_ROT_LT 33 | //#define DEBUG_ALSZ_CHECKS 34 | //#define DEBUG_ALSZ_CHECKS_INPUT 35 | //#define DEBUG_ALSZ_CHECKS_OUTPUT 36 | //#define DEBUG_NNOB_CHECKS 37 | //#define DEBUG_NNOB_CHECKS_INPUT 38 | //#define DEBUG_NNOB_CHECKS_OUTPUT 39 | //#define DEBUG_KK_OTBREAKDOWN 40 | 41 | 42 | #include "maskingfunction.h" 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include "OTconstants.h" 48 | #include 49 | 50 | #ifdef OTTiming 51 | #include 52 | #include 53 | #endif 54 | 55 | class BaseOT; 56 | class CBitVector; 57 | 58 | #ifdef USE_PIPELINED_AES_NI 59 | typedef ROUND_KEYS OT_AES_KEY_CTX; 60 | 61 | static void InitAESKey(OT_AES_KEY_CTX* ctx, uint8_t* keybytes, uint32_t numkeys, crypto* crypt) { 62 | intrin_sequential_ks4(ctx, keybytes, numkeys); 63 | } 64 | #else 65 | typedef AES_KEY_CTX OT_AES_KEY_CTX; 66 | 67 | static const uint8_t fixed_key_aes_seed[32] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 68 | 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; 69 | 70 | static void InitAESKey(OT_AES_KEY_CTX* ctx, uint8_t* keybytes, uint32_t numkeys, crypto* crypt) { 71 | BYTE* pBufIdx = keybytes; 72 | uint32_t aes_key_bytes = crypt->get_aes_key_bytes(); 73 | for (uint32_t i = 0; i < numkeys; i++) { 74 | crypt->init_aes_key(ctx + i, pBufIdx); 75 | pBufIdx += aes_key_bytes; 76 | } 77 | } 78 | #endif 79 | 80 | 81 | 82 | 83 | struct ot_block { 84 | uint64_t startotid; 85 | uint64_t otlen; 86 | uint8_t* buf; 87 | }; 88 | 89 | struct mask_block { 90 | uint64_t startotid; 91 | uint64_t otlen; 92 | CBitVector* buf; 93 | }; 94 | 95 | typedef struct { 96 | uint32_t ida; 97 | uint32_t idb; 98 | } linking_t; 99 | 100 | 101 | 102 | typedef struct mask_buf_ctx { 103 | uint64_t otid; 104 | uint64_t otlen; 105 | CBitVector* maskbuf; 106 | } mask_buf_t; 107 | 108 | 109 | 110 | 111 | class OTExt { 112 | 113 | public: 114 | OTExt(uint64_t num_ot_blocks, bool verify_ot, bool use_fixed_key_aes_hashing) 115 | : num_ot_blocks(num_ot_blocks), buffer_ot_keys(num_ot_blocks), 116 | verify_ot(verify_ot), 117 | use_fixed_key_aes_hashing(use_fixed_key_aes_hashing) {}; 118 | virtual ~OTExt() { 119 | if (use_fixed_key_aes_hashing) { 120 | m_cCrypt->clean_aes_key(m_kCRFKey); 121 | free(m_kCRFKey); 122 | } 123 | }; 124 | 125 | virtual void ComputeBaseOTs(field_type ftype) = 0; 126 | 127 | void EnableMinEntCorrRobustness() { 128 | m_bUseMinEntCorRob = true; 129 | } 130 | void DisableMinEntCorrRobustness() { 131 | m_bUseMinEntCorRob = false; 132 | } 133 | 134 | protected: 135 | void Init(crypto* crypt, RcvThread* rcvthread, SndThread* sndthread, uint32_t nbaseOTs) { 136 | m_cCrypt = crypt; 137 | m_nSymSecParam = m_cCrypt->get_seclvl().symbits; 138 | m_nBaseOTs = nbaseOTs; 139 | m_nBlockSizeBits = pad_to_power_of_two(m_nBaseOTs); 140 | m_nBlockSizeBytes = pad_to_power_of_two(m_nBaseOTs/8); 141 | m_nCounter = 0; 142 | m_bUseMinEntCorRob = false; 143 | m_tBaseOTKeys.resize(0); 144 | 145 | //sndthread = new SndThread(sock); 146 | //rcvthread = new RcvThread(sock); 147 | 148 | //sndthread->Start(); 149 | //rcvthread->Start(); 150 | m_cSndThread = sndthread; 151 | m_cRcvThread = rcvthread;; 152 | 153 | //m_vBaseOTKeys = (AES_KEY_CTX*) malloc(sizeof(AES_KEY_CTX) * nbasekeys); 154 | } 155 | 156 | 157 | void InitPRFKeys(OT_AES_KEY_CTX* base_ot_keys, uint8_t* keybytes, uint32_t nbasekeys) { 158 | InitAESKey(base_ot_keys, keybytes, nbasekeys, m_cCrypt); 159 | 160 | if (use_fixed_key_aes_hashing) { 161 | m_kCRFKey = (AES_KEY_CTX*) malloc(sizeof(AES_KEY_CTX)); 162 | m_cCrypt->init_aes_key(m_kCRFKey, (uint8_t*) fixed_key_aes_seed); 163 | } 164 | } 165 | 166 | snd_ot_flavor m_eSndOTFlav; 167 | rec_ot_flavor m_eRecOTFlav; 168 | uint32_t m_nSndVals; 169 | uint64_t m_nOTs; 170 | uint64_t m_nBitLength; 171 | uint64_t m_nCounter; 172 | uint32_t m_nSymSecParam; 173 | uint32_t m_nBaseOTs; 174 | uint32_t m_nChecks; 175 | uint32_t m_nBlockSizeBits; 176 | uint32_t m_nBlockSizeBytes; 177 | 178 | crypto* m_cCrypt; 179 | 180 | //The flag whether to use min-entropy correlation robustness instead of correlation robustness 181 | bool m_bUseMinEntCorRob; 182 | 183 | SndThread* m_cSndThread; 184 | RcvThread* m_cRcvThread; 185 | 186 | std::vector m_tBaseOTKeys; 187 | 188 | MaskingFunction* m_fMaskFct; 189 | 190 | BaseOT* m_cBaseOT; 191 | 192 | // (previously compile time options) 193 | const uint64_t num_ot_blocks; 194 | const uint64_t buffer_ot_keys; 195 | const bool verify_ot; 196 | const bool use_fixed_key_aes_hashing; 197 | 198 | AES_KEY_CTX* m_kCRFKey; 199 | }; 200 | 201 | inline void fillRndMatrix(uint8_t* seed, uint64_t** mat, uint64_t cols, uint64_t rows, crypto* crypt) { 202 | uint32_t columnlen = ceil_divide(cols, sizeof(uint64_t) * 8); 203 | prf_state_ctx tmpstate; 204 | crypt->init_prf_state(&tmpstate, seed); 205 | for(uint32_t i = 0; i < rows; i++) { 206 | gen_rnd_bytes(&tmpstate, (uint8_t*) mat[i], columnlen * sizeof(uint64_t)); 207 | } 208 | crypt->free_prf_state(&tmpstate); 209 | } 210 | 211 | inline void initRndMatrix(uint64_t*** mat, uint64_t cols, uint64_t rows) { 212 | uint32_t columnlen = ceil_divide(cols, sizeof(uint64_t) * 8); 213 | *mat = (uint64_t**) malloc(sizeof(uint64_t*) * rows); 214 | for(uint32_t i = 0; i < rows; i++) { 215 | (*mat)[i] = (uint64_t*) malloc(sizeof(uint64_t) * columnlen); 216 | }} 217 | 218 | inline void freeRndMatrix(uint64_t** mat, uint32_t nrows) { 219 | for(uint32_t i = 0; i < nrows; i++) 220 | free(mat[i]); 221 | free(mat); 222 | } 223 | 224 | inline void BitMatrixMultiplication(uint8_t* resbuf, uint64_t resbytelen, uint8_t* invec, uint32_t inveclen, 225 | uint64_t** matrix, uint64_t* tmpbuf) { 226 | uint32_t columniters = ceil_divide(resbytelen, sizeof(uint64_t)); 227 | uint32_t rowbit; 228 | memset((uint8_t*) tmpbuf, 0, columniters * sizeof(uint64_t)); 229 | for(uint32_t i = 0, j; i < inveclen; i++) { 230 | rowbit = !!(invec[i>>3] & (0x01<<(i&0x07))); 231 | for(j = 0; j < columniters; j++) { 232 | tmpbuf[j] ^= (matrix[i][j] * rowbit); 233 | //cout << "rowbit = " << rowbit << ", matrix[i][j] = " << matrix[i][j] << ", tmpbuf = " << tmpbuf[j] << endl; 234 | } 235 | } 236 | memcpy(resbuf, tmpbuf, resbytelen); 237 | /*cout << (dec) << "out: " << resbytelen << ": "<< (hex); 238 | for(uint32_t i = 0; i < resbytelen; i++) { 239 | cout << (uint32_t) resbuf[i]; 240 | } 241 | cout << (dec) << endl;*/ 242 | } 243 | 244 | #define OWF_BYTES AES_BYTES 245 | 246 | inline void FixedKeyHashing(AES_KEY_CTX* aeskey, BYTE* outbuf, BYTE* inbuf, BYTE* tmpbuf, uint64_t id, uint32_t bytessecparam, crypto* crypt) { 247 | assert(bytessecparam <= AES_BYTES); 248 | #ifdef HIGH_SPEED_ROT_LT 249 | ((uint64_t*) tmpbuf)[0] = id ^ ((uint64_t*) inbuf)[0]; 250 | ((uint64_t*) tmpbuf)[1] = ((uint64_t*) inbuf)[1]; 251 | #else 252 | memset(tmpbuf, 0, AES_BYTES); 253 | memcpy(tmpbuf, (BYTE*) (&id), sizeof(uint64_t)); 254 | 255 | for (uint32_t i = 0; i < bytessecparam; i++) { 256 | tmpbuf[i] = tmpbuf[i] ^ inbuf[i]; 257 | } 258 | #endif 259 | 260 | crypt->encrypt(aeskey, outbuf, tmpbuf, AES_BYTES); 261 | 262 | #ifdef HIGH_SPEED_ROT_LT 263 | ((uint64_t*) outbuf)[0] ^= ((uint64_t*) inbuf)[0]; 264 | ((uint64_t*) outbuf)[1] ^= ((uint64_t*) inbuf)[1]; 265 | #else 266 | for (uint32_t i = 0; i < bytessecparam; i++) { 267 | outbuf[i] = outbuf[i] ^ inbuf[i]; 268 | } 269 | #endif 270 | } 271 | 272 | 273 | 274 | #endif /* __OT_EXTENSION_H_ */ 275 | -------------------------------------------------------------------------------- /ot/pvwddh.cpp: -------------------------------------------------------------------------------- 1 | #include "pvwddh.h" 2 | #include 3 | #include 4 | #include 5 | 6 | void PVWDDH::Receiver([[maybe_unused]] uint32_t nSndVals, uint32_t nOTs, CBitVector* choices, channel* chan, uint8_t* retbuf) { 7 | 8 | fe *g[2], *h[2], *pkg, *pkh, *u, *zkcommit[2]; 9 | num *y, *alpha, *r[nOTs], *zkr, *zkchallenge, *zkproof; 10 | uint8_t *sndbuf, *sndbufptr, *rcvbuf, *rcvbufptr, *retbufptr, *tmpbuf; 11 | 12 | brickexp* bg[2]; 13 | brickexp* bh[2]; 14 | uint32_t i, sndbufsize, hash_bytes, fe_bytes, num_bytes; 15 | 16 | hash_bytes = m_cCrypto->get_hash_bytes(); 17 | fe_bytes = m_cPKCrypto->fe_byte_size(); 18 | num_bytes = m_cPKCrypto->num_byte_size(); 19 | 20 | //First step: do initial crs exchange 21 | sndbufsize = fe_bytes * 6; 22 | sndbuf = (uint8_t*) malloc(sndbufsize); 23 | 24 | for(i = 0; i < 2; i++) { 25 | g[i] = m_cPKCrypto->get_fe(); 26 | h[i] = m_cPKCrypto->get_fe(); 27 | zkcommit[i] = m_cPKCrypto->get_fe(); 28 | } 29 | 30 | //use default generator and init brick 31 | g[0] = m_cPKCrypto->get_generator(); 32 | bg[0] = m_cPKCrypto->get_brick(g[0]); 33 | 34 | //generate random y and alpha 35 | y = m_cPKCrypto->get_rnd_num(); 36 | alpha = m_cPKCrypto->get_rnd_num(); 37 | 38 | 39 | //compute g1 = g0 ^ y and init brick 40 | bg[0]->pow(g[1], y); 41 | bg[1] = m_cPKCrypto->get_brick(g[1]); 42 | 43 | //sample random rzk for zero-knowledge proof 44 | zkr = m_cPKCrypto->get_rnd_num(); 45 | 46 | sndbufptr = sndbuf; 47 | 48 | //compute h0 = g0 ^ alpha and h1 = g1 ^ alpha 49 | for(i = 0; i < 2; i++) { 50 | bg[i]->pow(h[i], alpha); 51 | bh[i] = m_cPKCrypto->get_brick(h[i]); 52 | 53 | //Convert field elements to bytes 54 | g[i]->export_to_bytes(sndbufptr); 55 | sndbufptr+=fe_bytes; 56 | h[i]->export_to_bytes(sndbufptr); 57 | sndbufptr+=fe_bytes; 58 | 59 | //ZK-proof data 60 | bg[i]->pow(zkcommit[i], zkr); 61 | zkcommit[i]->export_to_bytes(sndbufptr); 62 | sndbufptr+=fe_bytes; 63 | } 64 | 65 | //send public keys together with proofs to the sender 66 | chan->send(sndbuf, sndbufsize); 67 | free(sndbuf); 68 | 69 | 70 | //Second step: for each OT generate and send a public-key and receive challenge + send compute proof 71 | pkg = m_cPKCrypto->get_fe(); 72 | pkh = m_cPKCrypto->get_fe(); 73 | 74 | sndbufsize = fe_bytes * 2 * nOTs + num_bytes; 75 | sndbuf = (uint8_t*) malloc(sndbufsize); 76 | sndbufptr = sndbuf; 77 | 78 | for(i = 0; i < nOTs; i++) { 79 | //generate r_i at random and compute g_i = g_sigma_i ^ r_i and h_i = h_sigma_i ^ r_i 80 | r[i] = m_cPKCrypto->get_rnd_num(); 81 | bg[choices->GetBit(i)]->pow(pkg, r[i]); 82 | bh[choices->GetBit(i)]->pow(pkh, r[i]); 83 | 84 | //convert elements to bytes 85 | pkg->export_to_bytes(sndbufptr); 86 | sndbufptr+=fe_bytes; 87 | pkh->export_to_bytes(sndbufptr); 88 | sndbufptr+=fe_bytes; 89 | } 90 | 91 | //Receive challenge 92 | rcvbuf = chan->blocking_receive(); 93 | zkchallenge = m_cPKCrypto->get_num(); 94 | zkchallenge->import_from_bytes(rcvbuf, num_bytes); 95 | free(rcvbuf); 96 | 97 | //Compute proof as zkproof = (zkr + zkchallenge * alpha ) mod q 98 | zkproof = m_cPKCrypto->get_num(); 99 | zkproof->set_mul_mod(alpha, zkchallenge, m_cPKCrypto->get_order()); 100 | zkproof->set_add(zkproof, zkr); 101 | zkproof->mod(m_cPKCrypto->get_order()); 102 | zkproof->export_to_bytes(sndbufptr, num_bytes); 103 | 104 | //send data and proof 105 | chan->send(sndbuf, sndbufsize); 106 | 107 | 108 | //Third step: receive the seeds to the KDF from the sender and generate a random string from the chosen one 109 | u = m_cPKCrypto->get_fe(); 110 | 111 | //receive the values 112 | //rcvbufsize = 2 * nOTs * fe_bytes; 113 | rcvbuf = chan->blocking_receive(); 114 | 115 | //a buffer for storing the hash input 116 | tmpbuf = (uint8_t*) malloc(fe_bytes); 117 | 118 | retbufptr = retbuf; 119 | rcvbufptr = rcvbuf; 120 | 121 | for (i = 0; i < nOTs; i++, rcvbufptr+=(2 * fe_bytes), retbufptr+=hash_bytes) { 122 | //convert the received bytes to a field element, compute u_i ^ r_i, and convert u_i^r_i back to bytes 123 | u->import_from_bytes(rcvbufptr + (choices->GetBit(i) * fe_bytes)); 124 | u->set_pow(u, r[i]); 125 | u->export_to_bytes(tmpbuf); 126 | 127 | //hash u_i^r_i 128 | hashReturn(retbufptr, hash_bytes, tmpbuf, fe_bytes, i); 129 | } 130 | 131 | for(i = 0; i < 2; i++) { 132 | delete bg[i]; 133 | delete bh[i]; 134 | } 135 | 136 | free(sndbuf); 137 | free(rcvbuf); 138 | free(tmpbuf); 139 | } 140 | 141 | 142 | void PVWDDH::Sender([[maybe_unused]] uint32_t nSndVals, uint32_t nOTs, channel* chan, uint8_t* retbuf) { 143 | fe *g[2], *h[2], *pkg, *pkh, *u, *v, *gs, *ht, *zkcommit[2], *gchk, *zkchk; 144 | num *s, *t, *zkchallenge, *zkproof; 145 | 146 | brickexp *bg[2]; 147 | brickexp *bh[2]; 148 | 149 | uint8_t *sndbuf, *sndbufptr, *rcvbuf, *rcvbufptr, *retbufptr, *tmpbuf; 150 | 151 | uint32_t i, j, sndbufsize, fe_bytes, num_bytes, hash_bytes; 152 | 153 | hash_bytes = m_cCrypto->get_hash_bytes(); 154 | fe_bytes = m_cPKCrypto->fe_byte_size(); 155 | num_bytes = m_cPKCrypto->num_byte_size(); 156 | 157 | //First step: receive the crs and initialize the bricks 158 | zkchallenge = m_cPKCrypto->get_rnd_num(); 159 | 160 | rcvbuf = chan->blocking_receive(); 161 | 162 | //Send challenge 163 | sndbuf = (uint8_t*) malloc(num_bytes); 164 | zkchallenge->export_to_bytes(sndbuf, num_bytes); 165 | chan->send(sndbuf, num_bytes); 166 | free(sndbuf); 167 | 168 | rcvbufptr = rcvbuf; 169 | for(i = 0; i < 2; i++) { 170 | g[i] = m_cPKCrypto->get_fe(); 171 | g[i]->import_from_bytes(rcvbufptr); 172 | rcvbufptr += fe_bytes; 173 | bg[i] = m_cPKCrypto->get_brick(g[i]); 174 | 175 | h[i] = m_cPKCrypto->get_fe(); 176 | h[i]->import_from_bytes(rcvbufptr); 177 | rcvbufptr += fe_bytes; 178 | bh[i] = m_cPKCrypto->get_brick(h[i]); 179 | 180 | //Zero-knowledge commits 181 | zkcommit[i] = m_cPKCrypto->get_fe(); 182 | zkcommit[i]->import_from_bytes(rcvbufptr); 183 | rcvbufptr += fe_bytes; 184 | } 185 | 186 | free(rcvbuf); 187 | 188 | //Second step: receive a public-key for each OT 189 | pkg = m_cPKCrypto->get_fe(); 190 | pkh = m_cPKCrypto->get_fe(); 191 | u = m_cPKCrypto->get_fe(); 192 | v = m_cPKCrypto->get_fe(); 193 | gs = m_cPKCrypto->get_fe(); 194 | ht = m_cPKCrypto->get_fe(); 195 | 196 | rcvbuf = chan->blocking_receive(); 197 | 198 | sndbufsize = 2 * nOTs * fe_bytes; 199 | sndbuf = (uint8_t*) malloc(sndbufsize); 200 | 201 | tmpbuf = (uint8_t*) malloc(fe_bytes); 202 | 203 | rcvbufptr = rcvbuf; 204 | sndbufptr = sndbuf; 205 | retbufptr = retbuf; 206 | 207 | for(i = 0; i < nOTs; i++) { 208 | //read pkg_i and pkh_i 209 | pkg->import_from_bytes(rcvbufptr); 210 | rcvbufptr += fe_bytes; 211 | pkh->import_from_bytes(rcvbufptr); 212 | rcvbufptr += fe_bytes; 213 | 214 | 215 | for(j = 0; j < 2; j++) { 216 | //choose random si and ti 217 | s = m_cPKCrypto->get_rnd_num(); 218 | t = m_cPKCrypto->get_rnd_num(); 219 | 220 | //u_i = g_j^s_i * h_j ^ t_i 221 | bg[j]->pow(gs, s); 222 | bh[j]->pow(ht, t); 223 | u = m_cPKCrypto->get_fe();//TODO: there is sth weird going on here, get new fe to avoid this problem 224 | u->set_mul(gs, ht); 225 | 226 | v = m_cPKCrypto->get_fe();//TODO: there is sth weird going on here, get new fe to avoid this problem 227 | //v_i = pkg_i^s_i * pkh_i ^ t_i 228 | v->set_double_pow_mul(pkg, s, pkh, t); 229 | 230 | //store u_i in the sndbuf 231 | u->export_to_bytes(sndbufptr); 232 | sndbufptr+=fe_bytes; 233 | 234 | v->export_to_bytes(tmpbuf); 235 | hashReturn(retbufptr, hash_bytes, tmpbuf, fe_bytes, i); 236 | retbufptr+=hash_bytes; 237 | } 238 | } 239 | 240 | zkproof = m_cPKCrypto->get_num(); 241 | 242 | //send the u_i's 243 | chan->send(sndbuf, sndbufsize); 244 | 245 | //Verify proof 246 | zkproof->import_from_bytes(rcvbufptr, num_bytes); 247 | 248 | //Group check is omitted because both parties use the pre-generated NIST parameters 249 | gchk = m_cPKCrypto->get_fe(); 250 | zkchk = m_cPKCrypto->get_fe(); 251 | 252 | for(j = 0; j < 2; j++) { 253 | //gj ^ zkproof 254 | bg[j]->pow(gchk, zkproof); 255 | 256 | //zkcommit_j * h_j^zkchallenge 257 | bh[j]->pow(zkchk, zkchallenge); 258 | zkchk->set_mul(zkchk, zkcommit[j]); 259 | 260 | //if(gchk != zkchk) { 261 | if(!gchk->eq(zkchk)) { 262 | std::cout << "Zero-knowledge proof for base-OTs failed!" << std::endl; 263 | gchk->print(); 264 | std::cout << ", vs. "; 265 | zkchk->print(); 266 | std::cout << std::endl; 267 | exit(0); 268 | } 269 | } 270 | 271 | for(i = 0; i < 2; i++) { 272 | delete bg[i]; 273 | delete bh[i]; 274 | } 275 | 276 | free(rcvbuf); 277 | free(sndbuf); 278 | free(tmpbuf); 279 | } 280 | -------------------------------------------------------------------------------- /ot/pvwddh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Compute the Base OTs using the Peikert-Vakuntanathan-Waters OT based on DDH in decryption mode (PVW08) 3 | */ 4 | 5 | #ifndef __PVWDDH_H_ 6 | #define __PVWDDH_H_ 7 | 8 | #include "baseOT.h" 9 | 10 | class PVWDDH : public BaseOT 11 | { 12 | 13 | public: 14 | 15 | ~PVWDDH(){}; 16 | 17 | PVWDDH(crypto* crypt, field_type ftype): 18 | BaseOT(crypt, ftype) { 19 | } 20 | ; 21 | 22 | void Receiver(uint32_t nSndVals, uint32_t nOTs, CBitVector* choices, channel* chan, BYTE* ret); 23 | void Sender(uint32_t nSndVals, uint32_t nOTs, channel* chan, BYTE* ret); 24 | 25 | 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /ot/simpleot.cpp: -------------------------------------------------------------------------------- 1 | #include "simpleot.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void SimpleOT::Receiver([[maybe_unused]] uint32_t nSndVals, uint32_t nOTs, CBitVector* choices, channel* chan, uint8_t* retbuf) { 9 | 10 | fe *g, **B, *A, *AB; 11 | num **b, *order, *tmp; 12 | uint8_t *sndbuf, *sndbufptr, *rcvbuf, *retbufptr, *tmpbuf; 13 | 14 | brickexp* bg; 15 | uint32_t i, sndbufsize, hash_bytes, fe_bytes; 16 | 17 | hash_bytes = m_cCrypto->get_hash_bytes(); 18 | fe_bytes = m_cPKCrypto->fe_byte_size(); 19 | 20 | //use default generator and init brick 21 | g = m_cPKCrypto->get_generator(); 22 | bg = m_cPKCrypto->get_brick(g); 23 | 24 | order = m_cPKCrypto->get_order(); 25 | 26 | b = (num**) malloc(sizeof(num*) * nOTs); 27 | B = (fe**) malloc(sizeof(fe*) * nOTs); 28 | 29 | tmp = m_cPKCrypto->get_num(); 30 | A = m_cPKCrypto->get_fe(); 31 | //Receive A values 32 | rcvbuf = chan->blocking_receive(); 33 | 34 | sndbufsize = nOTs * fe_bytes; 35 | sndbuf = (uint8_t*) malloc(sndbufsize); 36 | sndbufptr = sndbuf; 37 | 38 | A->import_from_bytes(rcvbuf); 39 | //TODO: very timing side channel affine 40 | for(i = 0; i < nOTs; i++, sndbufptr+=fe_bytes) { 41 | b[i] = m_cPKCrypto->get_rnd_num(); 42 | b[i]->mod(order); 43 | B[i] = m_cPKCrypto->get_fe(); 44 | 45 | if(choices->GetBit(i) == 0) { 46 | bg->pow(B[i] , b[i]); 47 | B[i]->export_to_bytes(sndbufptr); 48 | } else { 49 | tmp->set_sub(order, b[i]); 50 | bg->pow(B[i], tmp); 51 | AB = m_cPKCrypto->get_fe(); 52 | AB->set_mul(B[i], A); 53 | AB->export_to_bytes(sndbufptr); 54 | delete AB; 55 | } 56 | } 57 | 58 | chan->send(sndbuf, sndbufsize); 59 | free(sndbuf); 60 | 61 | retbufptr = retbuf; 62 | tmpbuf = (uint8_t*) malloc(fe_bytes); 63 | AB = m_cPKCrypto->get_fe(); 64 | for(i = 0; i < nOTs; i++, retbufptr+=hash_bytes) { 65 | AB->set_pow(A, b[i]); 66 | AB->export_to_bytes(tmpbuf); 67 | 68 | hashReturn(retbufptr, hash_bytes, tmpbuf, fe_bytes, i); 69 | } 70 | 71 | free(tmpbuf); 72 | free(rcvbuf); 73 | for(uint32_t i = 0; i < nOTs; i++) { 74 | delete b[i]; 75 | delete B[i]; 76 | } 77 | free(b); 78 | free(B); 79 | 80 | delete bg; 81 | 82 | delete g; 83 | delete A; 84 | delete AB; 85 | delete order; 86 | delete tmp; 87 | } 88 | 89 | 90 | void SimpleOT::Sender([[maybe_unused]] uint32_t nSndVals, uint32_t nOTs, channel* chan, uint8_t* retbuf) { 91 | fe *g, *A, *Asqr, *B, *AB, *tmp; 92 | num *a, *asqr, *order; 93 | 94 | brickexp *bg; 95 | 96 | uint8_t *sndbuf, *sndbufptr, *rcvbuf, *rcvbufptr, *retbufptr, *tmpbuf; 97 | 98 | uint32_t i, sndbufsize, fe_bytes, hash_bytes; 99 | 100 | hash_bytes = m_cCrypto->get_hash_bytes(); 101 | fe_bytes = m_cPKCrypto->fe_byte_size(); 102 | 103 | //use default generator and init brick 104 | g = m_cPKCrypto->get_generator(); 105 | bg = m_cPKCrypto->get_brick(g); 106 | 107 | a = m_cPKCrypto->get_rnd_num(); 108 | A = m_cPKCrypto->get_fe(); 109 | 110 | sndbufsize = fe_bytes; 111 | sndbuf = (uint8_t*) malloc(sndbufsize); 112 | sndbufptr = sndbuf; 113 | 114 | bg->pow(A, a); 115 | A->export_to_bytes(sndbufptr); 116 | 117 | chan->send(sndbuf, sndbufsize); 118 | free(sndbuf); 119 | 120 | asqr = m_cPKCrypto->get_num(); 121 | Asqr = m_cPKCrypto->get_fe(); 122 | 123 | order = m_cPKCrypto->get_order(); 124 | asqr->set_mul_mod(a, a, order); 125 | delete order; 126 | bg->pow(Asqr, asqr); 127 | //Asqr->set_pow(g, asqr); 128 | 129 | 130 | rcvbuf = chan->blocking_receive(); 131 | tmpbuf = (uint8_t*) malloc(fe_bytes); 132 | 133 | rcvbufptr = rcvbuf; 134 | retbufptr = retbuf; 135 | 136 | for(i = 0; i < nOTs; i++, rcvbufptr+=fe_bytes) { 137 | B = m_cPKCrypto->get_fe(); 138 | B->import_from_bytes(rcvbufptr); 139 | //cout << "B: "; B->print(); 140 | //cout << "A[i]: "; A[i]->print(); 141 | //cout << "a[i]: "; a[i]->print(); 142 | 143 | //For X0 144 | AB = m_cPKCrypto->get_fe(); 145 | AB->set_pow(B, a); 146 | AB->export_to_bytes(tmpbuf); 147 | hashReturn(retbufptr, hash_bytes, tmpbuf, fe_bytes, i); 148 | retbufptr+=hash_bytes; 149 | 150 | //For X1 151 | //AB = m_cPKCrypto->get_fe(); 152 | tmp = m_cPKCrypto->get_fe(); 153 | tmp->set_div(Asqr, AB); 154 | tmp->export_to_bytes(tmpbuf), 155 | hashReturn(retbufptr, hash_bytes, tmpbuf, fe_bytes, i); 156 | retbufptr+=hash_bytes; 157 | 158 | delete AB; 159 | delete B; 160 | delete tmp; 161 | } 162 | 163 | free(tmpbuf); 164 | free(rcvbuf); 165 | delete bg; 166 | 167 | delete g; 168 | delete A; 169 | delete Asqr; 170 | delete a; 171 | delete asqr; 172 | } 173 | -------------------------------------------------------------------------------- /ot/simpleot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Compute the Simple OT protocol from Tung Chou and Claudio Orlandi on http://eprint.iacr.org/2015/267 3 | */ 4 | 5 | #ifndef __SIMPLEOT_H_ 6 | #define __SIMPLEOT_H_ 7 | 8 | #include "baseOT.h" 9 | 10 | class channel; 11 | class CBitVector; 12 | 13 | class SimpleOT : public BaseOT 14 | { 15 | 16 | public: 17 | 18 | SimpleOT(crypto* crypt, field_type ftype): 19 | BaseOT(crypt, ftype) { 20 | } 21 | ; 22 | 23 | void Receiver(uint32_t nSndVals, uint32_t nOTs, CBitVector* choices, channel* chan, BYTE* ret); 24 | void Sender(uint32_t nSndVals, uint32_t nOTs, channel* chan, BYTE* ret); 25 | 26 | 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /ot/xormasking.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file ot-ext-rec.cpp 3 | \author michael.zohner@ec-spride.de 4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation 5 | Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published 8 | by the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | ABY is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program. If not, see . 16 | \brief XOR Masking 17 | */ 18 | 19 | #ifndef XORMASKING_H_ 20 | #define XORMASKING_H_ 21 | 22 | #include "maskingfunction.h" 23 | 24 | class XORMasking: public MaskingFunction { 25 | public: 26 | XORMasking(uint32_t bitlength) { 27 | init(bitlength); 28 | } 29 | ; 30 | XORMasking(uint32_t bitlength, CBitVector& delta) { 31 | m_vDelta = δ 32 | init(bitlength); 33 | } 34 | ; 35 | virtual ~XORMasking() { 36 | } 37 | ; 38 | 39 | void init(uint32_t bitlength) { 40 | m_nBitLength = bitlength; 41 | } 42 | 43 | void Mask(uint32_t progress, uint32_t processedOTs, CBitVector** values, CBitVector* snd_buf, snd_ot_flavor protocol) { 44 | 45 | if (protocol == Snd_OT) { 46 | snd_buf[0].XORBytes(values[0]->GetArr() + ceil_divide(progress * m_nBitLength, 8), 0, ceil_divide(processedOTs * m_nBitLength, 8)); 47 | snd_buf[1].XORBytes(values[1]->GetArr() + ceil_divide(progress * m_nBitLength, 8), 0, ceil_divide(processedOTs * m_nBitLength, 8)); 48 | } else if (protocol == Snd_C_OT) { 49 | uint64_t bitPos = progress * m_nBitLength; 50 | uint64_t length = processedOTs * m_nBitLength; 51 | uint64_t bytePos = ceil_divide(bitPos, 8); 52 | values[0]->SetBytes(snd_buf[0].GetArr(), bytePos, ceil_divide(length, 8)); //.SetBits(hash_buf, i*m_nBitLength, m_nBitLength); 53 | 54 | values[1]->SetBits(values[0]->GetArr() + bytePos, bitPos, length); 55 | values[1]->XORBits(m_vDelta->GetArr() + bytePos, bitPos, length); 56 | snd_buf[1].XORBits(values[1]->GetArr() + bytePos, 0, length); 57 | } 58 | else if (protocol == Snd_R_OT || protocol == Snd_GC_OT) { 59 | values[0]->SetBytes(snd_buf[0].GetArr(), ceil_divide(progress * m_nBitLength, 8), ceil_divide(processedOTs * m_nBitLength, 8)); 60 | values[1]->SetBytes(snd_buf[1].GetArr(), ceil_divide(progress * m_nBitLength, 8), ceil_divide(processedOTs * m_nBitLength, 8)); 61 | } 62 | } 63 | ; 64 | 65 | //output already has to contain the masks 66 | void UnMask(uint32_t progress, uint32_t processedOTs, CBitVector* choices, CBitVector* output, CBitVector* rcv_buf, 67 | CBitVector* tmpmask, snd_ot_flavor protocol) { 68 | uint32_t bytelen = bits_in_bytes(m_nBitLength); 69 | uint64_t gprogress = progress * bytelen; 70 | uint64_t lim = progress + processedOTs; 71 | uint64_t offset; 72 | 73 | if (protocol == Snd_OT) { 74 | if(m_nBitLength & 0x07) { 75 | gprogress = progress * m_nBitLength; 76 | offset = PadToMultiple(processedOTs * m_nBitLength, 8); 77 | output->Copy(tmpmask->GetArr(), bits_in_bytes(gprogress), bits_in_bytes(offset)); 78 | for (uint32_t u, i = progress, l = 0; i < lim; i++, gprogress += m_nBitLength, l += m_nBitLength) { 79 | u = (uint32_t) choices->GetBitNoMask(i); 80 | output->XORBitsPosOffset(rcv_buf->GetArr(), (u * offset) + l, gprogress, m_nBitLength); 81 | } 82 | } else { 83 | offset = processedOTs * bytelen; 84 | for (uint32_t u, i = progress, l = 0; i < lim; i++, gprogress += bytelen, l += bytelen) { 85 | u = (uint32_t) choices->GetBitNoMask(i); 86 | output->SetXOR(rcv_buf->GetArr() + (u * offset) + l, tmpmask->GetArr() + l, gprogress, bytelen); 87 | } 88 | } 89 | 90 | } else if (protocol == Snd_C_OT) { 91 | if(m_nBitLength & 0x07) { 92 | gprogress = progress * m_nBitLength; 93 | offset = PadToMultiple(processedOTs * m_nBitLength, 8); 94 | //output.Copy(tmpmask.GetArr() + bits_in_bytes(gprogress), bits_in_bytes(gprogress), 95 | // bits_in_bytes(offset)); 96 | output->Copy(tmpmask->GetArr(), bits_in_bytes(gprogress), bits_in_bytes(offset)); 97 | for (uint32_t i = progress, l = 0; i < lim; i++, gprogress += m_nBitLength, l += m_nBitLength) { 98 | if(choices->GetBitNoMask(i)) { 99 | output->XORBitsPosOffset(rcv_buf->GetArr(), l, gprogress, m_nBitLength); 100 | } 101 | } 102 | } else { 103 | //output.Copy(tmpmask.GetArr() + gprogress, gprogress, bytelen * processedOTs); 104 | output->Copy(tmpmask->GetArr(), gprogress, bytelen * processedOTs); 105 | for (uint32_t i = progress, l = 0; i < lim; i++, l += bytelen, gprogress += bytelen) { 106 | if (choices->GetBitNoMask(i)) { 107 | output->XORBytes(rcv_buf->GetArr() + l, gprogress, bytelen); 108 | } 109 | } 110 | } 111 | } else if (protocol == Snd_R_OT || protocol == Snd_GC_OT) { 112 | gprogress = bits_in_bytes(progress * m_nBitLength); 113 | output->Copy(tmpmask->GetArr(), gprogress, bits_in_bytes(processedOTs * m_nBitLength)); 114 | } 115 | } 116 | ; 117 | 118 | void expandMask(CBitVector* out, BYTE* sbp, uint32_t offset, uint32_t processedOTs, uint32_t bitlength, crypto* crypt) { 119 | 120 | if (bitlength <= AES_KEY_BITS) { 121 | uint64_t pos = offset * bitlength; 122 | for (uint32_t i = 0; i < processedOTs; i++, sbp += AES_KEY_BYTES, pos+=bitlength) { 123 | out->SetBits(sbp, pos, (uint64_t) bitlength); 124 | } 125 | } else { 126 | uint8_t* m_bBuf = (uint8_t*) malloc(AES_BYTES); 127 | uint8_t* ctr_buf = (uint8_t*) calloc(AES_BYTES, sizeof(uint8_t)); 128 | uint32_t counter = *((uint32_t*) ctr_buf); 129 | AES_KEY_CTX* tkey = (AES_KEY_CTX*) malloc(sizeof(AES_KEY_CTX)); 130 | //crypt->init_aes_key(tkey, sbp); 131 | for (uint32_t i = 0, rem; i < processedOTs; i++, sbp += AES_KEY_BYTES) { 132 | crypt->init_aes_key(tkey, sbp); 133 | for (counter = 0; counter < bitlength / AES_BITS; counter++) { 134 | crypt->encrypt(tkey, m_bBuf, ctr_buf, AES_BYTES); 135 | out->SetBits(m_bBuf, ((uint64_t) offset + i) * bitlength + (counter * AES_BITS), (uint64_t) AES_BITS); 136 | } 137 | //the final bits 138 | if ((rem = bitlength - (counter * AES_BITS)) > 0) { 139 | crypt->encrypt(tkey, m_bBuf, ctr_buf, AES_BYTES); 140 | out->SetBits(m_bBuf, ((uint64_t) offset + i) * bitlength + (counter * AES_BITS), (uint64_t) rem); 141 | } 142 | crypt->clean_aes_key(tkey); 143 | } 144 | free(m_bBuf); 145 | free(ctr_buf); 146 | free(tkey); 147 | } 148 | } 149 | 150 | private: 151 | CBitVector* m_vDelta; 152 | uint32_t m_nBitLength; 153 | }; 154 | 155 | #endif /* XORMASKING_H_ */ 156 | --------------------------------------------------------------------------------