Protocols

The protocols/ directory contains the MPC protocol implementations supported by CryptDough.

Contents:

  • interface/ - has abstract classes that define the protocol API.

  • eda_bits.h – Extended doubly-authenticated bits (edaBits) protocol wrapper.

  • op_structs.h – Operator functors (arithmetic/boolean) shared across protocol implementations.

  • dummy_0pc.h – Dummy 0-party protocol (mock only, not functional, useful for testing).

  • plaintext_1pc.h – Plaintext 1-party protocol (no privacy, useful for testing and debugging, but could be used inside of a TEE).

  • beaver_2pc.h – Dishonest-majority 2-party protocol using Beaver triples.

  • replicated_3pc.h – Replicated secret sharing 3-party protocol.

  • dalskov_4pc.h – Dalskov et al. Fantastic-Four 4-party protocol.

  • custom_4pc.h – Rewrite of Fantastic 4PC to be round efficient.

  • spdz2k_npc.h - Dishonest-majority n-party malicious protocol.

template<typename Data, typename Share, typename Vector, typename EVector>
class Dummy_0PC : public cdough::Protocol<Data, Share, Vector, EVector>

A DUMMY protocol which DOES NOTHING. Results WILL be nonsense.

Template Parameters:
  • Data – Plaintext data type.

  • Share – Replicated share type.

  • Vector – Data container type.

  • EVector – Share container type.

Public Functions

inline Dummy_0PC(PartyID _partyID, int thread_id, Communicator *_communicator, random::RandomnessManager *_randomnessManager)

Constructor for Dummy_0PC protocol.

Parameters:
  • _partyID – Party identifier.

  • _communicator – Pointer to communicator (should be null).

  • _randomnessManager – Pointer to randomness manager.

inline virtual void print_statistics()

Print protocol statistics including operation and round counts.

inline virtual void mark_statistics()

Mark current statistics for relative measurements.

inline virtual void clear_statistics()

Clear all accumulated statistics for this protocol instance.

inline virtual void add_a(const EVector &x, const EVector &y, EVector &z)

Dummy arithmetic addition (counts operations only).

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector (unused).

inline virtual void sub_a(const EVector &x, const EVector &y, EVector &z)

Dummy arithmetic subtraction (counts operations only).

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector (unused).

inline virtual void multiply_a(const EVector &x, const EVector &y, EVector &z)

Dummy arithmetic multiplication (counts operations and rounds).

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector (unused).

inline virtual std::pair<EVector, EVector> div_const_a(const EVector &x, const Data &c)

Dummy division by constant (counts operations and rounds).

Parameters:
  • x – Input vector.

  • c – Constant divisor.

Returns:

Dummy pair of vectors.

inline int div_const_a_count()

Get the number of vectors returned by div_const_a.

Returns:

Number of result vectors (always 2).

inline void dot_product_a(const EVector &x, const EVector &y, EVector &z, int aggSize)

Dummy dot product (counts operations and rounds).

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector (unused).

  • aggSize – Aggregation size.

inline virtual void xor_b(const EVector &x, const EVector &y, EVector &z)

Dummy bitwise XOR (counts operations only).

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector (unused).

inline virtual void and_b(const EVector &x, const EVector &y, EVector &z)

Dummy bitwise AND (counts operations and rounds).

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector (unused).

inline virtual void not_b(const EVector &x, EVector &y)

Dummy boolean complement (counts operations only).

Parameters:
  • x – Input vector.

  • y – Output vector (unused).

inline virtual void not_b_1(const EVector &x, EVector &y)

Dummy boolean NOT (counts operations only).

Parameters:
  • x – Input vector.

  • y – Output vector (unused).

inline virtual void ltz(const EVector &x, EVector &y)

Dummy less-than-zero comparison (counts operations only).

Parameters:
  • x – Input vector.

  • y – Output vector (unused).

inline virtual std::pair<EVector, EVector> redistribute_shares_b(const EVector &x)

Dummy share redistribution (counts operations and rounds).

Parameters:

x – Input vector.

Returns:

Dummy pair of vectors.

inline virtual void b2a_bit(const EVector &x, EVector &y)

Dummy boolean-to-arithmetic conversion (counts operations and rounds).

Parameters:
  • x – Input vector.

  • y – Output vector (unused).

inline virtual Data reconstruct_from_a(const std::vector<Share> &shares)

Dummy reconstruction from arithmetic shares.

Parameters:

shares – Input shares.

Returns:

First element of first share.

inline virtual Vector reconstruct_from_a(const std::vector<EVector> &shares)

Dummy vectorized reconstruction from arithmetic shares.

Parameters:

shares – Input shared vectors.

Returns:

First share’s first element.

inline virtual Data reconstruct_from_b(const std::vector<Share> &shares)

Dummy reconstruction from boolean shares.

Parameters:

shares – Input shares.

Returns:

First element of first share.

inline virtual Vector reconstruct_from_b(const std::vector<EVector> &shares)

Dummy vectorized reconstruction from boolean shares.

Parameters:

shares – Input shared vectors.

Returns:

First share’s first element.

inline virtual Vector unchecked_open_a(const EVector &shares)

Dummy opening of arithmetic shares (counts operations and rounds).

Parameters:

shares – Input shared vector.

Returns:

First share’s vector.

inline virtual Vector unchecked_open_b(const EVector &shares)

Dummy opening of boolean shares (counts operations and rounds).

Parameters:

shares – Input shared vector.

Returns:

First share’s vector.

inline std::vector<Share> get_share_a(const Data &data)

Generate dummy arithmetic share for single value.

Parameters:

data – Input data value.

Returns:

Vector containing the data.

inline virtual std::vector<EVector> get_shares_a(const Vector &data)

Generate dummy arithmetic shares for vector.

Parameters:

data – Input data vector.

Returns:

Vector of shared vectors.

inline std::vector<Share> get_share_b(const Data &data)

Generate dummy boolean share for single value.

Parameters:

data – Input data value.

Returns:

Vector containing the data.

inline virtual std::vector<EVector> get_shares_b(const Vector &data)

Generate dummy boolean shares for vector.

Parameters:

data – Input data vector.

Returns:

Vector of shared vectors.

inline virtual EVector secret_share_b_internal(const Vector &data, const PartyID &data_party = 0)

Dummy boolean secret sharing (counts operations and rounds).

Parameters:
  • data – Input data vector.

  • data_party – Party owning the data.

Returns:

Dummy shared vector.

inline virtual EVector secret_share_a_internal(const Vector &data, const PartyID &data_party = 0)

Dummy arithmetic secret sharing (counts operations and rounds).

Parameters:
  • data – Input data vector.

  • data_party – Party owning the data.

Returns:

Dummy shared vector.

inline virtual EVector public_share(const Vector &data, const std::set<PartyID> &who_knows)

Create dummy public share.

Parameters:

data – Input data vector.

Returns:

Dummy shared vector.

inline virtual void reshare(EVector &v, const std::set<int> group, bool binary)

Dummy resharing (counts operations and rounds).

Parameters:
  • v – Input/output vector.

  • group – Party group.

  • binary – Whether shares are binary.

Public Members

std::map<std::string, uint64_t> op_counter
std::map<std::string, std::optional<uint64_t>> mark_op_counter
std::map<std::string, uint64_t> round_counter
std::map<std::string, std::optional<uint64_t>> mark_round_counter

Public Static Attributes

static int parties_num = 1
template<typename Data, typename Share, typename Vector, typename EVector>
class Plaintext_1PC : public cdough::Protocol<Data, Share, Vector, EVector>

An INSECURE protocol for testing and benchmarking.

DO NOT use this protocol for secure computation.

Template Parameters:
  • Data – Plaintext data type.

  • Share – Replicated share type.

  • Vector – Data container type.

  • EVector – Share container type.

Public Functions

inline Plaintext_1PC(PartyID _partyID, int thread_id, Communicator *_communicator, random::RandomnessManager *_randomnessManager)

Constructor for Plaintext_1PC protocol.

Parameters:
  • _partyID – Party identifier.

  • _communicator – Pointer to communicator (should be null).

  • _randomnessManager – Pointer to randomness manager.

inline virtual void print_statistics()

Print protocol statistics including operation and round counts.

inline virtual void mark_statistics()

Mark current statistics for relative measurements.

inline virtual void clear_statistics()

Clear all accumulated statistics for this protocol instance.

inline virtual void add_a(const EVector &x, const EVector &y, EVector &z)

Plaintext arithmetic addition.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void sub_a(const EVector &x, const EVector &y, EVector &z)

Plaintext arithmetic subtraction.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void multiply_a(const EVector &x, const EVector &y, EVector &z)

Plaintext arithmetic multiplication.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void truncate(EVector &x)

Defines vectorized arithmetic truncation. This method must take one input vector with arithmetic shares and return a new vector that contains arithmetic shares of the truncated input. The default implementation invokes the protocol’s public division protocol.

Note

This default protocol assumes that public division is still secure when the error correction is not applied. This holds for all protocols currently in the system.

Parameters:

x – - The shared vector to truncate.

inline virtual void neg_a(const EVector &x, EVector &y)

Plaintext arithmetic negation.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual std::pair<EVector, EVector> div_const_a(const EVector &x, const Data &c)

Plaintext division by constant with error correction.

Parameters:
  • x – Input vector.

  • c – Constant divisor.

Returns:

Pair of vectors (quotient and error correction).

inline int div_const_a_count()

Get the number of vectors returned by div_const_a.

Returns:

Number of result vectors (always 2).

inline void dot_product_a(const EVector &x, const EVector &y, EVector &z, int aggSize)

Plaintext dot product.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

  • aggSize – Aggregation size.

inline virtual void xor_b(const EVector &x, const EVector &y, EVector &z)

Plaintext bitwise XOR.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void and_b(const EVector &x, const EVector &y, EVector &z)

Plaintext bitwise AND.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void not_b(const EVector &x, EVector &y)

Plaintext boolean complement.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual void not_b_1(const EVector &x, EVector &y)

Plaintext boolean NOT.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual void ltz(const EVector &x, EVector &y)

Plaintext less-than-zero comparison.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual void b2a_bit(const EVector &x, EVector &y)

Plaintext boolean-to-arithmetic conversion.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual std::pair<EVector, EVector> redistribute_shares_b(const EVector &x)

Plaintext share redistribution.

Parameters:

x – Input vector.

Returns:

Pair of vectors (original and zero).

inline virtual Data reconstruct_from_a(const std::vector<Share> &shares)

Plaintext reconstruction from arithmetic shares.

Parameters:

shares – Input shares.

Returns:

First element of first share.

inline virtual Vector reconstruct_from_a(const std::vector<EVector> &shares)

Plaintext vectorized reconstruction from arithmetic shares.

Parameters:

shares – Input shared vectors.

Returns:

First share’s first element.

inline virtual Data reconstruct_from_b(const std::vector<Share> &shares)

Plaintext reconstruction from boolean shares.

Parameters:

shares – Input shares.

Returns:

First element of first share.

inline virtual Vector reconstruct_from_b(const std::vector<EVector> &shares)

Plaintext vectorized reconstruction from boolean shares.

Parameters:

shares – Input shared vectors.

Returns:

First share’s first element.

inline virtual Vector unchecked_open_a(const EVector &shares)

Plaintext opening of arithmetic shares.

Parameters:

shares – Input shared vector.

Returns:

First share’s vector.

inline virtual Vector unchecked_open_b(const EVector &shares)

Plaintext opening of boolean shares.

Parameters:

shares – Input shared vector.

Returns:

First share’s vector.

inline std::vector<Share> get_share_a(const Data &data)

Generate plaintext arithmetic share for single value.

Parameters:

data – Input data value.

Returns:

Vector containing the data.

inline virtual std::vector<EVector> get_shares_a(const Vector &data)

Generate plaintext arithmetic shares for vector.

Parameters:

data – Input data vector.

Returns:

Vector of shared vectors.

inline std::vector<Share> get_share_b(const Data &data)

Generate plaintext boolean share for single value.

Parameters:

data – Input data value.

Returns:

Vector containing the data.

inline virtual std::vector<EVector> get_shares_b(const Vector &data)

Generate plaintext boolean shares for vector.

Parameters:

data – Input data vector.

Returns:

Vector of shared vectors.

inline virtual EVector secret_share_b_internal(const Vector &data, const PartyID &data_party = 0)

Plaintext boolean secret sharing.

Parameters:
  • data – Input data vector.

  • data_party – Party owning the data.

Returns:

Shared vector.

inline virtual EVector secret_share_a_internal(const Vector &data, const PartyID &data_party = 0)

Plaintext arithmetic secret sharing.

Parameters:
  • data – Input data vector.

  • data_party – Party owning the data.

Returns:

Shared vector.

inline virtual EVector public_share(const Vector &data, const std::set<PartyID> &who_knows)

Create plaintext public share.

Parameters:

data – Input data vector.

Returns:

Shared vector.

inline virtual void reshare(EVector &v, const std::set<int> group, bool binary)

Plaintext resharing (counts operations and rounds).

Parameters:
  • v – Input/output vector.

  • group – Party group.

  • binary – Whether shares are binary.

Public Members

std::map<std::string, uint64_t> op_counter
std::map<std::string, std::optional<uint64_t>> mark_op_counter
std::map<std::string, uint64_t> round_counter
std::map<std::string, std::optional<uint64_t>> mark_round_counter

Public Static Attributes

static int parties_num = 1
template<typename Data, typename Share, typename Vector, typename EVector>
class Beaver_2PC : public cdough::Protocol<Data, Share, Vector, EVector>

Implements the secure primitives for the 2-party semi-honest protocol that uses Beaver triples.

Template Parameters:
  • Data – Plaintext data type.

  • Share – Share type.

  • Vector – Data container type.

  • EVector – Share container type.

Public Functions

inline Beaver_2PC(PartyID _partyID, int thread_id, Communicator *_communicator, random::RandomnessManager *_randomnessManager)

Constructor for Beaver_2PC protocol.

Parameters:
  • _partyID – Party identifier.

  • _communicator – Pointer to communicator.

  • _randomnessManager – Pointer to randomness manager.

