Skip to content

Commit 4852cae

Browse files
committed
cleanup and message passing example.
1 parent 86dcb8b commit 4852cae

File tree

6 files changed

+318
-125
lines changed

6 files changed

+318
-125
lines changed

README.md

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ This library currently implements:
1919
* The malicious secure 1-out-of-2 Delta-OT [[KOS15]](https://eprint.iacr.org/2015/546),[[BLNNOOSS15]](https://eprint.iacr.org/2015/472.pdf).
2020
* The malicious 1-out-of-2 OT [[Roy22]](https://eprint.iacr.org/2022/192).
2121
* The malicious secure 1-out-of-N OT [[OOS16]](http://eprint.iacr.org/2016/933).
22-
* The malicious secure approximate K-out-of-N OT [[RR16]](https://eprint.iacr.org/2016/746).
2322
* The malicious secure 1-out-of-2 base OT [NP01].
2423
* The malicious secure 1-out-of-2 base OT [[CO15]](https://eprint.iacr.org/2015/267.pdf) (Faster Linux ASM version disabled by default).
2524
* The malicious secure 1-out-of-2 base OT [[MR19]](https://eprint.iacr.org/2019/706.pdf)
@@ -30,14 +29,13 @@ This library currently implements:
3029
This library provides several different classes of OT protocols. First is the
3130
base OT protocol of [CO15, MR19, MRR21]. These protocol bootstraps all the other
3231
OT extension protocols. Within the OT extension protocols, we have 1-out-of-2,
33-
1-out-of-N and K-out-of-N, both in the semi-honest and malicious settings. See The `frontend` or `libOTe_Tests` folder for examples.
32+
1-out-of-N, and VOLE both in the semi-honest and malicious settings. See The `frontend` or `libOTe_Tests` folder for examples.
3433

3534
All implementations are highly optimized using fast SSE instructions and vectorization
36-
to obtain optimal performance both in the single and multi-threaded setting. See
37-
the **Performance** section for a comparison between protocols and to other libraries.
35+
to obtain optimal performance both in the single and multi-threaded setting.
3836

3937
Networking can be performed using both the sockets provided by the library and
40-
external socket classes. See the coproto tutorial for an example.
38+
external socket classes. The simplest integration can be achieved via the [message passing interface](https://github.com/osu-crypto/libOTe/blob/master/frontend/ExampleMessagePassing.h) where the user is given the protocol messages that need to be sent/received. Users can also integrate their own socket type for maximum performance. See the [coproto](https://github.com/Visa-Research/coproto/blob/main/frontend/SocketTutorial.cpp) tutorial for examples.
4139

4240

4341
## Build
@@ -47,14 +45,14 @@ There is one mandatory dependency on [coproto](https://github.com/Visa-Research/
4745
and three **optional dependencies** on [libsodium](https://doc.libsodium.org/),
4846
[Relic](https://github.com/relic-toolkit/relic), or
4947
[SimplestOT](https://github.com/osu-crypto/libOTe/tree/master/SimplestOT) (Unix only)
50-
for Base OTs.
48+
for Base OTs. [Boost Asio](https://www.boost.org/doc/libs/1_77_0/doc/html/boost_asio.html) tcp networking and [OpenSSL](https://www.openssl.org/) support can optionally be enabled.
5149
CMake 3.15+ is required and the build script assumes python 3.
5250

53-
The library can be built as
51+
The library can be built with libsodium, all OT protocols enabled and boost asio TCP networking as
5452
```
5553
git clone https://github.com/osu-crypto/libOTe.git
5654
cd libOTe
57-
python build.py --sodium --boost
55+
python build.py --all --boost --sodium
5856
```
5957
The main executable with examples is `frontend` and is located in the build directory, eg `out/build/linux/frontend/frontend.exe, out/build/x64-Release/frontend/Release/frontend.exe` depending on the OS.
6058

@@ -96,16 +94,33 @@ Dependencies can be managed by cmake/build.py or installed via an external tool.
9694
```
9795
python build.py --relic
9896
```
99-
Relic can be disabled by removing `--relic` from the setup and setting `-D ENABLE_RELIC=OFF`. Relic can always be fetched and locally built using `-D FETCH_RELIC=true`.
97+
Relic can be disabled by removing `--relic` from the setup and setting `-D ENABLE_RELIC=false`. This will always download and build relic. To only enable but not download relic, use `python build.py -D ENABLE_RELIC=true`.
10098

10199
**Enabling/Disabling [libsodium](https://github.com/osu-crypto/libsodium) (for base OTs):**
102100
The library can be built with libsodium as
103101
```
104102
python build.py --sodium
105103
```
106-
libsodium can be disabled by removing `--sodium` from the setup and setting `-D ENABLE_SODIUM=OFF`. Sodium can always be fetched and locally built using `-D FETCH_SODIUM=true`.
104+
libsodium can be disabled by removing `--sodium` from the setup and setting `-D ENABLE_SODIUM=false`. This will always download and build sodium. To only enable but not download relic, use `python build.py -D ENABLE_SODIUM=true`.
107105

108-
The McQuoid Rosulek Roy 2021 Base OTs uses a twisted curve which additionally require the `noclamp` option for Montgomery curves and is currently only in a [fork](https://github.com/osu-crypto/libsodium) of libsodium. If you prefer the stable libsodium, then install it and add `-D SODIUM_MONTGOMERY=OFF` as a cmake argument to libOTe.
106+
The McQuoid Rosulek Roy 2021 Base OTs uses a twisted curve which additionally require the `noclamp` option for Montgomery curves and is currently only in a [fork](https://github.com/osu-crypto/libsodium) of libsodium. If you prefer the stable libsodium, then install it and add `-D SODIUM_MONTGOMERY=false` as a cmake argument to libOTe.
107+
108+
109+
**Enabling/Disabling [boost asio](https://www.boost.org/doc/libs/1_77_0/doc/html/boost_asio.html) (for TCP networking):**
110+
The library can be built with boost as
111+
```
112+
python build.py --boost
113+
```
114+
boost can be disabled by removing `--boost` from the setup and setting `-D ENABLE_BOOST=false`. This will always download and build boost. To only enable but not download relic, use `python build.py -D ENABLE_BOOST=true`.
115+
116+
117+
118+
**Enabling/Disabling [OpenSSL](https://www.boost.org/doc/libs/1_77_0/doc/html/boost_asio.html) (for TLS networking):**
119+
The library can be built with boost as
120+
```
121+
python build.py --openssl
122+
```
123+
OpenSSL can be disabled by removing `--openssl` from the setup and setting `-D ENABLE_OPENSSL=false`. OpenSSL is never downloaded for you and is always found using your system installs.
109124

110125
## Install
111126

@@ -114,8 +129,7 @@ libOTe can be installed and linked the same way as other cmake projects. To inst
114129
python build.py --install
115130
```
116131

117-
118-
By default, sudo is not used. If installation requires sudo access, then add `--sudo` to the `build.py` script arguments. See `python build.py --help` for full details.
132+
Sudo is not used. If installation requires sudo access, then install as root. See `python build.py --help` for full details.
119133

120134

121135
## Linking
@@ -128,7 +142,40 @@ Other exposed targets are `oc::cryptoTools, oc::tests_cryptoTools, oc::libOTe_Te
128142

129143
To ensure that cmake can find libOTe, you can either install libOTe or build it locally and set `-D CMAKE_PREFIX_PATH=path/to/libOTe` or provide its location as a cmake `HINTS`, i.e. `find_package(libOTe HINTS path/to/libOTe)`.
130144

131-
145+
libOTe can be found with the following components:
146+
```
147+
find_package(libOTe REQUIRED
148+
COMPONENTS
149+
boost
150+
relic
151+
sodium
152+
bitpolymul
153+
openssl
154+
circuits
155+
sse
156+
avx
157+
asan
158+
pic
159+
no_sse
160+
no_avx
161+
no_asan
162+
no_pic
163+
simplestot
164+
simplestot_asm
165+
mrr
166+
mrr_twist
167+
mr
168+
mr_kyber
169+
kos
170+
iknp
171+
silentot
172+
softspoken_ot
173+
delta_kos
174+
silent_vole
175+
oos
176+
kkrt
177+
)
178+
```
132179

133180
## Help
134181

build.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,5 @@ def replace(argv, find, rep):
1717

1818
argv = sys.argv
1919
replace(argv, "--bitpolymul", "-DENABLE_SILENTOT=ON -DENABLE_BITPOLYMUL=ON")
20-
replace(argv, "--all", "-DENABLE_BITPOLYMUL=ON -DENABLE_SODIUM=ON -DENABLE_ALL_OT=ON")
21-
replace(argv, "--boost", "-DCOPROTO_ENABLE_BOOST=ON")
22-
replace(argv, "--openssl", "-DCOPROTO_ENABLE_OPENSSL=ON")
20+
replace(argv, "--all", "-DENABLE_ALL_OT=ON")
2321
cryptoTools.build.main("libOTe", argv[1:])

cryptoTools

frontend/ExampleMessagePassing.h

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
#include "cryptoTools/Common/CLP.h"
2+
#include "coproto/Socket/BufferingSocket.h"
3+
#include <fstream>
4+
#include "libOTe/TwoChooseOne/Silent/SilentOtExtReceiver.h"
5+
#include "libOTe/TwoChooseOne/Silent/SilentOtExtSender.h"
6+
7+
// This example demonstates how one can get and manually send the protocol messages
8+
// that are generated. This communicate method is one possible way of doing this.
9+
// It takes a protocol that has been started and coproto buffering socket as input.
10+
// It alternates between "sending" and "receiving" protocol messages. Instead of
11+
// sending the messages on a socket, this program writes them to a file and the other
12+
// party reads that file to get the message. In a real program the communication could
13+
// handled in any way the user decides.
14+
auto communicate(
15+
macoro::eager_task<>& protocol,
16+
bool sender,
17+
coproto::BufferingSocket& sock,
18+
bool verbose)
19+
{
20+
21+
int s = 0, r = 0;
22+
std::string me = sender ? "sender" : "recver";
23+
std::string them = !sender ? "sender" : "recver";
24+
25+
// write any outgoing data to a file me_i.bin where i in the message index.
26+
auto write = [&]()
27+
{
28+
// the the outbound messages that the protocol has generated.
29+
// This will consist of all the outbound messages that can be
30+
// generated without receiving the next inbound message.
31+
auto b = sock.getOutbound();
32+
33+
// If we do have outbound messages, then lets write them to a file.
34+
if (b && b->size())
35+
{
36+
std::ofstream message;
37+
auto temp = me + ".tmp";
38+
auto file = me + "_" + std::to_string(s) + ".bin";
39+
message.open(temp, std::ios::binary | std::ios::trunc);
40+
message.write((char*)b->data(), b->size());
41+
message.close();
42+
43+
if (verbose)
44+
{
45+
// optional for debug purposes.
46+
oc::RandomOracle hash(16);
47+
hash.Update(b->data(), b->size());
48+
oc::block h; hash.Final(h);
49+
50+
std::cout << me << " write " << std::to_string(s) << " " << h << "\n";
51+
}
52+
53+
if (rename(temp.c_str(), file.c_str()) != 0)
54+
std::cout << me << " file renamed failed\n";
55+
else if (verbose)
56+
std::cout << me << " file renamed successfully\n";
57+
58+
++s;
59+
}
60+
61+
};
62+
63+
// write incoming data from a file them_i.bin where i in the message index.
64+
auto read = [&]() {
65+
66+
std::ifstream message;
67+
auto file = them + "_" + std::to_string(r) + ".bin";
68+
while (message.is_open() == false)
69+
{
70+
message.open(file, std::ios::binary);
71+
if ((message.is_open() == false))
72+
std::this_thread::sleep_for(std::chrono::milliseconds(100));
73+
}
74+
75+
auto fsize = message.tellg();
76+
message.seekg(0, std::ios::end);
77+
fsize = message.tellg() - fsize;
78+
message.seekg(0, std::ios::beg);
79+
std::vector<oc::u8> buff(fsize);
80+
message.read((char*)buff.data(), fsize);
81+
message.close();
82+
std::remove(file.c_str());
83+
84+
if (verbose)
85+
{
86+
oc::RandomOracle hash(16);
87+
hash.Update(buff.data(), buff.size());
88+
oc::block h; hash.Final(h);
89+
90+
std::cout << me << " read " << std::to_string(r) << " " << h << "\n";
91+
}
92+
++r;
93+
94+
// This gives this socket the message which forwards it to the protocol and
95+
// run the protocol forward, possibly generating more outbound protocol
96+
// messages.
97+
sock.processInbound(buff);
98+
};
99+
100+
// The sender we generate the first message.
101+
if (!sender)
102+
write();
103+
104+
// While the protocol is not done we alternate between reading and writing messages.
105+
while (protocol.is_ready() == false)
106+
{
107+
read();
108+
write();
109+
}
110+
}
111+
112+
void messagePassingExampleRun(oc::CLP& cmd)
113+
{
114+
#ifdef ENABLE_SILENTOT
115+
auto isReceiver = cmd.get<int>("r");
116+
117+
// The number of OTs.
118+
auto n = cmd.getOr("n", 100);
119+
120+
auto verbose = cmd.isSet("v");
121+
122+
// A buffering socket. This socket type internally buffers the
123+
// protocol messages. It is then up to the user to manually send
124+
// and receive messages via the getOutbond(...) and processInbount(...)
125+
// methods.
126+
coproto::BufferingSocket sock;
127+
128+
// randomness source
129+
PRNG prng(oc::sysRandomSeed());
130+
131+
// Sets are always represented as 16 byte values. To support longer elements one can hash them.
132+
if (!isReceiver)
133+
{
134+
oc::SilentOtExtSender sender;
135+
136+
std::vector<std::array<block, 2>> senderOutput(n);
137+
138+
139+
if (verbose)
140+
std::cout << "sender start\n";
141+
142+
// Eagerly start the protocol. This will run the protocol up to the point
143+
// that it need to receive a message from the other party.
144+
auto protocol =
145+
sender.silentSend(senderOutput, prng, sock)
146+
| macoro::make_eager();
147+
148+
// Perform the communication and complete the protocol.
149+
communicate(protocol, true, sock, verbose);
150+
151+
std::cout << "sender done\n";
152+
153+
for (u64 i = 0; i < std::min<u64>(10, n); ++i)
154+
std::cout << "sender.msg[" << i << "] = { " << senderOutput[i][0] << ", " << senderOutput[i][1] << "}" << std::endl;
155+
if (n > 10)
156+
std::cout << "..." << std::endl;
157+
}
158+
else
159+
{
160+
std::vector<block> receiverOutputMsg(n);
161+
oc::BitVector receiverOutputBits(n);
162+
163+
oc::SilentOtExtReceiver receiver;
164+
165+
if (verbose)
166+
std::cout << "recver start\n";
167+
168+
// Eagerly start the protocol. This will run the protocol up to the point
169+
// that it need to receive a message from the other party.
170+
auto protocol =
171+
receiver.silentReceive(receiverOutputBits, receiverOutputMsg, prng, sock)
172+
| macoro::make_eager();
173+
174+
// Perform the communication and complete the protocol.
175+
communicate(protocol, false, sock, verbose);
176+
177+
std::cout << "recver done\n";
178+
179+
for (u64 i = 0; i < std::min<u64>(10, n); ++i)
180+
std::cout << "receiver.msg[" << i << "] = " << receiverOutputMsg[i] << " = sender.msg["<<i <<"][" << receiverOutputBits[i] << "]" << std::endl;
181+
if (n > 10)
182+
std::cout << "..." << std::endl;
183+
}
184+
#else
185+
std::cout << "ENABLE_SILENTOT is not defined. Rebuilt with -DENABLE_SILENTOT=true" << std::endl;
186+
#endif
187+
}
188+
189+
190+
void messagePassingExample(oc::CLP& cmd)
191+
{
192+
// If the user specified -r, then run that party.
193+
// Otherwise run both parties.
194+
if (cmd.hasValue("r"))
195+
{
196+
messagePassingExampleRun(cmd);
197+
}
198+
else
199+
{
200+
auto s = cmd;
201+
s.setDefault("r", 0);
202+
cmd.setDefault("r", 1);
203+
auto a = std::async([&]() {messagePassingExampleRun(s); });
204+
messagePassingExampleRun(cmd);
205+
a.get();
206+
}
207+
}
208+

0 commit comments

Comments
 (0)