Low-Level Interface¶
In the following we will explain the basic of the C++ interface by
walking trough Utils/paper-example.cpp
.
template<class T>
void run(char** argv, int prime_length);
MP-SPDZ heavily uses templating to allow to reuse code between
different protocols. run()
is a simple example of this. The
entire virtual machine in the Processor
directory is built on
the same principle. The central type is a type representing a share in
a particular type.
// bit length of prime
const int prime_length = 128;
// compute number of 64-bit words needed
const int n_limbs = (prime_length + 63) / 64;
Computation modulo a prime requires to fix the number of limbs (64-bit words) at compile time. This allows for optimal memory usage and computation.
if (protocol == "MASCOT")
run<Share<gfp_<0, n_limbs>>>(argv, prime_length);
else if (protocol == "CowGear")
run<CowGearShare<gfp_<0, n_limbs>>>(argv, prime_length);
Share types for computation module a prime (and in
\(\mathrm{GF}(2^n)\)) generally take one parameter for the
computation domain. gfp_
in turn takes two parameters, a
counter and the number of limbs. The counter allows to use several
instances with different parameters. It can be chosen freely, but the
convention is to use 0 for the online phase and 1 for the offline
phase where required.
else if (protocol == "SPDZ2k")
run<Spdz2kShare<64, 64>>(argv, 0);
Share types for computation modulo a power of two simply take the exponent as parameter, and some take an additional security parameter.
int my_number = atoi(argv[1]);
int n_parties = atoi(argv[2]);
int port_base = 9999;
Names N(my_number, n_parties, "localhost", port_base);
All implemented protocols require point-to-point connections between
all parties. Names
objects represent a setup of hostnames and
IPs used to set up the actual
connections. The chosen initialization provides a way where
every party connects to party 0 on a specified location (localhost in
this case), which then broadcasts the locations of all parties. The
base port number is used to derive the port numbers for the parties to
listen on (base + party number). See the the Names
class for
other possibilities such as a text file containing hostname and port
number for each party.
CryptoPlayer P(N);
The networking setup is used to set up the actual
connections. CryptoPlayer
uses encrypted connection while
PlainPlayer
does not. If you use several instances (for
several threads for example), you must use an integer identifier as
the second parameter, which must differ from any other by at least the
number of parties.
ProtocolSetup<T> setup(P, prime_length);
We have to use a specific prime for computation modulo a prime. This deterministically generates one of the desired length if necessary. For computation modulo a power of two, this does not do anything. Some protocols use an information-theoretic tag that is constant throughout the protocol. This code reads it from storage if available or generates a fresh one otherwise.
ProtocolSet<T> set(P, setup);
auto& input = set.input;
auto& protocol = set.protocol;
auto& output = set.output;
The ProtocolSet
contains one instance for every essential
protocol step.
int n = 1000;
vector<T> a(n), b(n);
T c;
typename T::clear result;
Remember that T
stands for a share in the protocol. The
derived type T::clear
stands for the cleartext domain. Share
types support linear operations such as addition, subtraction, and
multiplication with a constant. Use T::constant()
to convert a
constant to a share type.
input.reset_all(P);
for (int i = 0; i < n; i++)
input.add_from_all(i);
input.exchange();
for (int i = 0; i < n; i++)
{
a[i] = input.finalize(0);
b[i] = input.finalize(1);
}
The interface for all protocols proceeds in four stages:
Initialization. This is required to initialize and reset data structures in consecutive use.
Local data preparation
Communication
Output extraction
This blueprint allows for a minimal number of communication rounds.
protocol.init_dotprod(&processor);
for (int i = 0; i < n; i++)
protocol.prepare_dotprod(a[i], b[i]);
protocol.next_dotprod();
protocol.exchange();
c = protocol.finalize_dotprod(n);
The initialization of the multiplication sets the preprocessing and
output instances to use in Beaver multiplication. next_dotprod()
separates dot products in the data preparation phase.
protocol.check();
Some protocols require a check of all multiplications up to a certain point. To guarantee that outputs do not reveal secret information, it has to be run before using the output protocol.
output.init_open(P);
output.prepare_open(c);
output.exchange(P);
result = output.finalize_open();
cout << "result: " << result << endl;
output.Check(P);
The output protocol follows the same blueprint as the multiplication protocol.
T::LivePrep::teardown();
This frees the memory used for global key material when using homomorphic encryption. Otherwise, this does not do anything.
Domain Types¶
|
Computation modulo a prime. |
|
Computation modulo \(2^K\). This is not a field. |
|
\(GF(2^n)\). |
Protocol Setup¶
-
template<class T>
class ProtocolSetup¶ Global setup for an arithmetic share type
Subclassed by MixedProtocolSetup< T >
-
template<class T>
class ProtocolSet¶ Input, multiplication, and output protocol instance for an arithmetic share type
Public Functions
-
inline ProtocolSet(Player &P, const ProtocolSetup<T> &setup)¶
- Parameters
P – communication instance
setup – one-time setup instance
-
inline ProtocolSet(Player &P, const ProtocolSetup<T> &setup)¶
-
template<class T>
class BinaryProtocolSetup¶ Global setup for a binary share type
-
template<class T>
class BinaryProtocolSet¶ Input, multiplication, and output protocol instance for a binary share type
Public Functions
-
inline BinaryProtocolSet(Player &P, const BinaryProtocolSetup<T> &setup)¶
- Parameters
P – communication instance
setup – one-time setup instance
-
inline BinaryProtocolSet(Player &P, const BinaryProtocolSetup<T> &setup)¶
-
template<class T>
class MixedProtocolSetup : public ProtocolSetup<T>¶ Global setup for an arithmetic share type and the corresponding binary one
-
template<class T>
class MixedProtocolSet¶ Input, multiplication, and output protocol instance for an arithmetic share type and the corresponding binary one
Public Functions
-
inline MixedProtocolSet(Player &P, const MixedProtocolSetup<T> &setup)¶
- Parameters
P – communication instance
setup – one-time setup instance
-
inline MixedProtocolSet(Player &P, const MixedProtocolSetup<T> &setup)¶
Protocol Interfaces¶
-
template<class T>
class ProtocolBase¶ Abstract base class for multiplication protocols
Subclassed by Replicated< T >
Public Functions
-
inline virtual void init(Preprocessing<T>&, typename T::MAC_Check&)¶
Initialize protocol if needed (repeated call possible)
-
virtual void init_mul() = 0¶
Initialize multiplication round.
-
virtual void prepare_mul(const T &x, const T &y, int n = -1) = 0¶
Schedule multiplication of operand pair.
-
virtual void exchange() = 0¶
Run multiplication protocol.
-
inline void init_dotprod()¶
Initialize dot product round.
-
inline void next_dotprod()¶
Finish dot product.
-
inline virtual void init(Preprocessing<T>&, typename T::MAC_Check&)¶
-
template<class T>
class InputBase¶ Abstract base for input protocols
Subclassed by Input< T >
Public Functions
-
virtual void reset(int player) = 0¶
Initialize input round for
player
-
virtual void add_mine(const typename T::open_type &input, int n_bits = -1) = 0¶
Schedule input from me.
-
virtual void add_other(int player, int n_bits = -1) = 0¶
Schedule input from other player.
-
void add_from_all(const clear &input, int n_bits = -1)¶
Schedule input from all players.
-
virtual void send_mine() = 0¶
Send my inputs.
-
virtual void exchange()¶
Run input protocol for all players.
-
virtual void finalize_other(int player, T &target, octetStream &o, int n_bits = -1) = 0¶
Store share for next input from
player
from buffero
intarget
-
virtual void reset(int player) = 0¶
-
template<class T>
class MAC_Check_Base¶ Abstract base class for opening protocols
-
template<class T>
class Preprocessing : public PrepBase¶ Abstract base class for preprocessing
Subclassed by BufferPrep< T >, Sub_Data_Files< T >
-
template<class T>
class BufferPrep : public Preprocessing<T>¶ Abstract base class for live preprocessing
Subclassed by BitPrep< T >