inline virtual void multiply_a(const EVector &x, const EVector &y, EVector &z)

Secure arithmetic multiplication using Beaver triples.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void matrix_right_multiply_with_column_matrix_vectorized_a(const EVector &x, const EVector &y, EVector &z, const size_t lhs_rows, const size_t lhs_cols, const size_t rhs_rows, const size_t rhs_cols)

Secure matrix right multiplication with a column matrix, vectorized implementation. Expects the left-hand side matrix to be in row-major order. Expects the right-hand side matrix to be in column-major order.

Parameters:
  • x – The left-hand side matrix as a shared vector.

  • y – The right-hand side column matrix as a shared vector.

  • z – The output shared vector.

  • lhs_rows – Number of rows in the left-hand side matrix.

  • lhs_cols – Number of columns in the left-hand side matrix.

  • rhs_rows – Number of rows in the right-hand side matrix.

  • rhs_cols – Number of columns in the right-hand side matrix.

inline virtual void conv_2d_vectorized_a(const EVector &x, const EVector &y, EVector &z, const size_t instancesCount, const size_t inputHeight, const size_t inputWidth, const size_t filterHeight, const size_t filterWidth, const size_t strideHeight, const size_t strideWidth, const size_t paddingHeight, const size_t paddingWidth)

Secure 2D convolution.

Input layout: The input consists of mutiple instances concatenated after each other. Hence, the input size = instancesCount * inputHeight * inputWidth. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 input with 2 channels: [ch1(0,0), ch2(0,0), ch1(0,1), ch2(0,1), ch1(1,0), ch2(1,0), ch1(1,1), ch2(1,1)]

Filter layout: the filter is expected to have multiple channels. Hence, the filter size = channels * filterHeight * filterWidth. For example, the the physical layout for 2x2 filter with 2 channels:

[f_ch1(0,0), f_ch2(0,0), f_ch1(1,0), f_ch2(1,0), g_ch1(0,1), g_ch2(0,1), g_ch1(1,1), g_ch2(1,1)]

Output layout: (same layout as input but different height and width). The output consists of mutiple instances concatenated after each other. Hence, the output size = instancesCount * outputHeight * outputWidth * channels. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 output with 2 channels: [f(0,0), g(0,0), f(0,1), g(0,1), f(1,0), g(1,0), f(1,1), g(1,1)]

Parameters:
  • x – The input shared vector.

  • y – The filter shared vector.

  • z – The output shared vector.

  • instancesCount – Number of instances in the input.

  • inputHeight – Height of each input instance.

  • inputWidth – Width of each input instance.

  • filterHeight – Height of each filter channel.

  • filterWidth – Width of each filter channel.

  • strideHeight – Stride height.

  • strideWidth – Stride width.

  • paddingHeight – Padding height.

  • paddingWidth – Padding width.

inline virtual void truncate(EVector &x)

Truncate the input vector by its precision field.

This uses the non-interactive protocol by SecureML (Mohassel and Zhang, 2017). https://eprint.iacr.org/2017/396.pdf

We just locally truncate each party’s share by its precision field. The result is correct with up to 1 bit of error, plus a small probability of a much larger error with probability proportional to the number of bits between the most significant non-zero bit and the bitwidth. (i.e., if x = 2**18 and the type is 32-bit, then the probability of error is 1/2**14)

Parameters:

x – Input vector.

inline virtual std::pair<EVector, EVector> div_const_a(const EVector &x, const Data &c)

Division by constant with optional error correction.

Parameters:
  • x – Input vector.

  • c – Constant divisor.

Returns:

Pair of vectors (quotient and error correction).

inline virtual void and_b(const EVector &x, const EVector &y, EVector &z)

Secure bitwise AND using Beaver AND triples.

Performs bitwise AND between two binary secret shared values. Consumes one Beaver AND triple. Direct analog to multiplication.

Parameters:
  • x – Binary shared input.

  • y – Binary shared input.

  • z – Binary shared output.

inline virtual void not_b(const EVector &x, EVector &y)

Boolean complement operation.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual void not_b_1(const EVector &x, EVector &y)

Boolean NOT operation.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual void b2a_bit(const EVector &x, EVector &y)

Convert a boolean-shared bit in the least significant position to an arithmetic sharing:

First, interpret x = x0 ^ x1 as arithmetic shares. P1 negates its share. Then we have x = x0 - x1, where x’ is some unknown value. Squaring this value under MPC gives the arithmetic conversion:

y = x&rsquo; * x'
  = (x0 - x1) * (x0 - x1)
  = x0 * x0 + x1 * x1 - 2 * x0 * x1
  = x0 + x1 - 2 * x0 * x1

The last line holds since a * a == a for single-bit values. Then we have the arithmetized XOR expression, as required. Since we perform MPC multiplication, the result is already randomized.

Parameters:
  • x – Input boolean shared vector.

  • y – Output arithmetic shared vector.

inline virtual std::pair<EVector, EVector> redistribute_shares_b(const EVector &x)

Redistribute boolean shares.

Parameters:

x – Input vector.

Returns:

Pair of redistributed shared vectors.

inline virtual Data reconstruct_from_a(const std::vector<Share> &shares)

Reconstruct plaintext from arithmetic shares.

Parameters:

shares – Input shares from both parties.

Returns:

Reconstructed plaintext value.

inline virtual Vector reconstruct_from_a(const std::vector<EVector> &shares)

Reconstruct plaintext vector from arithmetic shares.

Parameters:

shares – Input shared vectors from both parties.

Returns:

Reconstructed plaintext vector.

inline virtual Data reconstruct_from_b(const std::vector<Share> &shares)

Reconstruct plaintext from boolean shares.

Parameters:

shares – Input shares from both parties.

Returns:

Reconstructed plaintext value.

inline virtual Vector reconstruct_from_b(const std::vector<EVector> &shares)

Reconstruct plaintext vector from boolean shares.

Parameters:

shares – Input shared vectors from both parties.

Returns:

Reconstructed plaintext vector.

inline virtual Vector unchecked_open_a(const EVector &shares)

Open arithmetic shares to reveal plaintext.

Parameters:

shares – Input shared vector.

Returns:

Opened plaintext vector.

inline virtual Vector unchecked_open_b(const EVector &shares)

Open boolean shares to reveal plaintext.

Parameters:

shares – Input shared vector.

Returns:

Opened plaintext vector.

inline std::vector<Share> get_share_a(const Data &data)

Generate arithmetic shares for a single value.

Parameters:

data – Input plaintext value.

Returns:

Vector of arithmetic shares for both parties.

inline virtual std::vector<EVector> get_shares_a(const Vector &data)

Generate arithmetic shares for a vector.

Parameters:

data – Input plaintext vector.

Returns:

Vector of arithmetic shared vectors for both parties.

inline std::vector<Share> get_share_b(const Data &data)

Generate boolean shares for a single value.

Parameters:

data – Input plaintext value.

Returns:

Vector of boolean shares for both parties.

inline virtual std::vector<EVector> get_shares_b(const Vector &data)

Generate boolean shares for a vector.

Parameters:

data – Input plaintext vector.

Returns:

Vector of boolean shared vectors for both parties.

inline virtual EVector secret_share_b_internal(const Vector &data, const PartyID &data_party = 0)

Secret share a boolean vector.

Parameters:
  • data – Input plaintext vector.

  • data_party – Party that owns the data.

Returns:

This party’s boolean shared vector.

inline virtual EVector secret_share_a_internal(const Vector &data, const PartyID &data_party = 0)

Secret share an arithmetic vector.

Parameters:
  • data – Input plaintext vector.

  • data_party – Party that owns the data.

Returns:

This party’s arithmetic shared vector.

inline virtual EVector public_share(const Vector &data, const std::set<PartyID> &who_knows)

Create public shares from plaintext data.

Parameters:

data – Input plaintext vector.

Returns:

Public shared vector.

Public Members

std::shared_ptr<random::BeaverTripleGenerator<Data, cdough::Encoding::AShared>> BTgen
std::shared_ptr<random::BeaverTripleGenerator<Data, cdough::Encoding::BShared>> BTANDgen

Public Static Attributes

static int parties_num = 2
template<typename Data, typename Share, typename Vector, typename EVector>
class Replicated_3PC : public cdough::Protocol<Data, Share, Vector, EVector>

Implements the secure primitives for the 3-party semi-honest protocol by Araki et al. that uses replicated secret sharing.

Template Parameters:
  • Data – Plaintext data type.

  • Share – Replicated share type.

  • Vector – Data container type.

  • EVector – Share container type.

Public Functions

inline Replicated_3PC(PartyID _partyID, int thread_id, Communicator *_communicator, random::RandomnessManager *_randomnessManager)

Constructor for the semi-honest replicated 3-party protocol by Araki et al.

Parameters:
  • _partyID – The (globally) unique id of the party that calls this constructor.

  • _communicator – A pointer to the communicator.

  • _randomnessManager – A pointer to the randomness manager.

inline virtual void multiply_a(const EVector &x, const EVector &y, EVector &z)

Secure arithmetic multiplication using replicated secret sharing.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void truncate(EVector &x)

Truncate the input vector by its precision field.

This uses the protocol by ABY3 (Mohassel and Rindal, 2018). https://eprint.iacr.org/2018/403.pdf

The ABY3 protocol reduces the three-party case to the two-party SecureML protocol.

Parameters:

x – Input vector.

inline virtual std::pair<EVector, EVector> div_const_a(const EVector &x, const Data &c)

Division by constant with share redistribution.

Algorithm:

  1. Start with 3 secret shares (x1, x2, x3), but division requires 2 shares.

  2. Merge first 2 shares to get x1’ = x1 + x2.

  3. Use shares (x1’, x3) for division on secret shares.

  4. End up with (x1/c, x3/c) which are only two shares, but we need 3 shares.

  5. Redistribute shares (y1, y2) to be (y1 - r, r, y2) where r is random.

  6. Logic for calculating result and error is identical to 2PC.

Parameters:
  • x – Input vector.

  • c – Constant divisor.

Returns:

Pair of vectors (quotient and error correction).

inline virtual void dot_product_a(const EVector &x, const EVector &y, EVector &z, size_t aggSize)

Secure dot product using replicated secret sharing.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector containing dot products.

  • aggSize – Aggregation size.

inline virtual void matrix_right_multiply_with_column_matrix_vectorized_a(const EVector &x, const EVector &y, EVector &z, const size_t lhs_rows, const size_t lhs_cols, const size_t rhs_rows, const size_t rhs_cols)

Secure matrix right multiplication with a column matrix, vectorized implementation. Expects the left-hand side matrix to be in row-major order. Expects the right-hand side matrix to be in column-major order.

Parameters:
  • x – The left-hand side matrix as a shared vector.

  • y – The right-hand side column matrix as a shared vector.

  • z – The output shared vector.

  • lhs_rows – Number of rows in the left-hand side matrix.

  • lhs_cols – Number of columns in the left-hand side matrix.

  • rhs_rows – Number of rows in the right-hand side matrix.

  • rhs_cols – Number of columns in the right-hand side matrix.

inline virtual void conv_2d_vectorized_a(const EVector &x, const EVector &y, EVector &z, const size_t instancesCount, const size_t inputHeight, const size_t inputWidth, const size_t filterHeight, const size_t filterWidth, const size_t strideHeight, const size_t strideWidth, const size_t paddingHeight, const size_t paddingWidth)

Secure 2D convolution.

Input layout: The input consists of mutiple instances concatenated after each other. Hence, the input size = instancesCount * inputHeight * inputWidth. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 input with 2 channels: [ch1(0,0), ch2(0,0), ch1(0,1), ch2(0,1), ch1(1,0), ch2(1,0), ch1(1,1), ch2(1,1)]

Filter layout: the filter is expected to have multiple channels. Hence, the filter size = channels * filterHeight * filterWidth. For example, the the physical layout for 2x2 filter with 2 channels:

[f_ch1(0,0), f_ch2(0,0), f_ch1(1,0), f_ch2(1,0), g_ch1(0,1), g_ch2(0,1), g_ch1(1,1), g_ch2(1,1)]

Output layout: (same layout as input but different height and width). The output consists of mutiple instances concatenated after each other. Hence, the output size = instancesCount * outputHeight * outputWidth * channels. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 output with 2 channels: [f(0,0), g(0,0), f(0,1), g(0,1), f(1,0), g(1,0), f(1,1), g(1,1)]

Parameters:
  • x – The input shared vector.

  • y – The filter shared vector.

  • z – The output shared vector.

  • instancesCount – Number of instances in the input.

  • inputHeight – Height of each input instance.

  • inputWidth – Width of each input instance.

  • filterHeight – Height of each filter channel.

  • filterWidth – Width of each filter channel.

  • strideHeight – Stride height.

  • strideWidth – Stride width.

  • paddingHeight – Padding height.

  • paddingWidth – Padding width.

inline virtual void and_b(const EVector &x, const EVector &y, EVector &z)

Secure bitwise AND using replicated secret sharing.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void not_b(const EVector &x, EVector &y)

Boolean complement operation.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual void not_b_1(const EVector &x, EVector &y)

Boolean NOT operation (LSB only).

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual void b2a_bit(const EVector &x, EVector &y)

Convert boolean-shared bit to arithmetic sharing.

Converts a boolean-shared bit (LSB only) to arithmetic sharing using replicated secret sharing protocol.

Should only be used for the least significant bit.

Parameters:
  • x – Input boolean shared vector.

  • y – Output arithmetic shared vector.

inline virtual std::pair<EVector, EVector> redistribute_shares_b(const EVector &x)

Redistribute boolean shares.

Parameters:

x – Input vector.

Returns:

Pair of redistributed shared vectors.

inline virtual Data reconstruct_from_a(const std::vector<Share> &shares)

Reconstruct plaintext from arithmetic shares.

Parameters:

shares – Input shares from all three parties.

Returns:

Reconstructed plaintext value.

inline virtual Vector reconstruct_from_a(const std::vector<EVector> &shares)

Reconstruct plaintext vector from arithmetic shares.

Parameters:

shares – Input shared vectors from all three parties.

Returns:

Reconstructed plaintext vector.

