Backend

The backend/ directory bridges ORQ’s core MPC logic with runtime services such as task scheduling, networking, and memory management.

Sub-directories & files:

  • common/ – General-purpose runtime, task, and benchmark helpers.

  • null_communicator/ – Null service setup

  • nocopy_communicator/ – TCP-based service setup

  • service.h – Umbrella header for all service components.

Setup

namespace orq
namespace service

Functions

template<typename ProtocolFactory, typename CommunicatorFactory>
void orq_runtime_init(int argc, char **argv, const int &partiesNum, const std::vector<std::set<int>> &groups)
namespace mpi_service
namespace fantastic_4pc

Functions

init_mpc_types (int, orq::Vector, std::vector, orq::EVector, 3)
init_mpc_system(orq::MPICommunicator, orq::random::PRGAlgorithm, orq::Fantastic_4PC, orq::Fantastic_4PC_Factory)
init_mpc_functions (3)
void orq_init(int argc, char **argv)
namespace replicated_3pc

Functions

init_mpc_types (int, orq::Vector, std::vector, orq::EVector, 2)
init_mpc_system(orq::MPICommunicator, orq::random::PRGAlgorithm, orq::Replicated_3PC, orq::Replicated_3PC_Factory)
init_mpc_functions (2)
void orq_init(int argc, char **argv)
namespace nocopy_service
namespace fantastic_4pc

Functions

init_mpc_types (int, orq::Vector, std::vector, orq::EVector, 3)
init_mpc_system(orq::NoCopyCommunicator, orq::random::PRGAlgorithm, orq::Fantastic_4PC, orq::Fantastic_4PC_Factory)
init_mpc_functions (3)
void orq_init(int argc, char **argv)
namespace replicated_3pc

Functions

init_mpc_types (int, orq::Vector, std::vector, orq::EVector, 2)
init_mpc_system(orq::NoCopyCommunicator, orq::random::PRGAlgorithm, orq::Replicated_3PC, orq::Replicated_3PC_Factory)
init_mpc_functions (2)
void orq_init(int argc, char **argv)
namespace orq
namespace service

Typedefs

using cg_map_t = std::map<std::tuple<std::type_index, orq::random::Correlation>, orq::random::CorrelationGenerator*>

Type alias for the correlation generator map: {type, Correlation} -> Correlation Generator.

Functions

void create_common_prg_among_group(int rank, std::set<int> group, std::shared_ptr<orq::random::CommonPRGManager> commonPRGManager)

Utility function to setup a CommonPRG among a group.

Parameters:
  • rank – The absolute rank of the current party.

  • group – The group that shares the CommonPRG.

  • commonPRGManager – The CommonPRGManager to add the new CommonPRG to.

void setup_3pc_common_prgs(int rank, std::shared_ptr<orq::random::CommonPRGManager> commonPRGManager)

Setup the Common PRGs for replicated 3PC.

Parameters:
  • rank

  • commonPRGManager

void setup_4pc_common_prgs(int rank, std::shared_ptr<orq::random::CommonPRGManager> commonPRGManager)

Setup the Common PRGs for Fantastic 4PC.

Parameters:
  • rank

  • commonPRGManager

void setup_2pc_common_prgs(int rank, std::shared_ptr<orq::random::CommonPRGManager> commonPRGManager)

Setup the Common PRGs for Beaver 2PC.

Parameters:
  • rank

  • commonPRGManager

auto setup_random_generation(int num_parties, int rank, std::vector<std::set<int>> groups, int thread)

General randomness-generation setup.

Parameters:
  • num_parties

  • rank

  • groups

  • thread

Returns:

auto

Workers

Defines

MINIMUM_CHUNK_SIZE

Do not give any thread less than this amount of work (unless that’s all that’s left)

Developers may specify at compile time, in which case this default is ignore.

NOTE: this MUST be a multiple of 128 due to some internal alignment requirements.

namespace orq
namespace service
class Task
#include <task.h>

A parent class representing the runtime’s fundamental unit of single-threaded computation. For a single call into the runtime (e.g. MPC functionality), each worker gets one Task; a task is further divided into batches according to the user-specified batch size.

Subclassed by orq::service::Task_0_void, orq::service::Task_1_pair< In, Ret, T >, orq::service::Task_1_ref< In, Ret, T >, orq::service::Task_1_void< In >, orq::service::Task_1_void_nobatch< In >, orq::service::Task_2_Agg_ref< In, Ret, T >, orq::service::Task_2_ref< In, Ret, T >, orq::service::Task_2_void< In >

Public Functions

inline Task(size_t _start, size_t _end, ssize_t _batch_size)

Construct a new Task object; if negative batch size (even division), compute actual batch size for this worker.

Parameters:
  • _start

  • _end

  • _batch_size

inline virtual ~Task()
virtual void sub_execute(size_t, size_t) = 0