inline virtual Data reconstruct_from_b(const std::vector<Share> &shares)

Reconstruct plaintext from boolean shares.

Parameters:

shares – Input shares from all three parties.

Returns:

Reconstructed plaintext value.

inline virtual Vector reconstruct_from_b(const std::vector<EVector> &shares)

Reconstruct plaintext vector from boolean shares.

Parameters:

shares – Input shared vectors from all three parties.

Returns:

Reconstructed plaintext vector.

inline virtual Vector unchecked_open_a(const EVector &shares)

Open arithmetic shares to reveal plaintext.

Parameters:

shares – Input shared vector.

Returns:

Opened plaintext vector.

inline virtual Vector unchecked_open_b(const EVector &shares)

Open boolean shares to reveal plaintext.

Parameters:

shares – Input shared vector.

Returns:

Opened plaintext vector.

inline std::vector<Share> get_share_a(const Data &data)

Generate replicated arithmetic shares for a single value.

Parameters:

data – Input plaintext value.

Returns:

Vector of replicated arithmetic shares for all parties.

inline virtual std::vector<EVector> get_shares_a(const Vector &data)

Generate replicated arithmetic shares for a vector.

Parameters:

data – Input plaintext vector.

Returns:

Vector of replicated arithmetic shared vectors for all parties.

inline std::vector<Share> get_share_b(const Data &data)

Generate replicated boolean shares for a single value.

Parameters:

data – Input plaintext value.

Returns:

Vector of replicated boolean shares for all parties.

inline virtual std::vector<EVector> get_shares_b(const Vector &data)

Generate replicated boolean shares for a vector.

Parameters:

data – Input plaintext vector.

Returns:

Vector of replicated boolean shared vectors for all parties.

inline virtual EVector secret_share_b_internal(const Vector &data, const PartyID &data_party = 0)

Secret share a boolean vector using replicated sharing.

Parameters:
  • data – Input plaintext vector.

  • data_party – Party that owns the data.

Returns:

This party’s replicated boolean shared vector.

inline virtual EVector secret_share_a_internal(const Vector &data, const PartyID &data_party = 0)

Secret share an arithmetic vector using replicated sharing.

Parameters:
  • data – Input plaintext vector.

  • data_party – Party that owns the data.

Returns:

This party’s replicated arithmetic shared vector.

inline virtual EVector public_share(const Vector &x, const std::set<PartyID> &who_knows)

Create public shares from plaintext data using replicated sharing.

Parameters:
  • x – Input plaintext vector.

  • who_knows – set of parties who know the value. empty set {} represents everyone.

Returns:

Public replicated shared vector.

Public Static Attributes

static int parties_num = 3
template<typename Data, typename Share, typename Vector, typename EVector>
class Fantastic_4PC : public cdough::Protocol<Data, Share, Vector, EVector>, public cdough::Protocol<Data, Share, Vector, EVector>

Implements the secure primitives for the 4-party malicious protocol by Dalskov et al. that uses replicated secret sharing.

Implementation of the “Fantastic Four” paper by Dalskov et al.

This version implements functionalities exactly as specified in the paper, without any optimizations.

Template Parameters:
  • Data – Plaintext data type.

  • Share – Replicated share type.

  • Vector – Data container type.

  • EVector – Share container type.

  • Data – Plaintext data type.

  • Share – Replicated share type.

  • Vector – Data container type.

  • EVector – Share container type.

Public Functions

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

Override of default groups to achieve malicious security.

This group selection gives us two copies of each share per group (redundancy).

Returns:

Vector of party groups for malicious security.

inline Fantastic_4PC(PartyID _partyID, int thread_id, Communicator *_communicator, random::RandomnessManager *_randomnessManager)

Constructor for Fantastic_4PC protocol.

Parameters:
  • _partyID – Party identifier.

  • _communicator – Pointer to communicator.

  • _randomnessManager – Pointer to randomness manager.

inline virtual void multiply_a(const EVector &x, const EVector &y, EVector &z)

Secure arithmetic multiplication with malicious security.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void conv_2d_vectorized_a(const EVector &x, const EVector &y, EVector &z, const size_t instancesCount, const size_t inputHeight, const size_t inputWidth, const size_t filterHeight, const size_t filterWidth, const size_t strideHeight, const size_t strideWidth, const size_t paddingHeight, const size_t paddingWidth)

Secure 2D convolution.

Input layout: The input consists of mutiple instances concatenated after each other. Hence, the input size = instancesCount * inputHeight * inputWidth. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 input with 2 channels: [ch1(0,0), ch2(0,0), ch1(0,1), ch2(0,1), ch1(1,0), ch2(1,0), ch1(1,1), ch2(1,1)]

Filter layout: the filter is expected to have multiple channels. Hence, the filter size = channels * filterHeight * filterWidth. For example, the the physical layout for 2x2 filter with 2 channels:

[f_ch1(0,0), f_ch2(0,0), f_ch1(1,0), f_ch2(1,0), g_ch1(0,1), g_ch2(0,1), g_ch1(1,1), g_ch2(1,1)]

Output layout: (same layout as input but different height and width). The output consists of mutiple instances concatenated after each other. Hence, the output size = instancesCount * outputHeight * outputWidth * channels. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 output with 2 channels: [f(0,0), g(0,0), f(0,1), g(0,1), f(1,0), g(1,0), f(1,1), g(1,1)]

Parameters:
  • x – The input shared vector.

  • y – The filter shared vector.

  • z – The output shared vector.

  • instancesCount – Number of instances in the input.

  • inputHeight – Height of each input instance.

  • inputWidth – Width of each input instance.

  • filterHeight – Height of each filter channel.

  • filterWidth – Width of each filter channel.

  • strideHeight – Stride height.

  • strideWidth – Stride width.

  • paddingHeight – Padding height.

  • paddingWidth – Padding width.

inline virtual void matrix_right_multiply_with_column_matrix_vectorized_a(const EVector &x, const EVector &y, EVector &z, const size_t lhs_rows, const size_t lhs_cols, const size_t rhs_rows, const size_t rhs_cols)

Secure matrix right multiplication with a column matrix, vectorized implementation. Expects the left-hand side matrix to be in row-major order. Expects the right-hand side matrix to be in column-major order.

Parameters:
  • x – The left-hand side matrix as a shared vector.

  • y – The right-hand side column matrix as a shared vector.

  • z – The output shared vector.

  • lhs_rows – Number of rows in the left-hand side matrix.

  • lhs_cols – Number of columns in the left-hand side matrix.

  • rhs_rows – Number of rows in the right-hand side matrix.

  • rhs_cols – Number of columns in the right-hand side matrix.

inline EVector inp_a(const Vector &x, int i, int j, int g, int h)

Input sharing protocol for specific party sequence.

Note: this inp is for the div function pattern only. [i precedes j precedes g precedes h].

Parameters:
  • x – Input vector to be shared.

  • i – First party in sequence.

  • j – Second party in sequence.

  • g – Third party in sequence (receiver).

  • h – Fourth party in sequence (randomness generator).

Returns:

Shared vector.

inline virtual std::pair<EVector, EVector> div_const_a(const EVector &x, const Data &c)

Division by constant with malicious security.

Parameters:
  • x – Input vector.

  • c – Constant divisor.

Returns:

Pair of vectors (quotient and error correction).

inline EVector inp_b(const Vector &x, int i, int j, int g, int h)

Boolean input sharing protocol for specific party sequence.

Note: this inp is for the div function pattern only. [i precedes j precedes g precedes h].

Parameters:
  • x – Input vector to be shared.

  • i – First party in sequence.

  • j – Second party in sequence.

  • g – Third party in sequence (receiver).

  • h – Fourth party in sequence (randomness generator).

Returns:

Shared vector.

inline virtual void and_b(const EVector &x, const EVector &y, EVector &z)

Secure bitwise AND with malicious security.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void not_b(const EVector &x, EVector &y)

Boolean NOT operation.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual void not_b_1(const EVector &x, EVector &y)

Boolean NOT operation for the least significant bit.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual void b2a_bit(const EVector &x, EVector &y)

Convert a boolean-shared bit to arithmetic sharing.

4PC share distribution: P0: [B, C, D] -> B C D P1: [C, D, A] -> A C D P2: [D, A, B] -> A B D P3: [A, B, C] -> A B C

Reducing the 4-share to a 2-share: share0 = C ^ D share1 = A ^ B

P0 and P1 can both calculate share0. P2 and P3 can both calculate share1.

Since 2 parties can calculate each of the above, INP can be used to generate a secret-share for share0 and share1.

XOR evaluated as: x ^ y = (x - y)^2 (holds true for binary input)

Parameters:
  • x – Input boolean shared vector.

  • y – Output arithmetic shared vector.

inline virtual std::pair<EVector, EVector> redistribute_shares_b(const EVector &x)

Redistribute boolean shares.

Parameters:

x – Input vector.

Returns:

Pair of redistributed shared vectors.

inline virtual Data reconstruct_from_a(const std::vector<Share> &shares)

Reconstruct plaintext from arithmetic shares.

Parameters:

shares – Input shares from all four parties.

Returns:

Reconstructed plaintext value.

inline virtual Vector reconstruct_from_a(const std::vector<EVector> &shares)

Reconstruct plaintext vector from arithmetic shares.

Parameters:

shares – Input shared vectors from all four parties.

Returns:

Reconstructed plaintext vector.

inline virtual Data reconstruct_from_b(const std::vector<Share> &shares)

Reconstruct plaintext from boolean shares.

Parameters:

shares – Input shares from all four parties.

Returns:

Reconstructed plaintext value.

inline virtual Vector reconstruct_from_b(const std::vector<EVector> &shares)

Reconstruct plaintext vector from boolean shares.

Parameters:

shares – Input shared vectors from all four parties.

Returns:

Reconstructed plaintext vector.

inline virtual Vector unchecked_open_a(const EVector &shares)

Open arithmetic shares to reveal plaintext.

TODO: malicious check

Parameters:

shares – Input shared vector.

Returns:

Opened plaintext vector.

inline virtual Vector unchecked_open_b(const EVector &shares)

Open boolean shares to reveal plaintext.

TODO: malicious check

Parameters:

shares – Input shared vector.

Returns:

Opened plaintext vector.

inline std::vector<Share> get_share_a(const Data &data)

Generate arithmetic shares for a single value.

Parameters:

data – Input data value.

Returns:

Vector of shares for all parties.

inline virtual std::vector<EVector> get_shares_a(const Vector &data)

Generate arithmetic shares for a vector.

Parameters:

data – Input data vector.

Returns:

Vector of shares for all parties.

inline std::vector<Share> get_share_b(const Data &data)

Generate boolean shares for a single value.

Parameters:

data – Input data value.

Returns:

Vector of shares for all parties.

inline virtual std::vector<EVector> get_shares_b(const Vector &data)

Generate boolean shares for a vector.

Parameters:

data – Input data vector.

Returns:

Vector of shares for all parties.

inline virtual EVector secret_share_b_internal(const Vector &data, const PartyID &data_party = 0)

Secret share data using the custom 4PC protocol.

Parameters:
  • data – Input data vector.

  • data_party – Party ID of the data party.

Returns:

Secret shared vector.

inline virtual EVector secret_share_a_internal(const Vector &data, const PartyID &data_party = 0)

Secret share data using the custom 4PC protocol.

Parameters:
  • data – Input data vector.

  • data_party – Party ID of the data party.

Returns:

Secret shared vector.

inline virtual EVector public_share(const Vector &x)

Public sharing of a vector x.

P0 gets: (0, 0, 0 ) P1 gets: ( 0, 0, x) P2 gets: (0, 0, x) P3 gets: (0, 0, x)

Parameters:

x – Input data vector.

Returns:

EVector

inline virtual EVector public_share(const Vector &x, const std::set<PartyID> &who_knows)

Create a “secret” share of a public value, x. This implemented by setting one share to x and all others to zero; this gives a valid sharing under both arithmetic and boolean.

Parameters:
  • x – The public vector to share.

  • who_knows – a party who knows the value

Returns:

The shared vector.

inline virtual void reshare(EVector &v, const std::set<int> group, bool binary)

An override version of reshare for malicious security in 4PC.

Parameters:
  • v – The vector to be rerandomized and reshared.

  • group – The group performing the resharing.

  • binary – A flag indicating an arithmetic or binary encoding of the vector.

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

Override of default groups to achieve malicious security.

This group selection gives us two copies of each share per group (redundancy).

Returns:

Vector of party groups for malicious security.

inline Fantastic_4PC(PartyID _partyID, int thread_id, Communicator *_communicator, random::RandomnessManager *_randomnessManager)

Constructor for Fantastic_4PC protocol (Dalskov implementation).

Parameters:
  • _partyID – Party identifier.

  • _communicator – Pointer to communicator.

  • _randomnessManager – Pointer to randomness manager.

inline void jmp(Vector &x, int from, int also_from, int to)

Joint message passing protocol.

Parameters:
  • x – Vector of (non-secret shared) data.

  • from – Owner of this data.

  • also_from – Co-owner of data.

  • to – Party who will receive data from both.

template<cdough::Encoding E>
inline EVector inp(const Vector &x, int Pi, int Pj, std::optional<int> Pg = {}, std::optional<int> Ph = {})

Shared-input function.

Two parties, who both know a plaintext value x, secret-share it with the other two parties.

Template Parameters:

EEncoding type (A- or B-shared).

Parameters:
  • x – Plaintext data.

  • Pi – First owner.

  • Pj – Second owner.

  • Pg – Optional third party (computed if not provided).

  • Ph – Optional fourth party (computed if not provided).

Returns:

Shared vector.

template<cdough::Encoding EncodingType, typename Ops>
inline void generic_multiply(const EVector &x, const EVector &y, EVector &z, Ops ops = {})

Generic binary operation on shared vectors using the 4PC protocol.

Template function to avoid code duplication for structurally identical operations (e.g., multiply_a and and_b) that differ only in their operators.

The Ops struct should define:

  • operator(): accumulation operation (e.g., + for arithmetic, ^ for boolean)

  • op1: first binary operation (e.g., * for arithmetic, & for boolean)

  • op2: second binary operation (e.g., + for arithmetic, ^ for boolean)

  • do_truncate: boolean constant indicating if truncate() should be called