Tasks will overload this function with their specific workload. It will be called once per batch.

inline void execute()

Execute a series of batched tasks using calls to sub_execute.

Protected Attributes

size_t start
size_t end
ssize_t batch_size
class Task_0_void : public orq::service::Task
#include <task.h>

A Task which takes zero inputs and returns void. This is used when maximum flexibility is necessary; e.g. generating triples and execute_parallel_unsafe.

Public Functions

inline Task_0_void(const size_t _start, const size_t _end, const ssize_t _batch_size, std::function<void(const size_t, const size_t)> _func)
inline virtual void sub_execute(size_t start, size_t end) override

Tasks will overload this function with their specific workload. It will be called once per batch.

Private Members

std::function<void(const size_t, const size_t)> func
template<typename In, typename Ret, typename ...T>
class Task_1_pair : public orq::service::Task
#include <task.h>

A Task which takes 1 input and returns a pair.

Template Parameters:
  • In – The type of the input.

  • Ret – The type of each result.

Public Functions

inline Task_1_pair(const In &_x, std::pair<Ret, Ret> &_r, const size_t _start, const size_t _end, const ssize_t _batch_size, std::function<void(In&, Ret&, Ret&)> _func)
inline virtual void sub_execute(size_t start, size_t end) override

The main function which executes the task’s function in batches.

Private Members

In x
std::pair<Ret, Ret> r
std::function<void(In&, Ret&, Ret&)> func
template<typename In, typename Ret, typename ...T>
class Task_1_ref : public orq::service::Task
#include <task.h>

A Task which takes one input and returns via passed reference

Template Parameters:
  • In – The type of the input.

  • Ret – The type of the result.

Public Functions

inline Task_1_ref(const In &_x, Ret &_res, const size_t _start, const size_t _end, const ssize_t _batch_size, std::function<void(In&, Ret&)> _func)
inline virtual void sub_execute(size_t start, size_t end) override

Tasks will overload this function with their specific workload. It will be called once per batch.

Private Members

In x
Ret res
std::function<void(In&, Ret&)> func
template<typename In>
class Task_1_void : public orq::service::Task
#include <task.h>

A Task which takes one input and returns nothing.

Template Parameters:

In – The type of the input.

Public Functions

inline Task_1_void(const In &_x, const size_t _start, const size_t _end, const ssize_t _batch_size, std::function<void(In&)> _func)
inline virtual void sub_execute(size_t start, size_t end) override

Tasks will overload this function with their specific workload. It will be called once per batch.

Private Members

In x
std::function<void(In&)> func
template<typename In>
class Task_1_void_nobatch : public orq::service::Task
#include <task.h>

A Task which takes one input and returns nothing, and also has no batching. Currently used for permutation generation.

Template Parameters:

In – The type of the input.

Public Functions

inline Task_1_void_nobatch(const In &_x, std::function<void(In&)> _func)
inline virtual void sub_execute(size_t start, size_t end) override

Tasks will overload this function with their specific workload. It will be called once per batch.

Private Members

In x
std::function<void(In&)> func
template<typename In, typename Ret, typename ...T>
class Task_2_Agg_ref : public orq::service::Task
#include <task.h>

A Task which takes two inputs and returns via passed reference, but aggregates the results into a smaller output vector.

Template Parameters:
  • In – The type of both inputs.

  • Ret – The type of the result.

Public Functions

inline Task_2_Agg_ref(const In &_x, const In &_y, Ret &_res, const size_t _start, const size_t _end, const ssize_t _batch_size, const size_t &_agg_size, std::function<void(In&, In&, Ret&)> _func)
inline virtual void sub_execute(size_t start, size_t end) override

Tasks will overload this function with their specific workload. It will be called once per batch.

Private Members

In x
In y
Ret res
const size_t agg_size
std::function<void(In&, In&, Ret&)> func
template<typename In, typename Ret, typename ...T>
class Task_2_ref : public orq::service::Task
#include <task.h>

A Task which takes two inputs and returns via passed reference

Identical to Task_1_ref but with 2 arguments to the function.

Template Parameters:
  • In – The type of both inputs.

  • Ret – The type of the result.

Public Functions

inline Task_2_ref(const In &_x, const In &_y, Ret &_res, const size_t _start, const size_t _end, const ssize_t _batch_size, std::function<void(In&, In&, Ret&)> _func)
inline virtual void sub_execute(size_t start, size_t end) override

Tasks will overload this function with their specific workload. It will be called once per batch.

Private Members

In x
In y
Ret res
std::function<void(In&, In&, Ret&)> func
template<typename In>
class Task_2_void : public orq::service::Task
#include <task.h>

A Task which takes two inputs and returns nothing

Identical to Task_ARGS_VOID_1 but with 2 arguments to the function.

Template Parameters:

In – The type of both inputs.

Public Functions

inline Task_2_void(const In &_x, const In &_y, const size_t _start, const size_t _end, const ssize_t _batch_size, std::function<bool(In&, In&)> _func)
inline virtual void sub_execute(size_t start, size_t end) override

The main function which executes the task’s function in batches.

Private Members

In x
In y
std::function<bool(In&, In&)> func

A class which encapsulates a single worker thread.

namespace orq
namespace service
class Worker
#include <worker.h>

Public Functions

inline Worker(int rank, std::shared_ptr<std::barrier<>> barrier)
Worker(Worker&&) = default
Worker &operator=(Worker&&) = default
Worker(const Worker&) = delete
Worker &operator=(const Worker&) = delete
inline ~Worker()
inline void start()
inline void addTask(std::unique_ptr<Task> &&t)

Called by the main thread to enqueue a task for this worker. Once task is added, this worker is notified.

Parameters:

t

inline void stop()
inline bool malicious_check(const bool should_abort)
inline void print_statistics()
inline orq::random::RandomnessManager *getRandManager() const
inline orq::Communicator *getCommunicator() const
template<typename T, typename PF>
inline void init_proto(PF &pf)
inline void attach(std::unique_ptr<Communicator> &&c, std::unique_ptr<orq::random::RandomnessManager> &&r)

Attach a new communicator and randomness manager instance to this worker.

Parameters:
  • c

  • r

inline void attach_comm(std::unique_ptr<Communicator> &&c)

Attach a new communicator instance to this worker. Use this method when the randomness manager for the given protocol requires communication to be instantiated first.

Parameters:

c

inline void attach_rand(std::unique_ptr<orq::random::RandomnessManager> &&r)

Attach a new randomness manager to this worker. Use this method when the randomness manager for the given protocol requires communication to be instantiated first.

Parameters:

r

Public Members

std::unique_ptr<ProtocolBase> proto_8
std::unique_ptr<ProtocolBase> proto_16
std::unique_ptr<ProtocolBase> proto_32
std::unique_ptr<ProtocolBase> proto_64
std::unique_ptr<ProtocolBase> proto_128

Private Functions

inline void run()

Private Members

std::unique_ptr<Communicator> comm_
std::unique_ptr<orq::random::RandomnessManager> rand_
std::queue<std::unique_ptr<Task>> q_
int rank_
std::unique_ptr<std::mutex> m_
std::unique_ptr<std::condition_variable> cv_
std::shared_ptr<std::barrier<>> b_
std::thread thread_
bool terminate_

Runtime

Defines

DEFAULT_BATCH_SIZE

The default batch size for normal batching, if not specified by the user.

From 2024-Nov experiments on AWS, -12 looks to be a good default.

EVectorClass(T)

Helper macro to get the current execution’s EVector class of type T

define_reshare(S)

Macro to generate evaluator for reshare

define_1_alloc(S, F, InT, OutT)

Macro to generate evaluator for single-argument functions which allocate their own output storage, like secret_share

define_1_pair(S, F, InT, OutT)

Macro to generate evaluator for single-argument functions which return a pair, like div_const_a

define_1_arg(S, F, InT, OutT)

Macro to generate evaluator for single-argument functions.

define_2_arg(S, F, InT, OutT)

Macro to generate evaluator for two-argument functions.

define_2_arg_aggregator(S, F, InT, OutT)

Macro to generate evaluator for two-argument functions which return a differently-sized output.

runtime_declare_protocol_functions(T)

Macro to define all runtime-protocol functionalities.

namespace orq
namespace random
namespace service

Functions

bool RunTimeRunning()

Check if the runTime is running.

Returns:

true

Returns:

false

Variables

static std::unique_ptr<RunTime> runTime

Static storage of the singleton runTime.

class RunTime
#include <runtime.h>

Public Functions

inline orq::Communicator *comm0()

Get worker zero’s communicator.

Returns:

orq::Communicator*

inline orq::random::RandomnessManager *rand0()

Get worker zero’s randomness manager.

Returns:

orq::random::RandomnessManager*

inline bool terminated()

Check if this runtime is terminated.

Returns:

true

Returns:

false

inline ~RunTime()

Destructor. Set termiante_ to true, and wait for all socket communicator threads to be joined.

inline RunTime(const long _batch_size = -12, const int _num_threads = 1, bool testing = false)

Construct a new Runtime object.

Parameters:
  • _batch_size

  • _num_threads

  • testing – change to true if creating additional RunTime objects inside tests

inline void setup_workers(int rank)

Setup the thread workers for this party.

Parameters:

rank

template<typename ...T>
inline void emplace_socket_thread(T&&... t)

Create a socket communicator thread and it to the runtime’s internal store.

Template Parameters:

T

Parameters:

t