Template Parameters:
  • EncodingType – The encoding type (AShared or BShared).

  • Ops – Operator functor struct.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void multiply_a(const EVector &x, const EVector &y, EVector &z)

Multiply two arithmetic-shared vectors.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void matrix_right_multiply_with_column_matrix_vectorized_a(const EVector &x, const EVector &y, EVector &z, const size_t lhs_rows, const size_t lhs_cols, const size_t rhs_rows, const size_t rhs_cols)

Multiply an arithmetic-shared matrix with a column matrix.

Parameters:
  • x – Left-hand side matrix (AShared).

  • y – Right-hand side column matrix (AShared).

  • z – Output matrix (AShared).

  • lhs_rows – Number of rows in left-hand side matrix.

  • lhs_cols – Number of columns in left-hand side matrix.

  • rhs_rows – Number of rows in right-hand side matrix.

  • rhs_cols – Number of columns in right-hand side matrix.

inline virtual void conv_2d_vectorized_a(const EVector &x, const EVector &y, EVector &z, const size_t instancesCount, const size_t inputHeight, const size_t inputWidth, const size_t filterHeight, const size_t filterWidth, const size_t strideHeight, const size_t strideWidth, const size_t paddingHeight, const size_t paddingWidth)

Secure 2D convolution.

Parameters:
  • x – Input feature map (AShared).

  • y – Convolution filter (AShared).

  • z – Output feature map (AShared).

  • instancesCount – Number of instances.

  • inputHeight – Height of input feature map.

  • inputWidth – Width of input feature map.

  • filterHeight – Height of convolution filter.

  • filterWidth – Width of convolution filter.

  • strideHeight – Stride along height.

  • strideWidth – Stride along width.

  • paddingHeight – Padding along height.

  • paddingWidth – Padding along width.

inline virtual std::pair<EVector, EVector> div_const_a(const EVector &x, const Data &c)

Divide an arithmetic-shared vector by a constant.

Parameters:
  • x – Input vector.

  • c – Constant divisor.

Returns:

Pair of vectors (quotient and error correction).

inline virtual void and_b(const EVector &x, const EVector &y, EVector &z)

Boolean AND operation.

Parameters:
  • x – First input vector.

  • y – Second input vector.

  • z – Output vector.

inline virtual void not_b(const EVector &x, EVector &y)

Boolean NOT operation.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual void not_b_1(const EVector &x, EVector &y)

Boolean NOT operation for the least significant bit.

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual void b2a_bit(const EVector &x, EVector &y)

Convert a boolean-shared bit in the least significant position to an arithmetic sharing:

4PC share distribution: P0: [B, C, D] -> B C D P1: [C, D, A] -> A C D P2: [D, A, B] -> A B D P3: [A, B, C] -> A B C

Reducing the 4-share to a 2-share: share0 = C ^ D share1 = A ^ B

P0 and P1 can both calculate share0. P2 and P3 can both calculate share1.

Since 2 parties can calculate each of the above, INP can be used to generate a secret-share for share0 and share1.

XOR evaluated as: x ^ y = (x - y)^2 (holds true for binary input)

Parameters:
  • x – Input vector.

  • y – Output vector.

inline virtual std::pair<EVector, EVector> redistribute_shares_b(const EVector &x)

Redistribute boolean shares.

Parameters:

x – Input vector.

Returns:

Pair of vectors (redistributed shares).

inline virtual Data reconstruct_from_a(const std::vector<Share> &shares)

Reconstruct arithmetic shares from a vector of shares.

Parameters:

shares – Input shares.

Returns:

Reconstructed arithmetic shares.

inline virtual Vector reconstruct_from_a(const std::vector<EVector> &shares)

Reconstruct arithmetic shares from a vector of shares.

Parameters:

shares – Input shares.

Returns:

Reconstructed arithmetic shares.

inline virtual Data reconstruct_from_b(const std::vector<Share> &shares)

Reconstruct boolean shares from a vector of shares.

Parameters:

shares – Input shares.

Returns:

Reconstructed boolean shares.

inline virtual Vector reconstruct_from_b(const std::vector<EVector> &shares)

Reconstruct boolean shares from a vector of shares.

Parameters:

shares – Input shares.

Returns:

Reconstructed boolean shares.

inline virtual Vector unchecked_open_a(const EVector &shares)

Open arithmetic shares to reveal plaintext.

Parameters:

shares – Input shared vector.

Returns:

Opened plaintext vector.

inline virtual Vector unchecked_open_b(const EVector &shares)

Open boolean shares to reveal plaintext.

Parameters:

shares – Input shared vector.

Returns:

Opened plaintext vector.

inline virtual std::vector<EVector> get_shares_a(const Vector &data)

Generate arithmetic shares for a vector.

Parameters:

data – Input data vector.

Returns:

Vector of shares for all parties.

inline virtual std::vector<EVector> get_shares_b(const Vector &data)

Generate boolean shares for a vector.

Parameters:

data – Input data vector.

Returns:

Vector of shares for all parties.

inline virtual EVector secret_share_b_internal(const Vector &data, const PartyID &data_party = 0)

Secret share data using the custom 4PC protocol.

Parameters:
  • data – Input data vector.

  • data_party – Party ID of the data party.

Returns:

Secret shared vector.

inline virtual EVector secret_share_a_internal(const Vector &data, const PartyID &data_party = 0)

Secret share data using the custom 4PC protocol.

Parameters:
  • data – Input data vector.

  • data_party – Party ID of the data party.

Returns:

Secret shared vector.

inline virtual EVector public_share(const Vector &x, const std::set<PartyID> &who_knows)

Public sharing of a vector x.

Parameters:
  • x – Input data vector.

  • who_knows – set of parties who know the value

Returns:

EVector

inline virtual void reshare(EVector &v, const std::set<int> group, const bool binary)

An override version of reshare for malicious security in 4PC.

Parameters:
  • v – The vector to be rerandomized and reshared.

  • group – The group performing the resharing.

  • binary – A flag indicating an arithmetic or binary encoding of the vector.

inline virtual void dot_product_a(const EVector &x, const EVector &y, EVector &z, size_t aggSize)

Defines the vectorized dot product operation for consecutive elements.

Parameters:
  • x – The first shared vector of size S.

  • y – The second shared vector of size S.

  • z – The output shared vector.

  • aggSize – The number of consecutive pairs of elements to aggregate.

Public Static Attributes

static int parties_num = 4

Protected Functions

inline int next_party(int i, int j)

Computes the JMP receiver.

Designed to give each party a chance to be the receiver. This is required for open to be correct.

Parameters:
  • i – First party.

  • j – Second party.

Returns:

Party ID of the receiver.

inline int excluded_party(int i, int j, int k)

Return the index of the missing party.

All party indices will sum to 6 (0 + 1 + 2 + 3), so just subtract the given parties to find the missing one.

Parameters:
  • i – First party.

  • j – Second party.

  • k – Third party.

Returns:

Index of the missing party.

inline int abs2rel(int p)

Convert absolute party ID to relative party ID.

Parameters:

p – Absolute party ID.

Returns:

Relative party ID.

inline int rel2abs(int p)

Convert relative party ID to absolute party ID.

Parameters:

p – Relative party ID.

Returns:

Absolute party ID.

inline int abs2sh(int p)

Compute which relative share is \(x_p\) (my share excluding party p).

If self, return 0, even though that’s not a valid share (this is to prevent out-of-bounds array accesses on party-agnostic code).

Parameters:

p – Party ID.

Returns:

Relative share index.

inline int who_hashes(int a, int b)

Given two JMP senders, decide who will hash and who will send.

Different strategies here could change performance by redistributing work. This function must be commutative (who_hashes(a, b) == who_hashes(b, a)).

Parameters:
  • a – First party.

  • b – Second party.

Returns:

Party who should hash.

inline void init_hashes()

Initialize hash states for malicious security.

inline Vector _open_shares(const EVector &sh)

Internal method to open shares using JMP protocol. Malicious check run automatically by the protocol layer.

Parameters:

sh – Input shared vector.

Returns:

Opened plaintext vector.

template<typename cdough::Encoding E>
inline std::vector<EVector> get_shares(const Vector &data)

Generate shares for given data with specified encoding.

Template Parameters:

EEncoding type (AShared or BShared).

Parameters:

data – Input plaintext vector.

Returns:

Vector of shared vectors for all parties.

template<cdough::Encoding E>
inline EVector _secret_share(const Vector &data, const PartyID &data_party)

Internal secret sharing method with specified encoding.

Template Parameters:

EEncoding type (AShared or BShared).

Parameters:
  • data – Input plaintext vector.

  • data_party – Party that owns the data.

Returns:

This party’s shared vector.

inline PartyAssignment _jmp_assignments(int Pi, int Pj, int Pr)

Compute JMP assignments for parties Pi and Pj.

Parameters:
  • Pi – First sending party.

  • Pj – Second sending party.

  • Pr – Receiver

Returns:

Tuple containing hash party, send party, and hash ID.

inline virtual void _jmp_recv(Vector &x, int Pi, int Pj, int Pr)

JMP receive operation for malicious security.

Parameters:
  • x – Vector to receive data into.

  • Pi – First sender party.

  • Pj – Second sender party.

  • Pr – Receiver party (must be this party).

inline virtual void _jmp_send(const Vector &x, int Pi, int Pj, int Pr)

JMP send operation for malicious security.

Parameters:
  • x – Vector to send.

  • Pi – First sender party.

  • Pj – Second sender party.

  • Pr – Receiver party.

inline virtual bool malicious_check_internal()

Malicious check for hash consistency.

Returns:

True if checks passed, false otherwise.

inline virtual void reset_malicious_state()

Reset the internal malicious-detection state.

Private Functions

inline void malicious_check(const Vector &message, const Vector &hash, const int p1, const int p2)

Malicious check to assert that two vectors are the same.

Given two vectors x and y, assert that they are the same. If they are not, accuse the specified parties and abort.

Parameters:
  • x – The first vector.

  • y – The second vector.

  • p1 – The first party relative ID to accuse if they are not the same.

  • p2 – The second party relative ID to accuse if they are not the same.

Private Members

std::map<PartyAssignment, std::unique_ptr<crypto_generichash_state>> hash_states
int thread_id

Private Static Functions

static inline Vector generateHash(const Vector message)

Private Static Attributes

static const auto HASH_RES_BYTES = crypto_generichash_BYTES
static const auto HASH_RES_ELEMENTS = HASH_RES_BYTES / sizeof(Data) + ((HASH_RES_BYTES % sizeof(Data)) != 0)
template<typename Data, template<typename> class Share, template<typename> class Vector, template<typename, int, int> class EVector>
class SPDZ_2k : public cdough::Protocol<Data, Share<ShareTypeSelector<Data>::type>, Vector<Data>, EVector<ShareTypeSelector<Data>::type, 2, std::numeric_limits<Data>::digits>>

Implementation of the SPDZ-2k protocol for n-party.

The SPDZ-2k protocol provides malicious security against dishonest majority, operating over signed integers of k bits with s bits of statistical security. The total share size used is (s+k) bits. We expect input data to be within k bits.

Paper URL: https://eprint.iacr.org/2018/482.pdf

Security Notes:

  1. For production use, ensure that you use secure authenticated preprocessing generators rather than the included dummy generators.

  2. Shares of data are exchanged between parties but shares of MACs are only locally aggregated and seen as an aggregate by other users. Do not expose your MACs to other parties.

  3. Fresh seeds are generated using a commitment protocol for each aggregation round to prevent malicious parties from pre-computing attack strategies. Seeds are committed in batches and opened on-demand to reduce communication overhead.

Template Parameters:
  • Data – - Plaintext data type.

  • Share – - Share type.

  • Vector – - Data container type.

  • EVector – - Share container type.

Public Types

using DataType = Data
using DataVector = Vector<DataType>
using ShareType = typename ShareTypeSelector<Data>::type
using ShareMultiVector = EVector<ShareType, 2, std::numeric_limits<DataType>::digits>

Public Functions

inline SPDZ_2k(const PartyID _partyID, const PartyID _numParties, const ShareType _alpha_i, Communicator *_communicator, random::RandomnessManager *_randomnessManager, const std::shared_ptr<random::AuthRandomGeneratorBase<ShareType, ShareMultiVector>> &_authRGen, const std::shared_ptr<random::AuthTripleGeneratorBase<ShareType, ShareMultiVector>> &_authTGen)

Constructor for SPDZ-2k protocol.

Parameters:
  • _partyID – The (globally) unique identifier of the party that calls this constructor.

  • _numParties – The total number of computing parties participating in the protocol.

  • _alpha_i – The secret share of the MAC key for this party.

  • _communicator – A pointer to the communicator.

  • _randomnessManager – A pointer to the randomness manager.

  • _authRGen – A pointer to the authenticated random generator.

  • _authTGen – A pointer to the authenticated triple generator.

inline void multiply_a(const ShareMultiVector &x, const ShareMultiVector &y, ShareMultiVector &z)

Secure arithmetic multiplication of two secret shared vectors.

Parameters:
  • x – The first secret shared vector.

  • y – The second secret shared vector.

  • z – The output secret shared vector to store the result.

inline void matrix_right_multiply_with_column_matrix_vectorized_a(const ShareMultiVector &x, const ShareMultiVector &y, ShareMultiVector &z, const size_t lhs_rows, const size_t lhs_cols, const size_t rhs_rows, const size_t rhs_cols)
inline void conv_2d_vectorized_a(const ShareMultiVector &x, const ShareMultiVector &y, ShareMultiVector &z, const size_t instancesCount, const size_t inputHeight, const size_t inputWidth, const size_t filterHeight, const size_t filterWidth, const size_t strideHeight, const size_t strideWidth, const size_t paddingHeight, const size_t paddingWidth)
inline std::pair<ShareMultiVector, ShareMultiVector> div_const_a(const ShareMultiVector &x, const DataType &c)

Secure division of an Arithmetic secret shared vector by a public constant. Note: This method is currently not supported in SPDZ-2k.

Parameters:
  • x – The input secret shared vector.

  • c – The public constant to divide by.

Returns:

A pair of secret shared vectors representing the (quotient and error correction).

inline void and_b(const ShareMultiVector &x, const ShareMultiVector &y, ShareMultiVector &z)

Secure bitwise AND of two boolean secret shared vectors. Note: Not supported in SPDZ-2k.

Parameters:
  • x – The first secret shared vector.

  • y – The second secret shared vector.

  • z – The output secret shared vector to store the result.

inline void and_b_1(const ShareMultiVector &first, const ShareMultiVector &second, ShareMultiVector &result)
inline void or_b_1(const ShareMultiVector &first, const ShareMultiVector &second, ShareMultiVector &result)
inline void not_b(const ShareMultiVector &x, ShareMultiVector &y)

Secure bitwise NOT of a boolean secret shared vector. Note: Not supported in SPDZ-2k.

Parameters:
  • x – The input secret shared vector.

  • y – The output secret shared vector to store the result.

inline void not_b_1(const ShareMultiVector &x, ShareMultiVector &y)

Secure NOT of a boolean secret shared vector (LSB only). Note: Not supported in SPDZ-2k.

Parameters:
  • x – The input secret shared vector.

  • y – The output secret shared vector to store the result.

inline void xor_b(const ShareMultiVector &x, const ShareMultiVector &y, ShareMultiVector &z)
inline void xor_b_1(const ShareMultiVector &x, const ShareMultiVector &y, ShareMultiVector &z)
inline void inplace_invert_b(ShareMultiVector &x)
inline void pack_from(const ShareMultiVector &in, ShareMultiVector &out, const size_t pos)
inline void unpack_from(const ShareMultiVector &in, ShareMultiVector &out, const size_t pos)
inline void bit_arithmetic_right_shift(const ShareMultiVector &in, ShareMultiVector &out, const int &shift_size)
inline void bit_logical_right_shift(const ShareMultiVector &in, ShareMultiVector &out, const int &shift_size)
inline void bit_left_shift(const ShareMultiVector &in, ShareMultiVector &out, const int &shift_size)
inline void bit_xor(const ShareMultiVector &in, ShareMultiVector &out)
inline void extend_lsb(const ShareMultiVector &in, ShareMultiVector &out)
inline void mask(const ShareMultiVector &in, const DataType mask_value)
inline void ltz(const ShareMultiVector &in, ShareMultiVector &out)
inline void b2a_bit(const ShareMultiVector &x, ShareMultiVector &y)

Convert boolean-shared bit to arithmetic sharing. Note: Not supported in SPDZ-2k.

Parameters:
  • x – Input boolean shared vector.

  • y – Output arithmetic shared vector.

inline std::pair<ShareMultiVector, ShareMultiVector> redistribute_shares_b(const ShareMultiVector &x)

Redistribute arithmetic shares among parties. Note: Not supported in SPDZ-2k because it only supports arithmetic sharing.

Parameters:

x – Input vector.

Returns:

Pair of redistributed shared vectors.

inline DataType reconstruct_from_a(const std::vector<Share<ShareType>> &shares)

Reconstruct plaintext from arithmetic shares. It opens shares without communication. Note: This method is for protocols developer only. Users should use open_shares_a() instead.

Parameters:

shares – Input shares from all parties.

Returns:

Reconstructed plaintext value.

inline Vector<DataType> reconstruct_from_a(const std::vector<ShareMultiVector> &shares)

Reconstruct plaintext vector from arithmetic shares. It opens shares without communication. Note: This method is for protocols developer only. Users should use open_shares_a() instead.

Parameters:

shares – Input shared vectors from all parties.

Returns:

Reconstructed plaintext vector.

inline DataType reconstruct_from_b(const std::vector<Share<ShareType>> &shares)

Reconstruct plaintext from boolean shares. It opens shares without communication. Note: This method is for protocols developer only. Users should use open_shares_b() instead. Note: Not supported in SPDZ-2k.

Parameters:

shares – Input shares from all parties.

Returns:

Reconstructed plaintext value.

inline Vector<DataType> reconstruct_from_b(const std::vector<ShareMultiVector> &shares)

Reconstruct plaintext vector from boolean shares. It opens shares without communication. Note: This method is for protocols developer only. Users should use open_shares_b() instead. Note: Not supported in SPDZ-2k.

Parameters:

shares – Input shared vectors from all parties.

Returns:

Reconstructed plaintext vector.

inline virtual bool malicious_check_internal()

Finalize the malicious check after opening shares. It verifies the MACs of the opened shares so far.

Returns:

true if the verification succeeded, false otherwise.

inline Vector<DataType> unchecked_open_a(const ShareMultiVector &shares)

Open arithmetic shares to reveal plaintext. It opens shares with communication. Protocol layer handles malicious checks.

Parameters:

shares – Input A shared vector.

Returns:

Opened plaintext vector.

inline Vector<DataType> unchecked_open_b(const ShareMultiVector &shares)

Open boolean shares to reveal plaintext. It opens shares with communication. Note: Not supported in SPDZ-2k.

Parameters:

shares – Input boolean shared vector.

Returns:

Reconstructed plaintext vector.

inline std::vector<ShareMultiVector> get_shares_a(const Vector<DataType> &data)

Secret share plaintext vector into arithmetic shares. It should be generating shares without communication. Note: functionality not supported in SPDZ-2k.

Parameters:

data – Input plaintext vector.

Returns:

Vector of secret shared vectors for all parties.

inline std::vector<ShareMultiVector> get_shares_b(const Vector<DataType> &data)

Secret share plaintext vector into boolean shares. It should be generating shares without communication. Note: functionality not supported in SPDZ-2k.

Parameters:

data – Input plaintext vector.

Returns:

Vector of secret shared vectors for all parties.

inline ShareMultiVector secret_share_b_internal(const Vector<DataType> &data, const PartyID &data_party = 0)

Secret share plaintext vector into boolean shares. It uses communication to secret share the data. Note: functionality not supported in SPDZ-2k. Note: Can not be supported for 128-bit also.

Parameters:
  • data – Input plaintext vector.

  • data_party – The party that provides the input data.

Returns:

Secret shared vector.

inline ShareMultiVector secret_share_a_internal(const Vector<DataType> &data, const PartyID &data_party = 0)

Secret share plaintext vector into arithmetic shares. It uses communication to secret share the data. Note: does not support DataType of __int128_t.

Parameters:
  • data – Input plaintext vector.

  • data_party – The party that provides the input data.

Returns:

Secret shared vector.

inline ShareMultiVector public_share(const Vector<DataType> &x, const std::set<PartyID> &who_knows)

Create public shares from plaintext vector. Note: does not support DataType of __int128_t.

What happens if someone tries to open a public share? They key share is still safe because MAC shares do not leave the computing parties. Pay close attention to the BatchCheck protocol.

Parameters:

x – Input plaintext vector.

Returns:

Public shared vector.

inline ShareMultiVector public_share(const Vector<DataType> &x)
inline ShareMultiVector add_public_a(const ShareMultiVector &x, const Data val)
inline ShareMultiVector sub_public_a(const ShareMultiVector &x, const Data val)
inline ShareMultiVector multiply_public_a(const ShareMultiVector &x, const Vector<Data> &val)
inline ShareMultiVector multiply_public_a(const ShareMultiVector &x, const Data &val)
inline virtual void reset_malicious_state()

Reset the malicious state. It clears the aggregatedDiff and back log.

Public Static Attributes

static int parties_num

Private Types

using UnsignedDataType = typename std::make_unsigned<DataType>::type
using UnsignedShareType = typename std::make_unsigned<ShareType>::type

Private Functions

inline void addToAggregationBackLog(const ShareMultiVector &shares)

Add the opened shares to the verification back log for later MAC checking.

inline void processAggregationBackLog()

Process the verification back log to calculate the aggregated difference for MAC checking.

inline void optionalAggregationBackLogOptimization()

Optional optimization to process the verification back log in batches to reduce memory overhead. This can be called after each partial opening to ensure that the back log does not grow too large, which can lead to high memory usage. The threshold for processing can be adjusted based on the expected size of the opened shares and the available memory resources.

inline Vector<ShareType> initiateBatchCheck(const ShareMultiVector &shares, const bool addMask = true)

Initiate batch opening and MAC checking of secret shared values.

Parameters:
  • shares – The secret shared values to open and verify.

  • addMask – Whether to add random masks before opening. Use by default unless opening for intermediate secret shares inside the multiplication protocol.

inline bool finalizeBatchCheck(bool shouldAbort = true)

Finalize the batch opening and MAC checking of secret shared values.

Parameters:

shouldAbort – Whether to abort the protocol on verification failure.

Returns:

true if the verification succeeded, false otherwise.

inline Vector<ShareType> partial_open(const ShareMultiVector &shares, const bool addMask = true)

Partial opening of secret shared values with MAC checking. This function initiates the batch opening and MAC checking.

Parameters:
  • shares – The secret shared values to open and verify.

  • addMask – Whether to add random masks before opening. Use by default unless opening for intermediate secret shares inside the multiplication protocol.

Returns:

The opened values as a vector.

inline Vector<DataType> packIntoKBits(const Vector<DataType> &data)

Pack data into k bits by moving the sign bit to the k-th position. Useful if need you use less number of bits than the data type size.

Parameters:

data – The input data to be packed.

Returns:

The packed data with sign bit at k-th position.

inline Vector<DataType> unPackIntoKBits(const Vector<DataType> &data)

Unpack data from k bits by moving the sign bit from the k-th position to the most significant bit. This is the reverse operation of packIntoKBits.

Parameters:

data – The input data to be unpacked.

Returns:

The unpacked data with sign bit at the most significant bit.

Private Members

const ShareType MAX_BITS_NUMBER = std::numeric_limits<UnsignedShareType>::digits
const ShareType k = std::numeric_limits<UnsignedDataType>::digits
const ShareType s = std::max((ShareType)48, MAX_BITS_NUMBER - k)
const ShareType r = MAX_BITS_NUMBER - s - k
const ShareType s2 = (ShareType)1 << (s - 1)
const ShareType k2 = (ShareType)1 << (k - 1)
const ShareType ks2 = (ShareType)1 << (k + s - 1)
const ShareType mask_s = ((ShareType)1 << s) - 1
const ShareType mask_k = ((ShareType)1 << k) - 1
const ShareType mask_ks = ((ShareType)1 << (k + s)) - 1
const ShareType alpha_i
std::vector<ShareMultiVector> aggregationBackLog
size_t backLogElementSize = 0
ShareType aggregatedDiff = 0
std::shared_ptr<random::AuthRandomGeneratorBase<ShareType, ShareMultiVector>> authRGen
std::shared_ptr<random::AuthTripleGeneratorBase<ShareType, ShareMultiVector>> authTGen
std::shared_ptr<random::CommonPRGManager> rGen
std::shared_ptr<random::CommonPRG> localPRG
std::unique_ptr<random::CommittedSeedsQueue> seedQueue
std::vector<cdough::PartyID> toPartyIDs_
std::vector<cdough::PartyID> fromPartyIDs_
std::set<cdough::PartyID> allPartiesSet_

Private Static Functions

static inline cdough::Vector<int8_t> generateHash(const Vector<ShareType> packedMessage)

Generate a hash of the given aggregate using libsodium.

Parameters:

packedMessage – The aggregate to hash + the key.

Returns:

The hash of the aggregate as a Vector of int8_t.

Private Static Attributes

static const auto HASH_RES_BYTES = crypto_generichash_BYTES
static const auto HASH_KEY_BYTES = crypto_generichash_KEYBYTES
static const auto HASH_MESSAGE_BYTES = sizeof(ShareType)
static const auto HASH_PACKED_MESSAGE_BYTES = sizeof(ShareType) + crypto_generichash_BYTES
static const auto HASK_PACKED_MESSAGE_SIZE = (HASH_PACKED_MESSAGE_BYTES + sizeof(ShareType) - 1) / sizeof(ShareType)
static size_t HEURISTIC_MAX_BACKLOG_ELEMENT_SIZE = 1 << 24
static size_t HEURISTIC_MAX_BACKLOG_SIZE = 24

Utilities and Base Classes

namespace cdough
template<typename Data, typename Share, typename Vector, typename EVector>
class Protocol : public cdough::ProtocolBase
#include <protocol.h>

Abstract class defining primitive methods for secure protocols.

This is the abstract class that defines the primitive methods each secure protocol must implement.

Primitive operations are grouped as follows:

  1. Arithmetic operations on arithmetic shares.

  2. Boolean operations on boolean shares.

  3. Primitives for sending and receiving shares.

  4. Primitives for constructing and opening shares to learners.

Template Parameters:
  • Data – Plaintext data type.

  • Share – Share type (e.g., a 32-bit integer, a pair of 64-bit integers, etc.).

  • Vector – Data container type.

  • EVector – Share container type.

Subclassed by cdough::protocols::SPDZ_2k< T, S, V, cdough::EVector >, cdough::protocols::edabits_protocol< T, S, V, cdough::EVector, typename ProtocolFactoryA::template ProtocolInstance< T >, typename ProtocolFactoryB::template ProtocolInstance< T > >, cdough::Beaver_2PC< Data, Share, Vector, EVector >, cdough::Dummy_0PC< Data, Share, Vector, EVector >, cdough::Fantastic_4PC< Data, Share, Vector, EVector >, cdough::Fantastic_4PC< Data, Share, Vector, EVector >, cdough::Plaintext_1PC< Data, Share, Vector, EVector >, cdough::Replicated_3PC< Data, Share, Vector, EVector >

Public Functions

inline Protocol(Communicator *_communicator, random::RandomnessManager *_randomnessManager, PartyID _partyID, int _numParties, int _replicationNumber)

Protocol constructor.

Parameters:
  • _communicator – A pointer to the communicator.

  • _randomnessManager – A pointer to the randomness manager.

  • _partyID – The (globally) unique identifier of the party that calls this constructor.

  • _numParties – The total number of computing parties participating in the protocol.

  • _replicationNumber – The protocol’s replication factor.

inline virtual ~Protocol()

Destructor.