template<int R, typename ...T>
inline void add_a(EVector<int8_t, R> x, EVector<int8_t, R> y, EVector<int8_t, R> &r, const T&... args)

Declare protocol functionalities for each supported type.

template<int R, typename ...T>
inline void sub_a(EVector<int8_t, R> x, EVector<int8_t, R> y, EVector<int8_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void multiply_a(EVector<int8_t, R> x, EVector<int8_t, R> y, EVector<int8_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void neg_a(EVector<int8_t, R> x, EVector<int8_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void xor_b(EVector<int8_t, R> x, EVector<int8_t, R> y, EVector<int8_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void dot_product_a(EVector<int8_t, R> x, EVector<int8_t, R> y, EVector<int8_t, R> &r, const size_t &agg, const T&... args)
template<int R, typename ...T>
inline void and_b(EVector<int8_t, R> x, EVector<int8_t, R> y, EVector<int8_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void not_b(EVector<int8_t, R> x, EVector<int8_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void not_b_1(EVector<int8_t, R> x, EVector<int8_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void ltz(EVector<int8_t, R> x, EVector<int8_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void b2a_bit(EVector<int8_t, R> x, EVector<int8_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void reshare(EVector<int8_t, R> &x, const T&... args)
template<int R, typename ...T>
inline void reconstruct_from_a(orq::Vector<int8_t> x, std::vector<EVector<int8_t, R>> &r, const T&... args)
template<int R, typename ...T>
inline void reconstruct_from_b(orq::Vector<int8_t> x, std::vector<EVector<int8_t, R>> &r, const T&... args)
template<int R, typename ...T>
inline orq::Vector<int8_t> open_shares_a(EVector<int8_t, R> x, const T&... args)
template<int R, typename ...T>
inline orq::Vector<int8_t> open_shares_b(EVector<int8_t, R> x, const T&... args)
template<int R, typename ...T>
inline EVector<int8_t, R> secret_share_a(orq::Vector<int8_t> x, const T&... args)
template<int R, typename ...T>
inline EVector<int8_t, R> secret_share_b(orq::Vector<int8_t> x, const T&... args)
template<int R, typename ...T>
inline EVector<int8_t, R> public_share(orq::Vector<int8_t> x, const T&... args)
template<int R, typename ...T>
inline std::pair<EVector<int8_t, R>, EVector<int8_t, R>> div_const_a(EVector<int8_t, R> x, const T&... args)
template<int R, typename ...T>
inline std::pair<EVector<int8_t, R>, EVector<int8_t, R>> redistribute_shares_b(EVector<int8_t, R> x, const T&... args)
template<int R, typename ...T>
inline void add_a(EVector<int16_t, R> x, EVector<int16_t, R> y, EVector<int16_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void sub_a(EVector<int16_t, R> x, EVector<int16_t, R> y, EVector<int16_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void multiply_a(EVector<int16_t, R> x, EVector<int16_t, R> y, EVector<int16_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void neg_a(EVector<int16_t, R> x, EVector<int16_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void xor_b(EVector<int16_t, R> x, EVector<int16_t, R> y, EVector<int16_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void dot_product_a(EVector<int16_t, R> x, EVector<int16_t, R> y, EVector<int16_t, R> &r, const size_t &agg, const T&... args)
template<int R, typename ...T>
inline void and_b(EVector<int16_t, R> x, EVector<int16_t, R> y, EVector<int16_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void not_b(EVector<int16_t, R> x, EVector<int16_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void not_b_1(EVector<int16_t, R> x, EVector<int16_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void ltz(EVector<int16_t, R> x, EVector<int16_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void b2a_bit(EVector<int16_t, R> x, EVector<int16_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void reshare(EVector<int16_t, R> &x, const T&... args)
template<int R, typename ...T>
inline void reconstruct_from_a(orq::Vector<int16_t> x, std::vector<EVector<int16_t, R>> &r, const T&... args)
template<int R, typename ...T>
inline void reconstruct_from_b(orq::Vector<int16_t> x, std::vector<EVector<int16_t, R>> &r, const T&... args)
template<int R, typename ...T>
inline orq::Vector<int16_t> open_shares_a(EVector<int16_t, R> x, const T&... args)
template<int R, typename ...T>
inline orq::Vector<int16_t> open_shares_b(EVector<int16_t, R> x, const T&... args)
template<int R, typename ...T>
inline EVector<int16_t, R> secret_share_a(orq::Vector<int16_t> x, const T&... args)
template<int R, typename ...T>
inline EVector<int16_t, R> secret_share_b(orq::Vector<int16_t> x, const T&... args)
template<int R, typename ...T>
inline EVector<int16_t, R> public_share(orq::Vector<int16_t> x, const T&... args)
template<int R, typename ...T>
inline std::pair<EVector<int16_t, R>, EVector<int16_t, R>> div_const_a(EVector<int16_t, R> x, const T&... args)
template<int R, typename ...T>
inline std::pair<EVector<int16_t, R>, EVector<int16_t, R>> redistribute_shares_b(EVector<int16_t, R> x, const T&... args)
template<int R, typename ...T>
inline void add_a(EVector<int32_t, R> x, EVector<int32_t, R> y, EVector<int32_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void sub_a(EVector<int32_t, R> x, EVector<int32_t, R> y, EVector<int32_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void multiply_a(EVector<int32_t, R> x, EVector<int32_t, R> y, EVector<int32_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void neg_a(EVector<int32_t, R> x, EVector<int32_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void xor_b(EVector<int32_t, R> x, EVector<int32_t, R> y, EVector<int32_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void dot_product_a(EVector<int32_t, R> x, EVector<int32_t, R> y, EVector<int32_t, R> &r, const size_t &agg, const T&... args)
template<int R, typename ...T>
inline void and_b(EVector<int32_t, R> x, EVector<int32_t, R> y, EVector<int32_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void not_b(EVector<int32_t, R> x, EVector<int32_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void not_b_1(EVector<int32_t, R> x, EVector<int32_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void ltz(EVector<int32_t, R> x, EVector<int32_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void b2a_bit(EVector<int32_t, R> x, EVector<int32_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void reshare(EVector<int32_t, R> &x, const T&... args)
template<int R, typename ...T>
inline void reconstruct_from_a(orq::Vector<int32_t> x, std::vector<EVector<int32_t, R>> &r, const T&... args)
template<int R, typename ...T>
inline void reconstruct_from_b(orq::Vector<int32_t> x, std::vector<EVector<int32_t, R>> &r, const T&... args)
template<int R, typename ...T>
inline orq::Vector<int32_t> open_shares_a(EVector<int32_t, R> x, const T&... args)
template<int R, typename ...T>
inline orq::Vector<int32_t> open_shares_b(EVector<int32_t, R> x, const T&... args)
template<int R, typename ...T>
inline EVector<int32_t, R> secret_share_a(orq::Vector<int32_t> x, const T&... args)
template<int R, typename ...T>
inline EVector<int32_t, R> secret_share_b(orq::Vector<int32_t> x, const T&... args)
template<int R, typename ...T>
inline EVector<int32_t, R> public_share(orq::Vector<int32_t> x, const T&... args)
template<int R, typename ...T>
inline std::pair<EVector<int32_t, R>, EVector<int32_t, R>> div_const_a(EVector<int32_t, R> x, const T&... args)
template<int R, typename ...T>
inline std::pair<EVector<int32_t, R>, EVector<int32_t, R>> redistribute_shares_b(EVector<int32_t, R> x, const T&... args)
template<int R, typename ...T>
inline void add_a(EVector<int64_t, R> x, EVector<int64_t, R> y, EVector<int64_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void sub_a(EVector<int64_t, R> x, EVector<int64_t, R> y, EVector<int64_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void multiply_a(EVector<int64_t, R> x, EVector<int64_t, R> y, EVector<int64_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void neg_a(EVector<int64_t, R> x, EVector<int64_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void xor_b(EVector<int64_t, R> x, EVector<int64_t, R> y, EVector<int64_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void dot_product_a(EVector<int64_t, R> x, EVector<int64_t, R> y, EVector<int64_t, R> &r, const size_t &agg, const T&... args)
template<int R, typename ...T>
inline void and_b(EVector<int64_t, R> x, EVector<int64_t, R> y, EVector<int64_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void not_b(EVector<int64_t, R> x, EVector<int64_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void not_b_1(EVector<int64_t, R> x, EVector<int64_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void ltz(EVector<int64_t, R> x, EVector<int64_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void b2a_bit(EVector<int64_t, R> x, EVector<int64_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void reshare(EVector<int64_t, R> &x, const T&... args)
template<int R, typename ...T>
inline void reconstruct_from_a(orq::Vector<int64_t> x, std::vector<EVector<int64_t, R>> &r, const T&... args)
template<int R, typename ...T>
inline void reconstruct_from_b(orq::Vector<int64_t> x, std::vector<EVector<int64_t, R>> &r, const T&... args)
template<int R, typename ...T>
inline orq::Vector<int64_t> open_shares_a(EVector<int64_t, R> x, const T&... args)
template<int R, typename ...T>
inline orq::Vector<int64_t> open_shares_b(EVector<int64_t, R> x, const T&... args)
template<int R, typename ...T>
inline EVector<int64_t, R> secret_share_a(orq::Vector<int64_t> x, const T&... args)
template<int R, typename ...T>
inline EVector<int64_t, R> secret_share_b(orq::Vector<int64_t> x, const T&... args)
template<int R, typename ...T>
inline EVector<int64_t, R> public_share(orq::Vector<int64_t> x, const T&... args)
template<int R, typename ...T>
inline std::pair<EVector<int64_t, R>, EVector<int64_t, R>> div_const_a(EVector<int64_t, R> x, const T&... args)
template<int R, typename ...T>
inline std::pair<EVector<int64_t, R>, EVector<int64_t, R>> redistribute_shares_b(EVector<int64_t, R> x, const T&... args)
template<int R, typename ...T>
inline void add_a(EVector<__int128_t, R> x, EVector<__int128_t, R> y, EVector<__int128_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void sub_a(EVector<__int128_t, R> x, EVector<__int128_t, R> y, EVector<__int128_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void multiply_a(EVector<__int128_t, R> x, EVector<__int128_t, R> y, EVector<__int128_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void neg_a(EVector<__int128_t, R> x, EVector<__int128_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void xor_b(EVector<__int128_t, R> x, EVector<__int128_t, R> y, EVector<__int128_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void dot_product_a(EVector<__int128_t, R> x, EVector<__int128_t, R> y, EVector<__int128_t, R> &r, const size_t &agg, const T&... args)
template<int R, typename ...T>
inline void and_b(EVector<__int128_t, R> x, EVector<__int128_t, R> y, EVector<__int128_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void not_b(EVector<__int128_t, R> x, EVector<__int128_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void not_b_1(EVector<__int128_t, R> x, EVector<__int128_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void ltz(EVector<__int128_t, R> x, EVector<__int128_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void b2a_bit(EVector<__int128_t, R> x, EVector<__int128_t, R> &r, const T&... args)
template<int R, typename ...T>
inline void reshare(EVector<__int128_t, R> &x, const T&... args)
template<int R, typename ...T>
inline void reconstruct_from_a(orq::Vector<__int128_t> x, std::vector<EVector<__int128_t, R>> &r, const T&... args)
template<int R, typename ...T>
inline void reconstruct_from_b(orq::Vector<__int128_t> x, std::vector<EVector<__int128_t, R>> &r, const T&... args)
template<int R, typename ...T>
inline orq::Vector<__int128_t> open_shares_a(EVector<__int128_t, R> x, const T&... args)
template<int R, typename ...T>
inline orq::Vector<__int128_t> open_shares_b(EVector<__int128_t, R> x, const T&... args)
template<int R, typename ...T>
inline EVector<__int128_t, R> secret_share_a(orq::Vector<__int128_t> x, const T&... args)
template<int R, typename ...T>
inline EVector<__int128_t, R> secret_share_b(orq::Vector<__int128_t> x, const T&... args)
template<int R, typename ...T>
inline EVector<__int128_t, R> public_share(orq::Vector<__int128_t> x, const T&... args)
template<int R, typename ...T>
inline std::pair<EVector<__int128_t, R>, EVector<__int128_t, R>> div_const_a(EVector<__int128_t, R> x, const T&... args)
template<int R, typename ...T>
inline std::pair<EVector<__int128_t, R>, EVector<__int128_t, R>> redistribute_shares_b(EVector<__int128_t, R> x, const T&... args)
template<typename ObjectType, typename ...T>
inline void execute_parallel(const ObjectType &x, ObjectType &res, ObjectType (ObjectType::* func)(const T&...) const, const T&... args)

Execute a non-MPC parallel functionality over a vector which puts the result into a new vector.

Template Parameters:
  • ObjectType

  • T

Parameters:
  • x

  • res

  • func

  • args

template<typename ObjectType, typename ...T1, typename ...T2>
inline void modify_parallel(ObjectType &x, void (ObjectType::* func)(const T1&..., const T2&...), const T1&... args1, const T2&... args2)

Execute a non-MPC parallel functionality over a vector which modifies the vector in place.

Template Parameters:
  • ObjectType

  • T1

  • T2

Parameters:
  • x

  • func

  • args1

  • args2

template<typename E1, typename E2>
inline void modify_parallel_2arg(E1 &x, const E2 &y, E1 &(E1::* func)(const E2&))

Execute a non-MPC member function over two batched elements. Useful for parallelizing vector copies, for example. Multithreaded equivalent to x.func(y) where x is modified but y is not.

This is similar to modify_parallel except that it applies batching to both input and output vectors, whereas modify_parallel assumes only the output vector x should have batching applied. A similar effect could be achieved with execute_parallel, but this would incur an unecessary copy.

This function has two separate template arguments to account for the fact that some functions (such as the copy-and-cast assignment operator) may accept EVectors of different types.

Template Parameters:
Parameters:
  • x

  • y

  • func

inline void execute_parallel_unsafe(const int &range_size, std::function<void(const size_t, const size_t)> func)

Execute an arbitrary function (probably passed as a lambda) in a multithreaded argument. Passed function should only take two arguments representing the start and end indices of its batch.

Parameters:
  • range_size

  • func

template<typename InputType, typename ...T>
inline void generate_parallel(void (orq::random::RandomnessManager::* func)(InputType&, T...), InputType &input, const T&... args)

Generates randomness in parallel using all available threads.

Template Parameters:
  • InputType

  • T

Parameters:
  • func – a function of the RandomnessManager class that will be called by each thread. The RandomnessManager class has functions generate_local and generate_common that can be passed as input to generate randomness from either the localPRG or a commonPRG.

  • input – vector to generate randomness into

  • args – additional args to pass to the generator

template<typename Proto, auto ProtoObj, typename EVector, typename ...T>
inline void eval_protocol_reshare(EVector &x, const T&... args)

Parallel evaluate reshare over a vector.

Template Parameters:
  • Proto

  • ProtoObj

  • EVector

  • T

Parameters:
  • x

  • args

template<typename Proto, auto ProtoObj, auto F, typename InT, typename OutT, typename ...T>
inline OutT eval_protocol_1arg_alloc(InT &x, const T&... args)

Evaluate a batched unary protocol function producing a freshly-allocated OutT (e.g. secret sharing)

Template Parameters:
  • Proto

  • ProtoObj

  • F

  • InT

  • OutT

  • T

Parameters:
  • x

  • args

template<typename Proto, auto ProtoObj, auto F, typename InT, typename OutT, typename ...T>
inline std::pair<OutT, OutT> eval_protocol_1arg_pair(InT &x, const T&... args)

Evaluate a batched unary protocol function producing a pair of <OutT, OutT>

Template Parameters:
  • Proto

  • ProtoObj

  • F

  • InT

  • OutT

  • T

Parameters:
  • x

  • args

template<typename Proto, auto ProtoObj, auto F, typename InT, typename OutT, typename ...T>
inline void eval_protocol_1arg(InT &x, OutT &r, const T&... args)

Evaluated a batched unary protocol function producing an OutT.

Template Parameters:
  • Proto

  • ProtoObj

  • F

  • InT

  • OutT

  • T

Parameters:
  • x

  • r

  • args

template<typename Proto, auto ProtoObj, auto F, typename InT, typename OutT, typename ...T>
inline void eval_protocol_2arg(InT &x, InT &y, OutT &r, const T&... args)

Evaluate a batched binary protocol function producing an OutT.

Template Parameters:
  • Proto

  • ProtoObj

  • F

  • InT

  • OutT

  • T

Parameters:
  • x

  • y

  • r

  • args

template<typename Proto, auto ProtoObj, auto F, typename InT, typename OutT, typename ...T>
inline void eval_protocol_aggregator_2arg(InT &x, InT &y, OutT &r, const size_t agg, const T&... args)

Extends protocol functionality for when input size is different than output size.

Template Parameters:
  • Proto

  • ProtoObj

  • F

  • InT

  • OutT

  • T – For the aggregation size.

  • T2

Parameters:
  • x

  • y

  • r

  • agg – the aggregation size, the ration between input sizes and output sizes.

  • args – additional arguments to the function.

template<typename T>
inline void generate_permutations(std::vector<std::shared_ptr<orq::random::ShardedPermutation>> &ret)

Generate a set of sharded permutations in parallel using all available threads.

Parameters:

ret – The set of sharded permutations to generate.

inline int getPartyID() const

Get this node’s party ID (rank)

Returns:

int

inline int getReplicationNumber() const

Get the replication number for the current protocol.

Returns:

int

inline std::vector<std::set<int>> getGroups() const

Get all randomness groups for this protocol.

Returns:

std::vector<std::set<int>>

inline ssize_t getBatchSize() const

Get the current batch size.

Returns:

ssize_t

inline void setBatchSize(const ssize_t &new_batch_size)

Update the batch size.

Parameters:

new_batch_size

inline ssize_t makeBatchSizeDivisibleBy(const size_t total, const size_t divisor)

Adjust the batch size to be divisible by some other divisor. Necessary for e.g. partial dot product operation, which must assign batches of the proper size to each thread.

Parameters:
  • total

  • divisor

Returns:

ssize_t

inline int get_num_threads()

Get the number of worker threads.

Returns:

int

inline const int getNumParties() const

Get the number of parties.

Returns:

const int

inline std::set<int> getPartySet() const

Get a set of all party indices.

Returns:

std::set<int>

inline std::vector<std::vector<int>> getPartyShareMappings() const

Get a mapping of parties to shares.

Returns:

std::vector<std::vector<int>>

template<typename T>
inline void populateLocalRandom(Vector<T> &v)

Populates the vector with locally generated pseudorandom shares.

Parameters:

v – vector to populate

template<typename T>
inline void populateCommonRandom(Vector<T> &v, std::set<int> group)

Populates the vector with commonly generated pseudorandom shares.

Parameters:
  • vVector to populate

  • group – The group that shares a CommonPRG.

template<typename T>
inline void reserve_triples(void (orq::random::RandomnessManager::* func)(size_t n), size_t n)

Generates and pools Beaver triples in parallel.

NOTE - This is very similar to generate_parallel except it doesn’t take a pre-allocated vector as input. We should eventually be able to merge these functions by making one slightly more general one.

TODO: use runtime::addtask. Custom batching here.

Parameters:
  • func – The function to call within the RandomnessManager to generate.

  • n – The number of triples to generate.

template<typename T>
inline void reserve_mul_triples(size_t n)

Calls reserve_triples() to generate arithmetic triples.

Parameters:

n – The number of triples to generate.

template<typename T>
inline void reserve_and_triples(size_t n)

Calls reserve_triples() to generate binary triples.

Parameters:

n – The number of triples to generate.

inline bool malicious_check(bool should_abort = true)
inline void print_communicator_statistics()

Print the number of bytes sent by each communicator.

inline void print_statistics()

Print statistics from worker 0. This is meant for cost modeling, operation counting, etc. so currently only executes on worker 0. If needed, can be extended to multithreaded in the future.

Public Members

std::vector<Worker> workers

The worker threads.

Worker *worker0

Temporary pointer to worker zero. (Eventually we would like to get rid of this.) Provides external callers a way to access a given worker. Currently only used in the shuffle cost model, so probably an easy way to redesign this.

Private Types

template<typename T, int R>
using RepProto = Protocol<T, std::vector<T>, Vector<T>, EVector<T, R>>

Private Functions

inline void main_thread_wait()

Main thread waits for all workers to arrive at the barrier.

inline std::vector<std::pair<size_t, size_t>> getThreadBatchBoundaries(size_t total_size, std::optional<long> batch_size_override = std::nullopt)

Determine which batches each thread will be assigned.

Parameters:
  • total_size

  • batch_size_override

Returns:

std::vector<std::pair<size_t, size_t>>

template<typename F>
inline void addTask(size_t size, F &&task_factory, std::optional<long> batch_size = std::nullopt)

Add a task to all workers.

TODO: make this a WorkerGroup method?

Template Parameters:

F

Parameters:
  • size – total size of this operation (usually the size of the input vector)

  • task_factory – lambda which returns a task for each worker.

  • batch_size – optional adjusted batch size

template<typename F>
inline void addTask(size_t size, F &&task_factory, std::optional<long> batch_size = std::nullopt)

Add a task to all workers; also pass a reference to the worker into the task. This is used for thread-specific functionality like MPC protocol primitives and randomness generation.

TODO: some clean way to combine these two versions?

Template Parameters:

F

Parameters:
  • size

  • task_factory

  • batch_size – optional adjusted batch size

Private Members

std::shared_ptr<std::barrier<>> barrier

Use a barrier to synchronization workers with main thread.

int num_threads
ssize_t batch_size
bool terminate_ = false
int rank_

Rank of this party.

bool testing = false

if this runtime is being used for testing (true) or real execution (false)

std::vector<std::thread> socket_comm_threads

We may have a different number of communication threads.

Networking

Functions

int socket_create(int port)
int socket_connect(const std::string &hostname, int port)
int send_meta(int sockfd, int byte_count)
int recv_meta(int sockfd)
int send_message(int sockfd, const RingEntry &entry)
size_t send_wrapper(int sockfd, const char *buf, ssize_t buf_size)
int recv_message(int sockfd, char *buf, ssize_t buf_size)

startmpc

Enums

enum ExecMode

Values:

enumerator LOCAL_EXEC_MODE
enumerator REMOTE_EXEC_MODE

Functions

template<typename ...Args>
void startmpc_print(Args&&... args)
void send_connections(int host_rank, int to_rank, int thread_num, std::string ip_addr, int connect_start_port, std::vector<std::vector<int>> *socket_maps)

Create an outgoing connection and assign it to the socket map. Each thread runs this function (along with listen_connections) concurrently, but since threads access disjoint vector indices (and no host sends and listens on the same port), this is thread safe.

The prior version of these functions used a vector<map<...>>, which lead to a concurrent-write race condition when multiple threads tried to write to the map at the same time.

TODO: socket_maps should probably be a shared_ptr, eventually.

Parameters:
  • host_rank

  • to_rank

  • thread_num

  • ip_addr

  • connect_start_port

  • socket_maps

void listen_connections(int host_rank, int from_rank, int thread_num, int listen_start_port, std::vector<std::vector<int>> *socket_maps)

Listen for an incoming connection and assign it to the socket map. See send_connections for more details.

Parameters:
  • host_rank

  • from_rank

  • thread_num

  • listen_start_port

  • socket_maps

void startmpc_init(int *rank, int protocol_count, int thread_num, std::vector<std::vector<int>> &socket_maps)