inline virtual void reshare(EVector &v, const std::set<int> group, bool binary)

Reshare shares with other parties.

The group rerandomizes the vector v and sends shares to all parties that are not in the group.

Operates in place.

TODO: fix runtime to support this better.

Parameters:
  • v – The EVector representing each party’s view of the vector to be

  • group – The group of parties that perform the resharing.

  • binary – whether this is a binary (true) or arithmetic (false) resharing reshared.

inline virtual void handle_precision(const EVector &x, const EVector &y, EVector &z)
inline virtual void add_a(const EVector &x, const EVector &y, EVector &z)

Defines vectorized arithmetic addition.

Parameters:
  • x – The first shared vector of size S.

  • y – The second shared vector of size S.

  • z – The output shared vector of size S.

inline virtual void sub_a(const EVector &x, const EVector &y, EVector &z)

Defines vectorized arithmetic subtraction.

Parameters:
  • x – The first shared vector of size S.

  • y – The second shared vector of size S.

  • z – The output shared vector of size S.

virtual void multiply_a(const EVector &first, const EVector &second, EVector &result) = 0

Defines vectorized arithmetic multiplication.

Parameters:
  • first – The first shared vector of size S.

  • second – The second shared vector of size S.

  • result – The output shared vector of size S.

inline virtual void neg_a(const EVector &in, EVector &out)

Defines vectorized arithmetic negation.

Parameters:
  • in – The input shared vector of size S.

  • out – The output shared vector of size S.

virtual std::pair<EVector, EVector> div_const_a(const EVector &input, const Data &c) = 0

Defines vectorized arithmetic division by constant.

Parameters:
  • input – The input shared vector.

  • c – The constant divisor.

Returns:

Pair of shared vectors representing the division result.

inline virtual void dot_product_a(const EVector &x, const EVector &y, EVector &z, size_t aggSize)

Defines the vectorized dot product operation for consecutive elements.

Parameters:
  • x – The first shared vector of size S.

  • y – The second shared vector of size S.

  • z – The output shared vector.

  • aggSize – The number of consecutive pairs of elements to aggregate.

inline virtual void matrix_right_multiply_with_column_matrix_vectorized_a(const EVector &x, const EVector &y, EVector &z, const size_t lhs_rows, const size_t lhs_cols, const size_t rhs_rows, const size_t rhs_cols)

Secure matrix right multiplication with a column matrix, vectorized implementation. Expects the left-hand side matrix to be in row-major order. Expects the right-hand side matrix to be in column-major order.

Parameters:
  • x – The left-hand side matrix as a shared vector.

  • y – The right-hand side column matrix as a shared vector.

  • z – The output shared vector.

  • lhs_rows – Number of rows in the left-hand side matrix.

  • lhs_cols – Number of columns in the left-hand side matrix.

  • rhs_rows – Number of rows in the right-hand side matrix.

  • rhs_cols – Number of columns in the right-hand side matrix.

inline virtual void conv_2d_vectorized_a(const EVector &x, const EVector &y, EVector &z, const size_t instancesCount, const size_t inputHeight, const size_t inputWidth, const size_t filterHeight, const size_t filterWidth, const size_t strideHeight, const size_t strideWidth, const size_t paddingHeight, const size_t paddingWidth)

Secure 2D convolution.

Input layout: The input consists of mutiple instances concatenated after each other. Hence, the input size = instancesCount * inputHeight * inputWidth. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 input with 2 channels: [ch1(0,0), ch2(0,0), ch1(0,1), ch2(0,1), ch1(1,0), ch2(1,0), ch1(1,1), ch2(1,1)]

Filter layout: the filter is expected to have multiple channels. Hence, the filter size = channels * filterHeight * filterWidth. For example, the the physical layout for 2x2 filter with 2 channels:

[f_ch1(0,0), f_ch2(0,0), f_ch1(1,0), f_ch2(1,0), g_ch1(0,1), g_ch2(0,1), g_ch1(1,1), g_ch2(1,1)]

Output layout: (same layout as input but different height and width). The output consists of mutiple instances concatenated after each other. Hence, the output size = instancesCount * outputHeight * outputWidth * channels. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 output with 2 channels: [f(0,0), g(0,0), f(0,1), g(0,1), f(1,0), g(1,0), f(1,1), g(1,1)]

Parameters:
  • x – The input shared vector.

  • y – The filter shared vector.

  • z – The output shared vector.

  • instancesCount – Number of instances in the input.

  • inputHeight – Height of each input instance.

  • inputWidth – Width of each input instance.

  • filterHeight – Height of each filter channel.

  • filterWidth – Width of each filter channel.

  • strideHeight – Stride height.

  • strideWidth – Stride width.

  • paddingHeight – Padding height.

  • paddingWidth – Padding width.

inline virtual void sumPoolingVectorized(const EVector &x, const EVector &y, EVector &z, const size_t instancesCount, const size_t channels, const size_t inputHeight, const size_t inputWidth, const size_t poolHeight, const size_t poolWidth, const size_t strideHeight, const size_t strideWidth, const size_t paddingHeight, const size_t paddingWidth)

Secure sum pooling. Aggregates values within pooling windows by summing them. Aggregation is performed over multiple instances with multiple channels. Each layer is pooled independently.

Input layout: The input consists of mutiple instances concatenated after each other. Hence, the input size = instancesCount * inputHeight * inputWidth * channels. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 input with 2 channels: [ch1(0,0), ch2(0,0), ch1(0,1), ch2(0,1), ch1(1,0), ch2(1,0), ch1(1,1), ch2(1,1)]

Output layout: same layout as input but with different height and width.

Parameters:
  • x – The input shared vector.

  • y – (unused) Placeholder for compatibility with other protocols.

  • z – The output shared vector.

  • instancesCount – Number of instances in the input.

  • channels – Number of channels in each instance.

  • inputHeight – Height of each input instance.

  • inputWidth – Width of each input instance.

  • poolHeight – Height of the pooling window.

  • poolWidth – Width of the pooling window.

  • strideHeight – Stride height.

  • strideWidth – Stride width.

  • paddingHeight – Padding height.

  • paddingWidth – Padding width.

inline virtual void truncate(EVector &x)

Defines vectorized arithmetic truncation. This method must take one input vector with arithmetic shares and return a new vector that contains arithmetic shares of the truncated input. The default implementation invokes the protocol’s public division protocol.

Note

This default protocol assumes that public division is still secure when the error correction is not applied. This holds for all protocols currently in the system.

Parameters:

x – - The shared vector to truncate.

inline virtual void xor_b(const EVector &x, const EVector &y, EVector &z)

Defines vectorized bitwise XOR (^).

Parameters:
  • x – The first shared vector of size S.

  • y – The second shared vector of size S.

  • z – The output shared vector of size S.

inline virtual void xor_b_1(const EVector &x, const EVector &y, EVector &z)
virtual void and_b(const EVector &first, const EVector &second, EVector &result) = 0

Defines vectorized bitwise AND (&).

Parameters:
  • first – The first shared vector of size S.

  • second – The second shared vector of size S.

  • result – The output shared vector of size S.

virtual void not_b(const EVector &in, EVector &out) = 0

Defines vectorized boolean complement (~).

Parameters:
  • in – The input shared vector of size S.

  • out – The output shared vector of size S.

virtual void not_b_1(const EVector &in, EVector &out) = 0

Defines vectorized boolean NOT (!).

Parameters:
  • in – The input shared vector of size S.

  • out – The output shared vector of size S.

inline virtual void gtez_a(const EVector &in, EVector &out)
inline virtual void and_b_1(const EVector &first, const EVector &second, EVector &result)

Defines vectorized logical AND (&&).

Assumes data in range between 0 and 1. Otherwise, it returns incorrect results.

Parameters:
  • first – The first shared vector of size S.

  • second – The second shared vector of size S.

  • result – The output shared vector of size S.

inline virtual void or_b(const EVector &first, const EVector &second, EVector &result)

Defines vectorized bitwise OR (|).

Parameters:
  • first – The first shared vector of size S.

  • second – The second shared vector of size S.

  • result – The output shared vector of size S.

inline virtual void or_b_1(const EVector &first, const EVector &second, EVector &result)

Defines vectorized logical OR (||).

Assumes data in range between 0 and 1. Otherwise, it returns incorrect results.

Parameters:
  • first – The first shared vector of size S.

  • second – The second shared vector of size S.

  • result – The output shared vector of size S.

inline virtual void equal_b(const EVector &first, const EVector &second, EVector &result)
inline virtual void compare_b(const EVector &first, const EVector &second, EVector &eq_bits, EVector &gt_bits)
inline virtual void rca_compare_b(const EVector &first, const EVector &second, EVector &gt_bits)
inline virtual void linear_compare_b(const EVector &x, const EVector &y, EVector &eq_bits, EVector &gt_bits)
inline virtual void ripple_carry_adder_b(const EVector &x, const EVector &y, EVector &res, const bool carry_in)
inline virtual void ripple_carry_adder_packed_sign_b(const EVector &x, const EVector &y, EVector &res, const bool carry_in)
inline virtual void parallel_prefix_adder_b(const EVector &x, const EVector &y, EVector &res, const bool &carry_in)
inline virtual void parallel_prefix_adder_packed_sign_b(const EVector &x, const EVector &y, EVector &res, const bool carry_in)
inline virtual void inplace_invert_b(EVector &x)
inline virtual void ltz(const EVector &in, EVector &out)

Defines vectorized less-than-zero comparison.

Parameters:
  • in – The input shared vector of size S.

  • out – The output shared vector of size S.

inline virtual void pack_from(const EVector &source, EVector &destination, const int &pos)
inline virtual void unpack_from(const EVector &source, EVector &destination, const int &pos)
inline virtual void bit_arithmetic_right_shift(const EVector &in, EVector &out, const int &shift_size)
inline virtual void bit_logical_right_shift(const EVector &in, EVector &out, const int &shift_size)
inline virtual void bit_left_shift(const EVector &in, EVector &out, const int &shift_size)
inline virtual void bit_xor(const EVector &in, EVector &out)
inline virtual void extend_lsb(const EVector &in, EVector &out)
inline virtual void mask(EVector &in, const Data mask_value)
virtual void b2a_bit(const EVector &in, EVector &out) = 0

Defines vectorized boolean-to-arithmetic single bit conversion.

Parameters:
  • in – A B-shared vector of S single-bit elements.

  • out – The output A-shared vector of size S.

inline virtual void a2b_packed_sign_a_b(const EVector &in, EVector &out)
virtual std::pair<EVector, EVector> redistribute_shares_b(const EVector &x) = 0

Defines a redistribution of arithmetic secret shares into boolean secret shares.

Parameters:

x – The input arithmetic shared vector.

Returns:

Pair of boolean shared vectors representing the redistribution.

virtual Data reconstruct_from_a(const std::vector<Share> &shares) = 0

Defines how to reconstruct a single data value by adding its arithmetic shares.

NOTE: This method is useful when a computing party also acts as learner that receives arithmetic shares from other parties and needs to reconstruct a true value.

Parameters:

shares – The input vector containing arithmetic shares of the secret value.

Returns:

The plaintext value of type Data.

virtual Vector reconstruct_from_a(const std::vector<EVector> &shares) = 0

Vectorized version of the reconstruct_from_a() method.

NOTE: This method is useful when a computing party also acts as learner that receives arithmetic shared vectors from other parties and needs to reconstruct the original vector.

Parameters:

shares – A vector of shared vectors (each one of size n) that contain arithmetic shares.

Returns:

A new vector that contains n plaintext values of type Data.

virtual Data reconstruct_from_b(const std::vector<Share> &shares) = 0

Defines how to reconstruct a single data value by XORing its boolean shares.

NOTE: This method is useful when a computing party also acts as learner that receives boolean shares from other parties and needs to reconstruct a true value.

Parameters:

shares – The input vector containing boolean shares of the secret value.

Returns:

The plaintext value of type Data.

virtual Vector reconstruct_from_b(const std::vector<EVector> &shares) = 0

Vectorized version of the reconstruct_from_b() method.

NOTE: This method is useful when a computing party also acts as learner that receives boolean shared vectors from other parties and needs to reconstruct the original vector.

Parameters:

shares – A vector of shared vectors (each one of size n) that contain boolean shares.

Returns:

A new vector that contains n plaintext values of type Data.

inline Vector open_shares_a(const EVector &shares)

Opens arithmetic shares to reveal plaintext values. For malicious protocols, run a check before (to prevent leakage) and after (to confirm proper opening). In test mode, returns empty vectors instead of aborting.

Parameters:

shares – A shared vector that contains arithmetic shares of the secret values.

Returns:

A new vector that contains the plaintext values of type Data.

inline Vector open_shares_b(const EVector &shares)

Opens boolean shares to reveal plaintext values. For malicious protocols, run a check first.

NOTE: This method is useful when computing parties need to reveal a secret-shared vector to each other.

Parameters:

shares – A shared vector that contains boolean shares of the secret values.

Returns:

A new vector that contains the plaintext values of type Data.

virtual Vector unchecked_open_a(const EVector &shares) = 0
virtual Vector unchecked_open_b(const EVector &shares) = 0
virtual std::vector<EVector> get_shares_a(const Vector &data) = 0

Compute secret shares for a vector of plaintext values.

Parameters:

data – A vector of input values of type Data.

Returns:

A vector of shared vectors containing arithmetic shares.

virtual std::vector<EVector> get_shares_b(const Vector &data) = 0

Compute secret shares for a vector of plaintext values.

Parameters:

data – A vector of input values of type Data.

Returns:

A vector of shared vectors containing boolean shares.

virtual EVector secret_share_b_internal(const Vector &data, const PartyID &data_party) = 0

Compute secret shares for a vector of plaintext values.

NOTE: This method is useful for secret-sharing plaintext data in cdough programs.

Parameters:
  • data – The plaintext vector that must be secret-shared among computing parties.

  • data_party – The party that owns the data.

Returns:

The boolean shared vector

inline virtual EVector secret_share_b_internal(const Vector &data, const PartyID &data_party, const int &fixed_point_precision)

Compute secret shares for a vector of plaintext values. Overloaded secret_share_b_internal function that establishes a non-zero fixed-point precision.

Parameters:
  • data – The plaintext vector that must be secret-shared among computing parties.

  • data_party – The party that owns the data.

  • fixed_point_precision – precision of the input values

Returns:

The boolean shared fixed-point vector

virtual EVector secret_share_a_internal(const Vector &data, const PartyID &data_party) = 0

Defines how to A-share a plaintext vector according to a protocol.

NOTE: This method is useful for secret-sharing plaintext data in cdough programs.

Parameters:
  • data – - The plaintext vector that must be secret-shared among computing parties.

  • data_party – data ownner

Returns:

The arithmetic shared vector of the party that calls this method.

inline virtual EVector secret_share_a_internal(const Vector &data, const PartyID &data_party, const int &fixed_point_precision)

Compute secret shares for a vector of plaintext values. Overloaded secret_share_a_internal function that establishes a non-zero fixed-point precision.

Parameters:
  • data – The plaintext vector that must be secret-shared among computing parties.

  • data_party – The party that owns the data.

  • fixed_point_precision – precision of the input values

Returns:

The arithmetic shared fixed-point vector

virtual EVector public_share(const Vector &x, const std::set<PartyID> &who_knows) = 0

Create a “secret” share of a public value, x. This implemented by setting one share to x and all others to zero; this gives a valid sharing under both arithmetic and boolean.

Parameters:
  • x – The public vector to share.

  • who_knows – a party who knows the value

Returns:

The shared vector.

inline virtual EVector public_share(const Vector &x)

Convenience overload that defaults to an empty who_knows set.

inline virtual EVector public_share(const Vector &x, const std::set<PartyID> &who_knows, const int &fixed_point_precision)

An overloaded public_share function that establishes a non-zero fixed-point precision.

Parameters:
  • x

  • fixed_point_precision

Returns:

EVector

Public Members

Communicator *communicator
random::RandomnessManager *randomnessManager

Defines

TYPE_BITS_int8_t
TYPE_BITS_int16_t
TYPE_BITS_int32_t
TYPE_BITS_int64_t
TYPE_BITS___int128_t
TYPE_BITS(T)
GLUE_(a, b)
GLUE(a, b)
PROTO_OBJ_NAME(T)
namespace cdough

Enums

enum class ReshareAction

Actions for resharing operations.

Values:

enumerator Send
enumerator Receive
class ProtocolBase
#include <protocol_base.h>

Base class for all secure multi-party computation protocols.

Subclassed by cdough::Protocol< T, std::vector< T >, Vector< T >, GenericInnerContainer< T > >, cdough::Protocol< T, S< T >, V< T >, E< T > >, cdough::Protocol< Data, Share< ShareTypeSelector< Data >::type >, Vector< Data >, EVector< ShareTypeSelector< Data >::type, 2, std::numeric_limits< Data >::digits > >, cdough::Protocol< Data, Share< AProtocol::ShareType >, Vector< Data >, AProtocol::ShareMultiVector >, cdough::Protocol< Data, Share, Vector, EVector >

Public Functions

inline ProtocolBase(PartyID pID, int partiesNum, int replicationNum)

Constructor for ProtocolBase.

Parameters:
  • pID – Party identifier for this protocol instance.

  • partiesNum – Total number of parties in the protocol.

  • replicationNum – Replication factor for the protocol.

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

Get the groups for shuffling operations.

Returns:

Vector of party groups for shuffling.

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

Get a mapping from parties to share numbers.

Returns:

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

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

Get a mapping from shares to parties holding that share.

Returns:

Vector mapping share IDs to party lists.

inline int getPartyID() const

Get the party ID for this protocol instance.

Returns:

Party identifier.

inline const int getRepNumber() const

Get the replication number for this protocol.

Returns:

Replication factor.

inline const int getNumParties() const

Get the total number of parties in this protocol.

Returns:

Number of parties.

inline virtual void print_statistics()

Print statistics for this protocol. The default is to do nothing, but protocols may choose to override this function to print operator counts, network statistics, or other information.

inline virtual void mark_statistics()

Mark statistics. This can be used to take relative measurements of a section of code.

inline virtual void clear_statistics()

Clear all accumulated statistics (counters, marks, etc.).

inline virtual bool malicious_check()

Check for malicious behavior. Aborts if malicious behavior occurred.

In MAL_TEST_MODE, does not abort, and resets internal state. MAL_TEST_MODE should only be used for explicitly testing malicious behavior, and never on benchmarks or real queries.

Public Members

size_t send_calls = 0
size_t recv_calls = 0

Public Static Functions

static inline void generateAllCombinations(std::set<int> set, std::set<int> partial_set, int size, std::vector<std::set<int>> &combinations)

Generates all combinations of a given size of an input size (recursively).

Parameters:
  • set – the set of ints to find combinations of.

  • partial_set – the partially complete combination at any given point in the recursion.

  • size – the size of the combinations to search for, decremented with each recursive call.

  • combinations – a vector of combinations to be filled throughout the algorithm.

static inline std::vector<std::set<int>> generateGroups(int num_parties, int parties_to_reconstruct, int num_adversaries)

Defines the groups for the protocol.

This is a STATIC function to be callable during setup before protocol objects exist.

Parameters:
  • num_parties – The number of parties in the protocol.

  • parties_to_reconstruct – Number of parties needed to reconstruct.

  • num_adversaries – Number of adversarial parties.

Returns:

The vector of groups.

static inline std::vector<std::set<int>> generateRandomnessGroups(int n, int n_reconstruct, int n_adversary)

Generate randomness groups (includes the group of everyone).

Parameters:
  • n – Number of parties.

  • n_reconstruct – Number of parties needed for reconstruction.

  • n_adversary – Number of adversarial parties.

Returns:

Vector of randomness groups.

Protected Attributes

PartyID partyID
const int numParties
const int replicationNumber
std::map<std::set<int>, ReshareAssignment> reshareMap = {}

Map from party-groups to resharing assignment.

reshare will retrieve a list of assignments from this map given the current group, and then each party will execute its respective instructions.

Private Functions

inline void generatePartyShareMappings()

Defines the mapping from rank to the secret shares held by that rank.

Index i in the vector is the set of shares held by rank i. For a replication k, party i holds shares [i, i+1, …, i+k-1]. This function should be called during construction.

inline void generateSharePartyMappings()

Generate a mapping from shares to parties holding that share.

Called during construction to populate the mapping.

inline auto generate_send_assignment(int p, std::set<int> group)

Generate send assignment for resharing shares to other parties.

Parameters:
  • p – Party identifier.

  • group – Set of parties in the resharing group.

Returns:

ReshareAssignment for sending shares.

inline auto generate_recv_assignment(int p, std::set<int> group)

Generate receive assignment for resharing shares from other parties.

Parameters:
  • p – Party identifier.

  • group – Set of parties in the resharing group.

Returns:

ReshareAssignment for receiving shares.

inline virtual bool malicious_check_internal()

Internal code to check for malicious behavior. Semihonest protocols should not implement. Malicious protocols should implement their checks here.

Returns:

true no malicious behavior occurred

Returns:

false malicious behavior occurred

inline virtual void reset_malicious_state()

Reset the internal malicious-detection state.

Private Members

std::vector<std::vector<int>> partyShareMap = {}
std::vector<std::vector<int>> sharePartyMap = {}

Friends

friend class service::Worker
struct ReshareAssignment
#include <protocol_base.h>

Assignment for resharing operations.

Defines whether a party sends or receives shares during resharing, along with the target parties and share indices.

Public Members

ReshareAction action
std::vector<int> ranks
std::vector<int> shareIdx
namespace service
namespace cdough
namespace protocols
namespace circuits

Functions

template<typename Share, typename BContainer, typename Protocol>
static void ripple_carry_adder(const BContainer &a, const BContainer &b, BContainer &sum, const bool carry_in, Protocol &protocol)
template<typename Share, typename BContainer, typename Protocol>
static void ripple_carry_adder_packed_sign(const BContainer &a, const BContainer &b, BContainer &sum, const bool carry_in, Protocol &protocol)
template<typename Share, typename BContainer, typename Protocol>
static void rca_compare(const BContainer &a, const BContainer &b, BContainer &sum, Protocol &protocol)
template<typename Share, typename BContainer, typename Protocol>
static std::pair<BContainer, BContainer> prefix_sum(const std::pair<BContainer, BContainer> &x, const std::pair<BContainer, BContainer> &y, Protocol &protocol)
template<typename Share, typename BContainer, typename Protocol>
static void parallel_prefix_adder(const BContainer &current, const BContainer &other, BContainer &sum, const bool carry_in, Protocol &protocol)
template<typename Share, typename BContainer, typename Protocol>
static void parallel_prefix_adder_packed_sign(const BContainer &a, const BContainer &b, BContainer &sum, const bool carry_in, Protocol &protocol)
template<typename Share, typename BContainer, typename Protocol>
BContainer bit_same(const BContainer &x, const BContainer &y, std::optional<BContainer> _temp, Protocol &protocol)
template<typename Share, typename BContainer, typename Protocol>
static void linear_compare(const BContainer &current, const BContainer &other, BContainer &eq_bits, BContainer &gt_bits, Protocol &protocol)
template<typename Share, typename BContainer, typename Protocol>
static void compare(const BContainer &current, const BContainer &other, BContainer &eq_bits, BContainer &gt_bits, Protocol &protocol)
namespace cdough
template<template<typename, typename, typename, typename> class Protocol, template<typename> class S, template<typename> class V, template<typename> class E>
class DefaultProtocolFactory : public cdough::ProtocolFactory<DefaultProtocolFactory<Protocol, S, V, E>>
#include <protocol_factory.h>

Default protocol factory implementation.

Template Parameters:
  • Protocol – The protocol class template.

  • S – Share type template.

  • V – Vector type template.

  • EEncoding vector type template.

Public Types

template<typename T>
using ProtocolInstance = Protocol<T, S<T>, V<T>, E<T>>
template<typename T>
using AInnerContainer = E<T>
template<typename T>
using BInnerContainer = E<T>

Public Functions

inline DefaultProtocolFactory(int partyID, int partiesNumber)

Constructor for DefaultProtocolFactory.

Parameters:
  • partyID – The party identifier.

  • partiesNumber – The total number of parties.

template<typename T>
inline std::unique_ptr<ProtocolBase> create(int thread_id, Communicator *communicator, random::RandomnessManager *randomnessManager)

Create a protocol instance for the given data type.

Template Parameters:

T – The data type for the protocol.

Parameters:
  • thread_id

  • communicator – Pointer to the communicator.

  • randomnessManager – Pointer to the randomness manager.

Returns:

Unique pointer to the created protocol instance.

Public Static Attributes

static const int DefaultNumParties = ProtocolInstance<int>::parties_num

Private Members

const int partyID_
const int partiesNumber_
template<typename InnerFactory>
class ProtocolFactory
#include <protocol_factory.h>

Base factory class for creating protocol instances using CRTP.

Template Parameters:

InnerFactory – The derived factory class.

Subclassed by cdough::DefaultProtocolFactory< Beaver_2PC, Share, Vector, EVector >, cdough::DefaultProtocolFactory< Fantastic_4PC, Share, Vector, EVector >, cdough::DefaultProtocolFactory< Dummy_0PC, Share, Vector, EVector >, cdough::DefaultProtocolFactory< Plaintext_1PC, Share, Vector, EVector >, cdough::DefaultProtocolFactory< Replicated_3PC, Share, Vector, EVector >, cdough::protocols::EDA_BITS_Factory< SPDZ_2k_Factory, SPDZ_2k_Factory, S, V, E >

Public Functions

virtual ~ProtocolFactory() = default
template<typename T>
inline std::unique_ptr<ProtocolBase> create(int thread_id, Communicator *_communicator, random::RandomnessManager *_randomnessManager)

Create a protocol instance for the given data type.

Template Parameters:

T – The data type for the protocol.

Parameters:
  • thread_id

  • _communicator – Pointer to the communicator.

  • _randomnessManager – Pointer to the randomness manager.

Returns:

Unique pointer to the created protocol instance.

namespace cdough
namespace protocols

Typedefs

template<template<typename> class S, template<typename> class V, template<typename> class E>
using EDA_BITS_SPDZ_Factory = EDA_BITS_Factory<SPDZ_2k_Factory, SPDZ_2k_Factory, S, V, E>

Variables

template<typename Data, template<typename> class Share, template<typename> class Vector, template<typename, int, int> class EVector, typename AProtocol, typename BProtocol>
int parties_num = 2
template<template<template<typename> class, template<typename> class, template<typename> class> class PFA, template<template<typename> class, template<typename> class, template<typename> class> class PFB, template<typename> class S, template<typename> class V, template<typename> class E>
class EDA_BITS_Factory : public cdough::ProtocolFactory<EDA_BITS_Factory<PFA, PFB, S, V, E>>
#include <eda_bits.h>

Public Types

using ProtocolFactoryA = PFA<S, V, E>
using ProtocolFactoryB = PFB<S, V, E>
template<typename T>
using ProtocolInstance = edabits_protocol<T, S, V, cdough::EVector, typename ProtocolFactoryA::template ProtocolInstance<T>, typename ProtocolFactoryB::template ProtocolInstance<T>>
template<typename T>
using AInnerContainer = typename ProtocolFactoryA::template AInnerContainer<T>

Open boolean shares to reveal plaintext. Note: functionality not supported in SPDZ-2k.

Param shares:

Input shared vector.

Return:

Opened plaintext vector.

template<typename T>
using BInnerContainer = typename ProtocolFactoryB::template BInnerContainer<T>

Public Functions

inline EDA_BITS_Factory(const int &partyID, const int &partiesNumber)

Constructor for the EDA_BITS_Factory.

Parameters:
  • partyID – The unique identifier of the party using this factory.

  • partiesNumber – The total number of parties in the protocol.

template<typename T>
inline std::unique_ptr<ProtocolBase> create(int thread_id, Communicator *communicator, random::RandomnessManager *randomnessManager)

Create an instance of the EDA_BITS protocol for a specific data type.

Parameters:
  • communicator – A pointer to the communicator.

  • randomnessManager – A pointer to the randomness manager.

Returns:

A unique pointer to the created protocol instance.

Private Members

PartyID partyID_
int partiesNumber_
ProtocolFactoryA aFactory
ProtocolFactoryB bFactory
template<typename Data, template<typename> class Share, template<typename> class Vector, template<typename, int, int> class EVector, typename AProtocol, typename BProtocol>
class edabits_protocol : public cdough::Protocol<Data, Share<AProtocol::ShareType>, Vector<Data>, AProtocol::ShareMultiVector>
#include <eda_bits.h>

Public Functions

inline edabits_protocol(const PartyID _partyID, const PartyID _numParties, Communicator *_communicator, random::RandomnessManager *_randomnessManager, std::unique_ptr<AProtocol> _protocol1, std::unique_ptr<BProtocol> _protocol2)
inline virtual void add_a(const AContainer &x, const AContainer &y, AContainer &z)

Defines vectorized arithmetic addition.

Parameters:
  • x – The first shared vector of size S.

  • y – The second shared vector of size S.

  • z – The output shared vector of size S.

inline virtual void sub_a(const AContainer &x, const AContainer &y, AContainer &z)

Defines vectorized arithmetic subtraction.

Parameters:
  • x – The first shared vector of size S.

  • y – The second shared vector of size S.

  • z – The output shared vector of size S.

inline virtual void multiply_a(const AContainer &x, const AContainer &y, AContainer &z)

Defines vectorized arithmetic multiplication.

Parameters:
  • first – The first shared vector of size S.

  • second – The second shared vector of size S.

  • result – The output shared vector of size S.

inline void neg_a(const AContainer &x, const AContainer &y, AContainer &z)
inline void dot_product_a(const AContainer &x, const AContainer &y, AContainer &z)
inline virtual void matrix_right_multiply_with_column_matrix_vectorized_a(const AContainer &x, const AContainer &y, AContainer &z, const size_t lhs_rows, const size_t lhs_cols, const size_t rhs_rows, const size_t rhs_cols)

Secure matrix right multiplication with a column matrix, vectorized implementation. Expects the left-hand side matrix to be in row-major order. Expects the right-hand side matrix to be in column-major order.

Parameters:
  • x – The left-hand side matrix as a shared vector.

  • y – The right-hand side column matrix as a shared vector.

  • z – The output shared vector.

  • lhs_rows – Number of rows in the left-hand side matrix.

  • lhs_cols – Number of columns in the left-hand side matrix.

  • rhs_rows – Number of rows in the right-hand side matrix.

  • rhs_cols – Number of columns in the right-hand side matrix.

inline virtual void conv_2d_vectorized_a(const AContainer &x, const AContainer &y, AContainer &z, const size_t instancesCount, const size_t inputHeight, const size_t inputWidth, const size_t filterHeight, const size_t filterWidth, const size_t strideHeight, const size_t strideWidth, const size_t paddingHeight, const size_t paddingWidth)

Secure 2D convolution.

Input layout: The input consists of mutiple instances concatenated after each other. Hence, the input size = instancesCount * inputHeight * inputWidth. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 input with 2 channels: [ch1(0,0), ch2(0,0), ch1(0,1), ch2(0,1), ch1(1,0), ch2(1,0), ch1(1,1), ch2(1,1)]

Filter layout: the filter is expected to have multiple channels. Hence, the filter size = channels * filterHeight * filterWidth. For example, the the physical layout for 2x2 filter with 2 channels:

[f_ch1(0,0), f_ch2(0,0), f_ch1(1,0), f_ch2(1,0), g_ch1(0,1), g_ch2(0,1), g_ch1(1,1), g_ch2(1,1)]

Output layout: (same layout as input but different height and width). The output consists of mutiple instances concatenated after each other. Hence, the output size = instancesCount * outputHeight * outputWidth * channels. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 output with 2 channels: [f(0,0), g(0,0), f(0,1), g(0,1), f(1,0), g(1,0), f(1,1), g(1,1)]

Parameters:
  • x – The input shared vector.

  • y – The filter shared vector.

  • z – The output shared vector.

  • instancesCount – Number of instances in the input.

  • inputHeight – Height of each input instance.

  • inputWidth – Width of each input instance.

  • filterHeight – Height of each filter channel.

  • filterWidth – Width of each filter channel.

  • strideHeight – Stride height.

  • strideWidth – Stride width.

  • paddingHeight – Padding height.

  • paddingWidth – Padding width.

inline virtual void sumPoolingVectorized(const AContainer &x, const AContainer &y, AContainer &z, const size_t instancesCount, const size_t channels, const size_t inputHeight, const size_t inputWidth, const size_t poolHeight, const size_t poolWidth, const size_t strideHeight, const size_t strideWidth, const size_t paddingHeight, const size_t paddingWidth)

Secure sum pooling. Aggregates values within pooling windows by summing them. Aggregation is performed over multiple instances with multiple channels. Each layer is pooled independently.

Input layout: The input consists of mutiple instances concatenated after each other. Hence, the input size = instancesCount * inputHeight * inputWidth * channels. Each instance has multiple channels interleaved per spatial location.

For example, for 2x2 input with 2 channels: [ch1(0,0), ch2(0,0), ch1(0,1), ch2(0,1), ch1(1,0), ch2(1,0), ch1(1,1), ch2(1,1)]

Output layout: same layout as input but with different height and width.

Parameters:
  • x – The input shared vector.

  • y – (unused) Placeholder for compatibility with other protocols.

  • z – The output shared vector.

  • instancesCount – Number of instances in the input.

  • channels – Number of channels in each instance.

  • inputHeight – Height of each input instance.

  • inputWidth – Width of each input instance.

  • poolHeight – Height of the pooling window.

  • poolWidth – Width of the pooling window.

  • strideHeight – Stride height.

  • strideWidth – Stride width.

  • paddingHeight – Padding height.

  • paddingWidth – Padding width.

inline virtual std::pair<AContainer, AContainer> div_const_a(const AContainer &x, const DataType &divisor)

Defines vectorized arithmetic division by constant.

Parameters:
  • input – The input shared vector.

  • c – The constant divisor.

Returns:

Pair of shared vectors representing the division result.

inline void xor_b(const BContainer &x, const BContainer &y, BContainer &z)
inline void xor_b_1(const BContainer &x, const BContainer &y, BContainer &z)
inline void and_b(const BContainer &x, const BContainer &y, BContainer &z)
inline void and_b_1(const BContainer &first, const BContainer &second, BContainer &result)
inline void not_b(const BContainer &x, BContainer &y)
inline void not_b_1(const BContainer &x, BContainer &y)
inline void or_b(const BContainer &first, const BContainer &second, BContainer &result)
inline void or_b_1(const BContainer &first, const BContainer &second, BContainer &result)
inline void inplace_invert_b(BContainer &x)
inline void pack_from(const BContainer &source, BContainer &destination, const int &pos)
inline void unpack_from(const BContainer &source, BContainer &destination, const int &pos)
inline void bit_arithmetic_right_shift(const BContainer &in, BContainer &out, const int &shift_size)
inline void bit_logical_right_shift(const BContainer &in, BContainer &out, const int &shift_size)
inline void bit_left_shift(const BContainer &in, BContainer &out, const int &shift_size)
inline void bit_xor(const BContainer &in, BContainer &out)
inline void extend_lsb(const BContainer &in, BContainer &out)
inline void mask(BContainer &in, const DataType mask_value)
inline virtual void equal_b(const BContainer &x, const BContainer &y, BContainer &result)
inline virtual void compare_b(const BContainer &first, const BContainer &second, BContainer &eq_bits, BContainer &gt_bits)
inline virtual void rca_compare_b(const BContainer &first, const BContainer &second, BContainer &gt_bits)
inline virtual void linear_compare_b(const BContainer &x, const BContainer &y, BContainer &eq_bits, BContainer &gt_bits)
inline virtual void ripple_carry_adder_b(const BContainer &x, const BContainer &y, BContainer &res, const bool carry_in)
inline virtual void ripple_carry_adder_packed_sign_b(const BContainer &x, const BContainer &y, BContainer &res, const bool carry_in)
inline virtual void parallel_prefix_adder_b(const BContainer &x, const BContainer &y, BContainer &res, const bool &carry_in)
inline virtual void parallel_prefix_adder_packed_sign_b(const BContainer &x, const BContainer &y, BContainer &res, const bool carry_in)
inline std::pair<std::vector<BContainer>, AContainer> getEdaBits(const size_t &size, const size_t &bit_length = sizeof(Data) * 8)
inline void public_rca(const std::vector<BContainer> &xBits, const ADataVector &yBits, std::optional<BContainer> res, std::optional<BContainer> signRes, const int lsb = 0, int msb = -1, const bool signExtension = true)
inline virtual void gtez_a(const AContainer &in, AContainer &out)
inline void ltz(const BContainer &in, BContainer &out)

Defines vectorized less-than-zero comparison.

Parameters:
  • in – The input shared vector of size S.

  • out – The output shared vector of size S.

inline virtual void b2a_bit(const AContainer &x, AContainer &y)

Defines vectorized boolean-to-arithmetic single bit conversion.

Parameters:
  • in – A B-shared vector of S single-bit elements.

  • out – The output A-shared vector of size S.

inline virtual void a2b_packed_sign_a_b(const AContainer &in, BContainer &out)
inline DataType reconstruct_from_a(const std::vector<Share<AShareType>> &shares)
inline ADataVector reconstruct_from_a(const std::vector<AContainer> &shares)
inline ADataVector open_shares_a(const AContainer &shares)
inline virtual ADataVector unchecked_open_a(const AContainer &shares)
inline std::vector<AContainer> get_shares_a(const ADataVector &data)
inline AContainer secret_share_a_internal(const ADataVector &data, const PartyID &data_party)
inline AContainer public_share(const ADataVector &x, const std::set<PartyID> &who_knows)
inline AContainer public_share(const ADataVector &x)
inline DataType reconstruct_from_b(const std::vector<Share<BShareType>> &shares)
inline BDataVector reconstruct_from_b(const std::vector<BContainer> &shares)
inline BDataVector open_shares_b(const BContainer &shares)
inline BDataVector unchecked_open_b(const BContainer &shares)
inline std::vector<BContainer> get_shares_b(const BDataVector &data)
inline BContainer secret_share_b_internal(const BDataVector &data, const PartyID &data_party)
inline virtual std::pair<BContainer, BContainer> redistribute_shares_b(const AContainer &x)

Defines a redistribution of arithmetic secret shares into boolean secret shares.

Parameters:

x – The input arithmetic shared vector.

Returns:

Pair of boolean shared vectors representing the redistribution.

inline virtual bool malicious_check_internal()

Internal code to check for malicious behavior. Semihonest protocols should not implement. Malicious protocols should implement their checks here.

Returns:

true no malicious behavior occurred

Returns:

false malicious behavior occurred

inline virtual void reset_malicious_state()

Reset the internal malicious-detection state.

Public Static Attributes

static int parties_num

Private Types

using DataType = Data
using UnsignedDataType = std::make_unsigned_t<DataType>
using AShareType = typename AProtocol::ShareType
using ADataVector = typename AProtocol::DataVector
using AContainer = typename AProtocol::ShareMultiVector
using BShareType = typename BProtocol::ShareType
using BDataVector = typename BProtocol::DataVector
using BContainer = typename BProtocol::ShareMultiVector

Private Members

std::unique_ptr<AProtocol> aProtocol
std::unique_ptr<BProtocol> bProtocol

Private Static Attributes

static const size_t replication_number = 2
namespace cdough
struct ArithmeticOps
#include <op_structs.h>

Operator functors for generic binary operations.

These structs define the operators used in binary operations like MULT and AND, allowing the control flow to be templated and shared between implementations.

Public Functions

template<typename T>
inline void accumulateOp(T &a, const T &b) const
template<typename T>
inline T multiplyOp(const T &a, const T &b) const
template<typename T>
inline T addOp(const T &a, const T &b) const

Public Static Attributes

static bool do_truncate = true
struct BooleanOps
#include <op_structs.h>

Public Functions

template<typename T>
inline void accumulateOp(T &a, const T &b) const
template<typename T>
inline T multiplyOp(const T &a, const T &b) const
template<typename T>
inline T addOp(const T &a, const T &b) const

Public Static Attributes

static bool do_truncate = false
struct DotProductOps
#include <op_structs.h>

Public Functions

inline DotProductOps(size_t agg = 0)
template<typename T>
inline void accumulateOp(T &a, const T &b) const
template<typename T>
inline T multiplyOp(const T &a, const T &b) const
template<typename T>
inline T addOp(const T &a, const T &b) const

Public Members

size_t agg = 0

Public Static Attributes

static bool do_truncate = true
struct MatConvOps
#include <op_structs.h>

Public Functions

MatConvOps() = default
inline MatConvOps(size_t instancesCount, size_t inputHeight, size_t inputWidth, size_t filterHeight, size_t filterWidth, size_t strideHeight, size_t strideWidth, size_t paddingHeight, size_t paddingWidth)
template<typename T>
inline void accumulateOp(T &a, const T &b) const
template<typename T>
inline T multiplyOp(const T &a, const T &b) const
template<typename T>
inline T addOp(const T &a, const T &b) const

Public Members

size_t instancesCount = 0
size_t inputHeight = 0
size_t inputWidth = 0
size_t filterHeight = 0
size_t filterWidth = 0
size_t strideHeight = 0
size_t strideWidth = 0
size_t paddingHeight = 0
size_t paddingWidth = 0

Public Static Attributes

static bool do_truncate = true
struct MatMulOps
#include <op_structs.h>

Public Functions

MatMulOps() = default
inline MatMulOps(size_t lhs_rows, size_t lhs_cols, size_t rhs_rows, size_t rhs_cols)
template<typename T>
inline void accumulateOp(T &a, const T &b) const
template<typename T>
inline T multiplyOp(const T &a, const T &b) const
template<typename T>
inline T addOp(const T &a, const T &b) const

Public Members

size_t lhs_rows = 0
size_t lhs_cols = 0
size_t rhs_rows = 0
size_t rhs_cols = 0

Public Static Attributes

static bool do_truncate = true