Welcome to MP-SPDZ’s documentation!¶
If you’re new to MP-SPDZ, consider the following:
Unlike the Readme, this documentation provides a reference for more detailed aspects of the software.
Compilation process¶
The easiest way of using MP-SPDZ is using compile.py
as
described below. If you would like to run compilation directly from
Python, see Scripts/direct_compilation_example.py
. It contains all
the necessary setup steps.
After putting your code in Program/Source/<progname>.mpc
, run the
compiler from the root directory as follows
./compile.py [options] <progname> [args]
The arguments <progname> [args]
are accessible as list under
program.args
within progname.mpc
, with <progname>
as
program.args[0]
.
The following options influence the computation domain:
- -F <integer length>¶
- --field=<integer length>¶
Compile for computation modulo a prime and the default integer length. This means that secret integers are assumed to have at most said length unless explicitly told otherwise. The compiled output will communicate the minimum length of the prime number to the virtual machine, which will fail if this is not met. This is the default with an integer length set to 64. When not specifying the prime, the minimum prime length will be around 40 bits longer than the integer length. Furthermore, the computation will be optimistic in the sense that overflows in the secrets might have security implications.
- -P <prime>¶
- --prime=<prime>¶
Specify a concrete prime modulus for computation. This can be used together with
-F
, in which case integer length has to be at most the prime length minus two. The security implications of overflows in the secrets do not go beyond incorrect results.
- -R <ring size>¶
- --ring=<ring size>¶
Compile for computation modulo 2^(ring size). This will set the assumed length of secret integers to one less because many operations require this. The exact ring size will be communicated to the virtual machine, which will use it automatically if supported.
- -B <integer length>¶
- --binary=<integer length>¶
Compile for binary computation using integer length as default.
For arithmetic computation (-F
, -P
, and
-R
) you can set the bit
length during execution using program.set_bit_length(length)
. For
binary computation you can do so with sint =
sbitint.get_type(length)
.
Use sfix.set_precision()
to change the range for fixed-point
numbers.
The following options switch from a single computation domain to mixed computation when using in conjunction with arithmetic computation:
The implementation of both daBits and edaBits are explained in this paper.
- -Z <number of parties>¶
- --split=<number of parties>¶
Enables mixed computation using local conversion. This has been used by Mohassel and Rindal and Araki et al. It only works with additive secret sharing modulo a power of two.
The following options change less fundamental aspects of the computation:
- -D¶
- --dead-code-elimination¶
Eliminates unused code. This currently means computation that isn’t used for input or output or written to the so-called memory (e.g.,
Array
; seetypes
).
- -b <budget>¶
- --budget=<budget>¶
Set the budget for loop unrolling with
for_range_opt()
and similar. This means that loops are unrolled up to budget instructions. Default is 100,000 instructions.
- -C¶
- --CISC¶
Speed up the compilation of repetitive code at the expense of a potentially higher number of communication rounds. For example, the compiler by default will try to compute a division and a logarithm in parallel if possible. Using this option complex operations such as these will be separated and only multiple divisions or logarithms will be computed in parallel. This speeds up the compilation because of reduced complexity.
- -l¶
- --flow-optimization¶
Optimize simple loops (
for <iterator> in range(<n>)
) by usingfor_range_opt()
and defer if statements to the run time.
Compilation vs run time¶
The most important thing to keep in mind is that the Python code is
executed at compile-time. This means that Python data structures such
as list
and dict
only exist at compile-time
and that all Python loops are unrolled. For run-time loops and lists,
you can use for_range()
(or the more
optimizing for_range_opt()
) and
Array
. For convenient multithreading you
can use for_range_opt_multithread()
, which
automatically distributes the computation on the requested number of
threads.
This reference uses the term ‘compile-time’ to indicate Python types
(which are inherently known when compiling). If the term ‘public’ is
used, this means both compile-time values as well as public run-time
types such as regint
.
Reference¶
High-Level Interface¶
Compiler.types module¶
This module defines all types available in high-level programs. These include basic types such as secret integers or floating-point numbers and container types. A single instance of the former uses one or more so-called registers in the virtual machine while the latter use the so-called memory. For every register type, there is a corresponding dedicated memory.
Registers are used for computation, allocated on an ongoing basis,
and thread-specific. The memory is allocated statically and shared
between threads. This means that memory-based types such as
Array
can be used to transfer information between threads.
Note that creating memory-based types outside the main thread is not
supported.
If viewing this documentation in processed form, many function signatures appear generic because of the use of decorators. See the source code for the correct signature.
Basic types¶
All basic can be used as vectors, that is one instance representing several values, with all operations being executed element-wise. For example, the following computes ten multiplications of integers input by party 0 and 1:
sint.get_input_from(0, size=10) * sint.get_input_from(1, size=10)
Secret integer in the protocol-specific domain. |
|
Clear integer in same domain as secure computation (depends on protocol). |
|
Clear 64-bit integer. |
|
Secret fixed-point number represented as secret integer, by multiplying with |
|
Clear fixed-point number represented as clear integer. |
|
Secret floating-point number. |
|
Secret \(\mathrm{GF}(2^n)\) value. |
|
Clear \(\mathrm{GF}(2^n)\) value. |
Container types¶
Single value in memory. |
|
Array accessible by public index. |
|
Matrix. |
|
Multidimensional array. |
- class Compiler.types.Array(length, value_type, address=None, debug=None, alloc=True)[source]¶
Array accessible by public index. That is,
a[i]
works for an arraya
andi
being aregint
,cint
, or a Python integer.- Parameters
length – compile-time integer (int) or
None
for unknown lengthvalue_type – basic type
address – if given (regint/int), the array will not be allocated
You can convert between arrays and register vectors by using slice indexing. This allows for element-wise operations as long as supported by the basic type. The following adds 10 secret integers from the first two parties:
a = sint.Array(10) a.input_from(0) b = sint.Array(10) b.input_from(1) a[:] += b[:]
- assign(other, base=0)[source]¶
Assignment.
- Parameters
other – vector/Array/Matrix/MultiArray/iterable of compatible type and smaller size
base – index to start assignment at
- assign_all(value, use_threads=True, conv=True)[source]¶
Assign the same value to all entries.
- Parameters
value – convertible to basic type
- assign_part_vector(other, base=0)¶
Assignment.
- Parameters
other – vector/Array/Matrix/MultiArray/iterable of compatible type and smaller size
base – index to start assignment at
- assign_vector(other, base=0)¶
Assignment.
- Parameters
other – vector/Array/Matrix/MultiArray/iterable of compatible type and smaller size
base – index to start assignment at
- classmethod create_from(l)[source]¶
Convert Python iterator or vector to array. Basic type will be taken from first element, further elements must to be convertible to that.
- expand_to_vector(index, size)[source]¶
Create vector from single entry.
- Parameters
index – regint/cint/int
size – int
- get_part(base, size)[source]¶
Part array.
- Parameters
base – start index (regint/cint/int)
size – integer
- Returns
Array of same type
- get_part_vector(base=0, size=None)¶
Return vector with content.
- Parameters
base – starting point (regint/cint/int)
size – length (compile-time int)
- get_vector(base=0, size=None)[source]¶
Return vector with content.
- Parameters
base – starting point (regint/cint/int)
size – length (compile-time int)
- input_from(player, budget=None, raw=False)[source]¶
Fill with inputs from player if supported by type.
- Parameters
player – public (regint/cint/int)
- maybe_get(condition, index)[source]¶
Return entry if condition is true.
- Parameters
condition – 0/1 (regint/cint/int)
index – regint/cint/int
- maybe_set(condition, index, value)[source]¶
Change entry if condition is true.
- Parameters
condition – 0/1 (regint/cint/int)
index – regint/cint/int
value – updated value
- print_reveal_nested(end='\n')[source]¶
Reveal and print as list.
- Parameters
end – string to print after (default: line break)
- read_from_file(start)[source]¶
Read content from
Persistence/Transactions-P<playerno>.data
. Precision must be the same as when storing if applicable.- Parameters
start – starting position in number of shares from beginning (int/regint/cint)
- Returns
destination for final position, -1 for eof reached, or -2 for file not found (regint)
- reveal_nested()¶
Reveal as list.
- reveal_to(player)[source]¶
Reveal secret array to
player
.- Parameters
player – public integer (int/regint/cint)
- Returns
personal
containing an array
- reveal_to_binary_output(player=None)[source]¶
Reveal to binary output if supported by type.
- Param
player to reveal to (default all)
- reveal_to_clients(clients)¶
Reveal contents to list of clients.
- Parameters
clients – list or array of client identifiers
- class Compiler.types.Matrix(rows, columns, value_type, debug=None, address=None)[source]¶
Matrix.
- Parameters
rows – compile-time (int)
columns – compile-time (int)
value_type – basic type of entries
- assign(other)¶
Assign container to content. Not implemented for floating-point.
- Parameters
other – container of matching size and type
- assign_all(value)¶
Assign the same value to all entries.
- Parameters
value – convertible to relevant basic type
- assign_part_vector(vector, base=0)¶
Assign vector from range of the first dimension, including all entries in further dimensions.
- Parameters
vector – updated entries
base – index in first dimension (regint/cint/int)
- assign_vector(vector, base=0)¶
Assign vector to content. Not implemented for floating-point.
- Parameters
vector – vector of matching size convertible to relevant basic type
base – compile-time (int)
- assign_vector_by_indices(vector, *indices)¶
Assign vector to entries with potential asterisks. See
get_vector_by_indices()
for an example.
- diag()¶
Matrix diagonal.
- direct_mul(other, reduce=True, indices=None)¶
Matrix multiplication in the virtual machine.
- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
indices – 4-tuple of
regint
vectors for index selection (default is complete multiplication)
- Returns
Matrix as vector of relevant type (row-major)
The following executes a matrix multiplication selecting every third row of
A
:A = sfix.Matrix(7, 4) B = sfix.Matrix(4, 5) C = sfix.Matrix(3, 5) C.assign_vector(A.direct_mul(B, indices=(regint.inc(3, 0, 3), regint.inc(4), regint.inc(4), regint.inc(5)))
- direct_mul_to_matrix(other)¶
Matrix multiplication in the virtual machine.
- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
- Returns
- direct_mul_trans(other, reduce=True, indices=None)¶
Matrix multiplication with the transpose of
other
in the virtual machine.- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
indices – 4-tuple of
regint
vectors for index selection (default is complete multiplication)
- Returns
Matrix as vector of relevant type (row-major)
- direct_trans_mul(other, reduce=True, indices=None)¶
Matrix multiplication with the transpose of
self
in the virtual machine.- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
indices – 4-tuple of
regint
vectors for index selection (default is complete multiplication)
- Returns
Matrix as vector of relevant type (row-major)
- dot(other, res_params=None)¶
Matrix-matrix and matrix-vector multiplication.
- Parameters
self – two-dimensional
other – Matrix or Array of matching size and type
- get_part(start, size)¶
Part multi-array.
- Parameters
start – first-dimension index (regint/cint/int)
size – int
- get_part_vector(base=0, size=None)¶
Vector from range of the first dimension, including all entries in further dimensions.
- Parameters
base – index in first dimension (regint/cint/int)
size – size in first dimension (int)
- get_slice_vector(slice)¶
Vector from range of indicies of the first dimension, including all entries in further dimensions.
- Parameters
slice – regint array
- get_vector(base=0, size=None)¶
Return vector with content. Not implemented for floating-point.
- Parameters
base – public (regint/cint/int)
size – compile-time (int)
- get_vector_by_indices(*indices)¶
Vector with potential asterisks. The potential retrieves all entry where the first dimension index is 0, and the third dimension index is 1:
a.get_vector_by_indices(0, None, 1)
- iadd(other)¶
Element-wise addition in place.
- Parameters
other – container of matching size and type
- input_from(player, budget=None, raw=False)¶
Fill with inputs from player if supported by type.
- Parameters
player – public (regint/cint/int)
- mul_trans(other)¶
Matrix multiplication with transpose of
other
.- Parameters
self – two-dimensional
other – two-dimensional container of matching type and size
- mul_trans_to(other, res, n_threads=None)¶
Matrix multiplication with the transpose of
other
in the virtual machine.- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
res – matrix of matching dimension to store result
n_threads – number of threads (default: single thread)
- plain_mul(other, res=None)¶
Alternative matrix multiplication.
- Parameters
self – two-dimensional
other – two-dimensional container of matching type and size
- print_reveal_nested(end='\n')¶
Reveal and print as nested list.
- Parameters
end – string to print after (default: line break)
- randomize(*args)¶
Randomize according to data type.
- read_from_file(start)¶
Read content from
Persistence/Transactions-P<playerno>.data
. Precision must be the same as when storing if applicable.- Parameters
start – starting position in number of shares from beginning (int/regint/cint)
- Returns
destination for final position, -1 for eof reached, or -2 for file not found (regint)
- reveal_list()¶
Reveal as list.
- reveal_nested()¶
Reveal as nested list.
- reveal_to_binary_output(player=None)¶
Reveal to binary output if supported by type.
- Param
player to reveal to (default all)
- reveal_to_clients(clients)¶
Reveal contents to list of clients.
- Parameters
clients – list or array of client identifiers
- same_shape()¶
- Returns
new multidimensional array with same shape and basic type
- schur(other)¶
Element-wise product.
- Parameters
other – container of matching size and type
- Returns
container of same shape and type as
self
- set_column(index, vector)[source]¶
Change column.
- Parameters
index – regint/cint/int
vector – short enought vector of compatible type
- trace()¶
Matrix trace.
- trans_mul(other, reduce=True, res=None)¶
Matrix multiplication with transpose of
self
- Parameters
self – two-dimensional
other – two-dimensional container of matching type and size
- trans_mul_to(other, res, n_threads=None)¶
Matrix multiplication with the transpose of
self
in the virtual machine.- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
res – matrix of matching dimension to store result
n_threads – number of threads (default: single thread)
- transpose()¶
Matrix transpose.
- Parameters
self – two-dimensional
- write_to_file(position=None)¶
Write shares of integer representation to
Persistence/Transactions-P<playerno>.data
.- Parameters
position – start position (int/regint/cint), defaults to end of file
- class Compiler.types.MemValue(value, address=None)[source]¶
Single value in memory. This is useful to transfer information between threads. Operations are automatically read from memory if required, this means you can use any operation with
MemValue
objects as if they were a basic type.- Parameters
value – basic type or int (will be converted to regint)
- max(other)¶
Maximum.
- Parameters
other – any compatible type
- min(other)¶
Minimum.
- Parameters
other – any compatible type
- square()¶
Square.
- class Compiler.types.MultiArray(sizes, value_type, debug=None, address=None, alloc=True)[source]¶
Multidimensional array. The access operator (
a[i]
) allows to a multi-dimensional array of dimension one less or a simple array for a two-dimensional array.- Parameters
sizes – shape (compile-time list of integers)
value_type – basic type of entries
You can convert between arrays and register vectors by using slice indexing. This allows for element-wise operations as long as supported by the basic type. The following has the first two parties input a 10x10 secret integer matrix followed by storing the element-wise multiplications in the same data structure:
a = sint.Tensor([3, 10, 10]) a[0].input_from(0) a[1].input_from(1) a[2][:] = a[0][:] * a[1][:]
- assign(other)¶
Assign container to content. Not implemented for floating-point.
- Parameters
other – container of matching size and type
- assign_all(value)¶
Assign the same value to all entries.
- Parameters
value – convertible to relevant basic type
- assign_part_vector(vector, base=0)¶
Assign vector from range of the first dimension, including all entries in further dimensions.
- Parameters
vector – updated entries
base – index in first dimension (regint/cint/int)
- assign_vector(vector, base=0)¶
Assign vector to content. Not implemented for floating-point.
- Parameters
vector – vector of matching size convertible to relevant basic type
base – compile-time (int)
- assign_vector_by_indices(vector, *indices)¶
Assign vector to entries with potential asterisks. See
get_vector_by_indices()
for an example.
- diag()¶
Matrix diagonal.
- direct_mul(other, reduce=True, indices=None)¶
Matrix multiplication in the virtual machine.
- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
indices – 4-tuple of
regint
vectors for index selection (default is complete multiplication)
- Returns
Matrix as vector of relevant type (row-major)
The following executes a matrix multiplication selecting every third row of
A
:A = sfix.Matrix(7, 4) B = sfix.Matrix(4, 5) C = sfix.Matrix(3, 5) C.assign_vector(A.direct_mul(B, indices=(regint.inc(3, 0, 3), regint.inc(4), regint.inc(4), regint.inc(5)))
- direct_mul_to_matrix(other)¶
Matrix multiplication in the virtual machine.
- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
- Returns
- direct_mul_trans(other, reduce=True, indices=None)¶
Matrix multiplication with the transpose of
other
in the virtual machine.- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
indices – 4-tuple of
regint
vectors for index selection (default is complete multiplication)
- Returns
Matrix as vector of relevant type (row-major)
- direct_trans_mul(other, reduce=True, indices=None)¶
Matrix multiplication with the transpose of
self
in the virtual machine.- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
indices – 4-tuple of
regint
vectors for index selection (default is complete multiplication)
- Returns
Matrix as vector of relevant type (row-major)
- dot(other, res_params=None)¶
Matrix-matrix and matrix-vector multiplication.
- Parameters
self – two-dimensional
other – Matrix or Array of matching size and type
- get_part(start, size)¶
Part multi-array.
- Parameters
start – first-dimension index (regint/cint/int)
size – int
- get_part_vector(base=0, size=None)¶
Vector from range of the first dimension, including all entries in further dimensions.
- Parameters
base – index in first dimension (regint/cint/int)
size – size in first dimension (int)
- get_slice_vector(slice)¶
Vector from range of indicies of the first dimension, including all entries in further dimensions.
- Parameters
slice – regint array
- get_vector(base=0, size=None)¶
Return vector with content. Not implemented for floating-point.
- Parameters
base – public (regint/cint/int)
size – compile-time (int)
- get_vector_by_indices(*indices)¶
Vector with potential asterisks. The potential retrieves all entry where the first dimension index is 0, and the third dimension index is 1:
a.get_vector_by_indices(0, None, 1)
- iadd(other)¶
Element-wise addition in place.
- Parameters
other – container of matching size and type
- input_from(player, budget=None, raw=False)¶
Fill with inputs from player if supported by type.
- Parameters
player – public (regint/cint/int)
- mul_trans(other)¶
Matrix multiplication with transpose of
other
.- Parameters
self – two-dimensional
other – two-dimensional container of matching type and size
- mul_trans_to(other, res, n_threads=None)¶
Matrix multiplication with the transpose of
other
in the virtual machine.- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
res – matrix of matching dimension to store result
n_threads – number of threads (default: single thread)
- plain_mul(other, res=None)¶
Alternative matrix multiplication.
- Parameters
self – two-dimensional
other – two-dimensional container of matching type and size
- print_reveal_nested(end='\n')¶
Reveal and print as nested list.
- Parameters
end – string to print after (default: line break)
- randomize(*args)¶
Randomize according to data type.
- read_from_file(start)¶
Read content from
Persistence/Transactions-P<playerno>.data
. Precision must be the same as when storing if applicable.- Parameters
start – starting position in number of shares from beginning (int/regint/cint)
- Returns
destination for final position, -1 for eof reached, or -2 for file not found (regint)
- reveal_list()¶
Reveal as list.
- reveal_nested()¶
Reveal as nested list.
- reveal_to_binary_output(player=None)¶
Reveal to binary output if supported by type.
- Param
player to reveal to (default all)
- reveal_to_clients(clients)¶
Reveal contents to list of clients.
- Parameters
clients – list or array of client identifiers
- same_shape()¶
- Returns
new multidimensional array with same shape and basic type
- schur(other)¶
Element-wise product.
- Parameters
other – container of matching size and type
- Returns
container of same shape and type as
self
- trace()¶
Matrix trace.
- trans_mul(other, reduce=True, res=None)¶
Matrix multiplication with transpose of
self
- Parameters
self – two-dimensional
other – two-dimensional container of matching type and size
- trans_mul_to(other, res, n_threads=None)¶
Matrix multiplication with the transpose of
self
in the virtual machine.- Parameters
self –
Matrix
/ 2-dimensionalMultiArray
other –
Matrix
/ 2-dimensionalMultiArray
res – matrix of matching dimension to store result
n_threads – number of threads (default: single thread)
- transpose()¶
Matrix transpose.
- Parameters
self – two-dimensional
- write_to_file(position=None)¶
Write shares of integer representation to
Persistence/Transactions-P<playerno>.data
.- Parameters
position – start position (int/regint/cint), defaults to end of file
- class Compiler.types.cfix(**kwargs)[source]¶
Clear fixed-point number represented as clear integer. It supports basic arithmetic (
+, -, *, /
), returning eithercfix
if the other operand is public (cfix/regint/cint/int) orsfix
if the other operand is an sfix. It also support comparisons (==, !=, <, <=, >, >=
), returning eitherregint
orsbitint
.- Parameters
v – cfix/float/int
- classmethod Array(size, *args, **kwargs)¶
Type-dependent array. Example:
a = sint.Array(10)
- classmethod Matrix(rows, columns, *args, **kwargs)¶
Type-dependent matrix. Example:
a = sint.Matrix(10, 10)
- classmethod MemValue(value)¶
- classmethod Tensor(shape)¶
Type-dependent tensor of any dimension:
a = sfix.Tensor([10, 10])
- binary_output(*args, **kwargs)[source]¶
Write double-precision floating-point number to
Player-Data/Binary-Output-P<playerno>-<threadno>
.- Parameters
player – only output on given player (default all)
- max(other)¶
Maximum.
- Parameters
other – any compatible type
- min(other)¶
Minimum.
- Parameters
other – any compatible type
- classmethod read_from_socket(*args, **kwargs)[source]¶
Receive clear fixed-point value(s) from client. The client needs to convert the values to the right integer representation.
- Parameters
client_id – Client id (regint)
n – number of values (default 1)
- Param
vector size (int)
- Returns
cfix (if n=1) or list of cfix
- classmethod set_precision(f, k=None)[source]¶
Set the precision of the integer representation. Note that some operations are undefined when the precision of
sfix
andcfix
differs. The initial defaults are chosen to allow the best optimization of probabilistic truncation in computation modulo 2^64 (2*k < 64). Generally, 2*k must be at most the integer length for rings and at most m-s-1 for computation modulo an m-bit prime and statistical security s (default 40).- Parameters
f – bit length of decimal part (initial default 16)
k – whole bit length of fixed point, defaults to twice
f
if not given (initial default 31)
- square()¶
Square.
- class Compiler.types.cfloat(**kwargs)[source]¶
Helper class for printing revealed sfloats.
- class Compiler.types.cgf2n(val=None, size=None)[source]¶
Clear \(\mathrm{GF}(2^n)\) value. n is chosen at runtime. A number operators are supported (
+, -, *, /, **, ^, &, |, ~, ==, !=, <<, >>
), returning eithercgf2n
if the other operand is public (cgf2n/regint/int) orsgf2n
if the other operand is secret. The following operators require the other operand to be a compile-time integer:**, <<, >>
.*, /, **
refer to field multiplication and division.- Parameters
val – initialization (cgf2n/cint/regint/int or list thereof)
size – vector size (int), defaults to 1 or size of list
- classmethod Array(size, *args, **kwargs)¶
Type-dependent array. Example:
a = sint.Array(10)
- classmethod Matrix(rows, columns, *args, **kwargs)¶
Type-dependent matrix. Example:
a = sint.Matrix(10, 10)
- classmethod MemValue(value)¶
- classmethod Tensor(shape)¶
Type-dependent tensor of any dimension:
a = sfix.Tensor([10, 10])
- binary_output(*args, **kwargs)¶
Write 64-bit signed integer to
Player-Data/Binary-Output-P<playerno>-<threadno>
.- Parameters
player – only output on given player (default all)
- bit_and(other)¶
AND in binary circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Return type
depending on inputs (secret if any of them is)
- classmethod bit_compose(bits, step=None)[source]¶
Clear \(\mathrm{GF}(2^n)\) bit composition.
- Parameters
bits – list of cgf2n
step – set every
step
-th bit in output (defaults to 1)
- bit_decompose(*args, **kwargs)[source]¶
Clear bit decomposition.
- Parameters
bit_length – number of bits (defaults to global \(\mathrm{GF}(2^n)\) bit length)
step – extract every
step
-th bit (defaults to 1)
- bit_not()¶
NOT in binary circuits.
- bit_or(other)¶
OR in binary circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
type depends on inputs (secret if any of them is)
- bit_xor(other)¶
XOR in \(\mathrm{GF}(2^n)\) circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Return type
depending on inputs (secret if any of them is)
- cond_swap(a, b, t=None)¶
Swapping in \(\mathrm{GF}(2^n)\). Similar to
_int.if_else()
.
- half_adder(other)¶
Half adder in binary circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
binary sum, carry
- Return type
depending on inputs (secret if any of them is)
- if_else(a, b)¶
MUX in \(\mathrm{GF}(2^n)\) circuits. Similar to
_int.if_else()
.
- classmethod malloc(size, creator_tape=None)¶
Allocate memory (statically).
- Parameters
size – compile-time (int)
- max(other)¶
Maximum.
- Parameters
other – any compatible type
- min(other)¶
Minimum.
- Parameters
other – any compatible type
- print_reg_plain(*args, **kwargs)¶
Output.
- reveal()¶
Identity.
- square()¶
Square.
- class Compiler.types.cint(**kwargs)[source]¶
Clear integer in same domain as secure computation (depends on protocol). A number operators are supported (
+, -, *, /, //, **, %, ^, &, |, ~, ==, !=, <<, >>
), returning eithercint
if the other operand is public (cint/regint/int) orsint
if the other operand issint
. Comparison operators (==, !=, <, <=, >, >=
) are also supported, returningregint()
. Comparisons and~
require that the value is within the global bit length. The same holds forabs()
./
runs field division if the modulus is a prime while//
runs integer floor division.**
requires the exponent to be compile-time integer or the base to be two.- Parameters
val – initialization (cint/regint/int/cgf2n or list thereof)
size – vector size (int), defaults to 1 or size of list
- classmethod Array(size, *args, **kwargs)¶
Type-dependent array. Example:
a = sint.Array(10)
- classmethod Matrix(rows, columns, *args, **kwargs)¶
Type-dependent matrix. Example:
a = sint.Matrix(10, 10)
- classmethod MemValue(value)¶
- classmethod Tensor(shape)¶
Type-dependent tensor of any dimension:
a = sfix.Tensor([10, 10])
- binary_output(*args, **kwargs)¶
Write 64-bit signed integer to
Player-Data/Binary-Output-P<playerno>-<threadno>
.- Parameters
player – only output on given player (default all)
- static bit_adder(*args, **kwargs)¶
Binary adder in arithmetic circuits.
- Parameters
a – summand (list of 0/1 in compatible type)
b – summand (list of 0/1 in compatible type)
carry_in – input carry (default 0)
get_carry – add final carry to output
- Returns
list of 0/1 in relevant type
- bit_and(other)¶
AND in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Return type
depending on inputs (secret if any of them is)
- classmethod bit_compose(bits)¶
Compose value from bits.
- Parameters
bits – iterable of any type implementing left shift
- bit_decompose(*args, **kwargs)[source]¶
Clear bit decomposition.
- Parameters
bit_length – number of bits (default is global bit length)
- Returns
list of cint
- bit_not()¶
NOT in arithmetic circuits.
- bit_or(other)¶
OR in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
type depends on inputs (secret if any of them is)
- bit_xor(other)¶
XOR in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
type depends on inputs (secret if any of them is)
- cond_swap(a, b)¶
Swapping in arithmetic circuits.
- Parameters
a/b – any type supporting the necessary operations
- Returns
(a, b)
ifself
is 0,(b, a)
ifself
is 1, and undefined otherwise- Return type
depending on operands, secret if any of them is
- half_adder(other)¶
Half adder in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
binary sum, carry
- Return type
depending on inputs, secret if any is
- if_else(a, b)¶
MUX on bit in arithmetic circuits.
- Parameters
a/b – any type supporting the necessary operations
- Returns
a if
self
is 1, b ifself
is 0, undefined otherwise- Return type
depending on operands, secret if any of them is
- less_than(*args, **kwargs)[source]¶
Clear comparison for particular bit length.
- Parameters
other – cint/regint/int
bit_length – signed bit length of inputs
- Returns
0/1 (regint), undefined if inputs outside range
- classmethod malloc(size, creator_tape=None)¶
Allocate memory (statically).
- Parameters
size – compile-time (int)
- max(other)¶
Maximum.
- Parameters
other – any compatible type
- min(other)¶
Minimum.
- Parameters
other – any compatible type
- print_reg_plain(*args, **kwargs)¶
Output.
- classmethod read_from_socket(*args, **kwargs)[source]¶
Receive clear value(s) from client.
- Parameters
client_id – Client id (regint)
n – number of values (default 1)
size – vector size (default 1)
- Returns
cint (if n=1) or list of cint
- reveal()¶
Identity.
- square()¶
Square.
- class Compiler.types.localint(value=None)[source]¶
Local integer that must prevented from leaking into the secure computation. Uses regint internally.
- Parameters
value – initialization, convertible to regint
- class Compiler.types.personal(player, value)[source]¶
Value known to one player. Supports operations with public values and personal values known to the same player. Can be used with
print_ln_to()
.- Parameters
player – player (int)
value – cleartext value (cint, cfix, cfloat) or array thereof
- class Compiler.types.regint(**kwargs)[source]¶
Clear 64-bit integer. Unlike
cint
this is always a 64-bit integer. The type supports the following operations withregint
or Python integers, always returningregint
:+, -, *, %, /, //, **, ^, &, |, <<, >>, ==, !=, <, <=, >, >=
. For operations with other types, see the respective descriptions. Both/
and//
stand for floor division.- Parameters
val – initialization (cint/cgf2n/regint/int or list thereof)
size – vector size (int), defaults to 1 or size of list
- classmethod Array(size, *args, **kwargs)¶
Type-dependent array. Example:
a = sint.Array(10)
- classmethod Matrix(rows, columns, *args, **kwargs)¶
Type-dependent matrix. Example:
a = sint.Matrix(10, 10)
- classmethod MemValue(value)¶
- classmethod Tensor(shape)¶
Type-dependent tensor of any dimension:
a = sfix.Tensor([10, 10])
- binary_output(player=None)[source]¶
Write 64-bit signed integer to
Player-Data/Binary-Output-P<playerno>-<threadno>
.- Parameters
player – only output on given player (default all)
- static bit_adder(*args, **kwargs)¶
Binary adder in arithmetic circuits.
- Parameters
a – summand (list of 0/1 in compatible type)
b – summand (list of 0/1 in compatible type)
carry_in – input carry (default 0)
get_carry – add final carry to output
- Returns
list of 0/1 in relevant type
- bit_and(other)¶
AND in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Return type
depending on inputs (secret if any of them is)
- bit_decompose(*args, **kwargs)[source]¶
Clear bit decomposition.
- Parameters
bit_length – number of bits (defaults to global bit length)
- Returns
list of regint
- bit_not()¶
NOT in arithmetic circuits.
- bit_or(other)¶
OR in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
type depends on inputs (secret if any of them is)
- bit_xor(other)¶
XOR in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
type depends on inputs (secret if any of them is)
- cond_swap(a, b)¶
Swapping in arithmetic circuits.
- Parameters
a/b – any type supporting the necessary operations
- Returns
(a, b)
ifself
is 0,(b, a)
ifself
is 1, and undefined otherwise- Return type
depending on operands, secret if any of them is
- classmethod get_random(*args, **kwargs)[source]¶
Public insecure randomness.
- Parameters
bit_length – number of bits (int)
size – vector size (int, default 1)
- half_adder(other)¶
Half adder in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
binary sum, carry
- Return type
depending on inputs, secret if any is
- if_else(a, b)¶
MUX on bit in arithmetic circuits.
- Parameters
a/b – any type supporting the necessary operations
- Returns
a if
self
is 1, b ifself
is 0, undefined otherwise- Return type
depending on operands, secret if any of them is
- classmethod inc(size, base=0, step=1, repeat=1, wrap=None)[source]¶
Produce
regint
vector with certain patterns. This is particularly useful forSubMultiArray.direct_mul()
.- Parameters
size – Result size
base – First value
step – Increase step
repeat – Repeate this many times
wrap – Start over after this many increases
The following produces (1, 1, 1, 3, 3, 3, 5, 5, 5, 7):
regint.inc(10, 1, 2, 3)
- classmethod malloc(size, creator_tape=None)¶
Allocate memory (statically).
- Parameters
size – compile-time (int)
- max(other)¶
Maximum.
- Parameters
other – any compatible type
- min(other)¶
Minimum.
- Parameters
other – any compatible type
- classmethod read_from_socket(*args, **kwargs)[source]¶
Receive clear integer value(s) from client.
- Parameters
client_id – Client id (regint)
n – number of values (default 1)
size – vector size (default 1)
- Returns
regint (if n=1) or list of regint
- square()¶
Square.
- class Compiler.types.sfix(**kwargs)[source]¶
Secret fixed-point number represented as secret integer, by multiplying with
2^f
and then rounding. Seesint
for security considerations of the underlying integer operations.It supports basic arithmetic (
+, -, *, /
), returningsfix
, and comparisons (==, !=, <, <=, >, >=
), returningsbitint
. The other operand can be any of sfix/sint/cfix/regint/cint/int/float. It also supportsabs()
and**
, the latter for integer exponents.Note that the default precision (16 bits after the dot, 31 bits in total) only allows numbers up to \(2^{31-16-1} \approx 16000\). You can increase this using
set_precision()
.- Params _v
int/float/regint/cint/sint/sfloat
- classmethod Array(size, *args, **kwargs)¶
Type-dependent array. Example:
a = sint.Array(10)
- classmethod Matrix(rows, columns, *args, **kwargs)¶
Type-dependent matrix. Example:
a = sint.Matrix(10, 10)
- classmethod MemValue(value)¶
- classmethod Tensor(shape)¶
Type-dependent tensor of any dimension:
a = sfix.Tensor([10, 10])
- compute_reciprocal(*args, **kwargs)¶
Secret fixed-point reciprocal.
- classmethod dot_product(x, y, res_params=None)[source]¶
Secret dot product.
- Parameters
x – iterable of appropriate secret type
y – iterable of appropriate secret type and same length
- classmethod get_input_from(*args, **kwargs)[source]¶
Secret fixed-point input.
- Parameters
player – public (regint/cint/int)
size – vector size (int, default 1)
- classmethod get_random(*args, **kwargs)[source]¶
Uniform secret random number around centre of bounds. Actual range can be smaller but never larger.
- Parameters
lower – float
upper – float
size – vector size (int, default 1)
- classmethod input_tensor_from(player, shape)¶
Input tensor secretly from player.
- Parameters
player – int/regint/cint
shape – tensor shape
- classmethod input_tensor_from_client(client_id, shape)¶
Input tensor secretly from client.
- Parameters
client_id – client identifier (public)
shape – tensor shape
- classmethod input_tensor_via(player, content)¶
Input tensor-like data via a player. This overwrites the input file for the relevant player. The following returns an
sint
matrix of dimension 2 by 2:M = [[1, 2], [3, 4]] sint.input_tensor_via(0, M)
Make sure to copy
Player-Data/Input-P<player>-0
if running on another host.
- classmethod load_mem(*args, **kwargs)¶
Load from memory by public address.
- max(other)¶
Maximum.
- Parameters
other – any compatible type
- min(other)¶
Minimum.
- Parameters
other – any compatible type
- classmethod read_from_file(*args, **kwargs)¶
Read shares from
Persistence/Transactions-P<playerno>.data
. Precision must be the same as when storing.- Parameters
start – starting position in number of shares from beginning (int/regint/cint)
n_items – number of items (int)
- Returns
destination for final position, -1 for eof reached, or -2 for file not found (regint)
- Returns
list of shares
- classmethod receive_from_client(*args, **kwargs)¶
Securely obtain shares of values input by a client. Assumes client has already converted values to integer representation.
- Parameters
n – number of inputs (int)
client_id – regint
size – vector size (default 1)
- reveal()¶
Reveal secret fixed-point number.
- Returns
relevant clear type
- reveal_to(player)[source]¶
Reveal secret value to
player
.- Parameters
player – public integer (int/regint/cint)
- Returns
- classmethod reveal_to_clients(clients, values)¶
Reveal securely to clients.
- Parameters
clients – client ids (list or array)
values – list of values of this class
- round_nearest = False¶
Whether to round deterministically to nearest instead of probabilistically, e.g. after fixed-point multiplication.
- classmethod set_precision(f, k=None)¶
Set the precision of the integer representation. Note that some operations are undefined when the precision of
sfix
andcfix
differs. The initial defaults are chosen to allow the best optimization of probabilistic truncation in computation modulo 2^64 (2*k < 64). Generally, 2*k must be at most the integer length for rings and at most m-s-1 for computation modulo an m-bit prime and statistical security s (default 40).- Parameters
f – bit length of decimal part (initial default 16)
k – whole bit length of fixed point, defaults to twice
f
if not given (initial default 31)
- square()¶
Square.
- store_in_mem(address)¶
Store in memory by public address.
Send shares of integer representations of a list of values to a specified client socket.
- Parameters
client_id – regint
values – list of values of this type
- classmethod write_to_file(shares, position=None)¶
Write shares of integer representation to
Persistence/Transactions-P<playerno>.data
.- Parameters
shares – (list or iterable of sfix)
position – start position (int/regint/cint), defaults to end of file
- class Compiler.types.sfloat(**kwargs)[source]¶
Secret floating-point number. Represents \((1 - 2s) \cdot (1 - z)\cdot v \cdot 2^p\).
v: significand
p: exponent
z: zero flag
s: sign bit
This uses integer operations internally, see
sint
for security considerations.The type supports basic arithmetic (
+, -, *, /
), returningsfloat
, and comparisons (==, !=, <, <=, >, >=
), returningsint
. The other operand can be any of sint/cfix/regint/cint/int/float.- Parameters
v – initialization (sfloat/sfix/float/int/sint/cint/regint)
- classmethod Array(size, *args, **kwargs)¶
Type-dependent array. Example:
a = sint.Array(10)
- classmethod Matrix(rows, columns, *args, **kwargs)¶
Type-dependent matrix. Example:
a = sint.Matrix(10, 10)
- classmethod MemValue(value)¶
- classmethod Tensor(shape)¶
Type-dependent tensor of any dimension:
a = sfix.Tensor([10, 10])
- classmethod get_input_from(*args, **kwargs)[source]¶
Secret floating-point input.
- Parameters
player – public (regint/cint/int)
size – vector size (int, default 1)
- classmethod input_tensor_from(player, shape)¶
Input tensor secretly from player.
- Parameters
player – int/regint/cint
shape – tensor shape
- classmethod input_tensor_from_client(client_id, shape)¶
Input tensor secretly from client.
- Parameters
client_id – client identifier (public)
shape – tensor shape
- classmethod input_tensor_via(player, content)¶
Input tensor-like data via a player. This overwrites the input file for the relevant player. The following returns an
sint
matrix of dimension 2 by 2:M = [[1, 2], [3, 4]] sint.input_tensor_via(0, M)
Make sure to copy
Player-Data/Input-P<player>-0
if running on another host.
- max(other)¶
Maximum.
- Parameters
other – any compatible type
- min(other)¶
Minimum.
- Parameters
other – any compatible type
- square()¶
Square.
- class Compiler.types.sgf2n(val=None, size=None)[source]¶
Secret \(\mathrm{GF}(2^n)\) value. n is chosen at runtime. A number operators are supported (
+, -, *, /, **, ^, ~, ==, !=, <<
),sgf2n
. Operators generally work with cgf2n/regint/cint/int, except**, <<
, which require a compile-time integer./
refers to field division.*, /, **
refer to field multiplication and division.- Parameters
val – initialization (sgf2n/cgf2n/regint/int/cint or list thereof)
size – vector size (int), defaults to 1 or size of list
- classmethod Array(size, *args, **kwargs)¶
Type-dependent array. Example:
a = sint.Array(10)
- classmethod Matrix(rows, columns, *args, **kwargs)¶
Type-dependent matrix. Example:
a = sint.Matrix(10, 10)
- classmethod MemValue(value)¶
- classmethod Tensor(shape)¶
Type-dependent tensor of any dimension:
a = sfix.Tensor([10, 10])
- bit_and(other)¶
AND in binary circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Return type
depending on inputs (secret if any of them is)
- classmethod bit_compose(bits)¶
Compose value from bits.
- Parameters
bits – iterable of any type convertible to sint
- bit_decompose(*args, **kwargs)[source]¶
Secret bit decomposition.
- Parameters
bit_length – number of bits
step – use every
step
-th bit
- Returns
list of sgf2n
- bit_not()¶
NOT in binary circuits.
- bit_or(other)¶
OR in binary circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
type depends on inputs (secret if any of them is)
- bit_xor(other)¶
XOR in \(\mathrm{GF}(2^n)\) circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Return type
depending on inputs (secret if any of them is)
- cond_swap(a, b, t=None)¶
Swapping in \(\mathrm{GF}(2^n)\). Similar to
_int.if_else()
.
- classmethod dot_product(*args, **kwargs)¶
Secret dot product.
- Parameters
x – Iterable of secret values
y – Iterable of secret values of same length and type
- Return type
same as inputs
- equal(other, bit_length=None, expand=1)[source]¶
Secret comparison.
- Parameters
other – sgf2n/cgf2n/regint/int
- Returns
0/1 (sgf2n)
- classmethod get_input_from(*args, **kwargs)¶
Secret input from player.
- Parameters
player – public (regint/cint/int)
size – vector size (int, default 1)
- classmethod get_random_bit(*args, **kwargs)¶
Secret random bit according to security model.
- Returns
0/1 50-50
- Parameters
size – vector size (int, default 1)
- classmethod get_random_input_mask_for(*args, **kwargs)¶
Secret random input mask according to security model.
- Returns
mask (sint), mask (personal cint)
- Parameters
size – vector size (int, default 1)
- classmethod get_random_inverse(*args, **kwargs)¶
Secret random inverse tuple according to security model.
- Returns
\((a, a^{-1})\)
- Parameters
size – vector size (int, default 1)
- classmethod get_random_square(*args, **kwargs)¶
Secret random square according to security model.
- Returns
\((a, a^2)\)
- Parameters
size – vector size (int, default 1)
- classmethod get_random_triple(*args, **kwargs)¶
Secret random triple according to security model.
- Returns
\((a, b, ab)\)
- Parameters
size – vector size (int, default 1)
- half_adder(other)¶
Half adder in binary circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
binary sum, carry
- Return type
depending on inputs (secret if any of them is)
- if_else(a, b)¶
MUX in \(\mathrm{GF}(2^n)\) circuits. Similar to
_int.if_else()
.
- classmethod input_tensor_from(player, shape)¶
Input tensor secretly from player.
- Parameters
player – int/regint/cint
shape – tensor shape
- classmethod input_tensor_from_client(client_id, shape)¶
Input tensor secretly from client.
- Parameters
client_id – client identifier (public)
shape – tensor shape
- classmethod input_tensor_via(player, content)¶
Input tensor-like data via a player. This overwrites the input file for the relevant player. The following returns an
sint
matrix of dimension 2 by 2:M = [[1, 2], [3, 4]] sint.input_tensor_via(0, M)
Make sure to copy
Player-Data/Input-P<player>-0
if running on another host.
- classmethod malloc(size, creator_tape=None)¶
Allocate memory (statically).
- Parameters
size – compile-time (int)
- max(other)¶
Maximum.
- Parameters
other – any compatible type
- min(other)¶
Minimum.
- Parameters
other – any compatible type
- not_equal(other, bit_length=None)[source]¶
Secret comparison.
- Parameters
other – sgf2n/cgf2n/regint/int
- Returns
0/1 (sgf2n)
- reveal(*args, **kwargs)¶
Reveal secret value publicly.
- Return type
relevant clear type
- right_shift(*args, **kwargs)[source]¶
Secret right shift by public value:
- Parameters
other – compile-time (int)
bit_length – number of bits of
self
(defaults to \(\mathrm{GF}(2^n)\) bit length)
- square(*args, **kwargs)¶
Secret square.
- class Compiler.types.sint(**kwargs)[source]¶
Secret integer in the protocol-specific domain. It supports operations with
sint
,cint
,regint
, and Python integers. Operations where one of the operands is ansint
either result in ansint
or ansintbit
, the latter for comparisons.The following operations work as expected in the computation domain (modulo a prime or a power of two):
+, -, *
./
denotes the field division modulo a prime. It will reveal if the divisor is zero. Comparisons operators (==, !=, <, <=, >, >=
) assume that the element in the computation domain represents a signed integer in a restricted range, see below. The same holds forabs()
, shift operators (<<, >>
), modulo (%
), and exponentation (**
). Modulo only works if the right-hand operator is a compile-time power of two, and exponentiation only works if the base is two or if the exponent is a compile-time integer.Most non-linear operations require compile-time parameters for bit length and statistical security. They default to the global parameters set by
program.set_bit_length()
andprogram.set_security()
. The acceptable minimum for statistical security is considered to be 40. The defaults for the parameters is output at the beginning of the compilation.If the computation domain is modulo a power of two, the operands will be truncated to the bit length, and the security parameter does not matter. Modulo prime, the behaviour is undefined and potentially insecure if the operands are longer than the bit length.
- Parameters
val – initialization (sint/cint/regint/int/cgf2n or list thereof or sbits/sbitvec/sfix)
size – vector size (int), defaults to 1 or size of list
When converting
sbits
, the result is a vector of bits, and when convertingsbitvec
, the result is a vector of values with bit length equal the length of the input.- classmethod Array(size, *args, **kwargs)¶
Type-dependent array. Example:
a = sint.Array(10)
- classmethod Matrix(rows, columns, *args, **kwargs)¶
Type-dependent matrix. Example:
a = sint.Matrix(10, 10)
- classmethod MemValue(value)¶
- classmethod Tensor(shape)¶
Type-dependent tensor of any dimension:
a = sfix.Tensor([10, 10])
- static bit_adder(*args, **kwargs)¶
Binary adder in arithmetic circuits.
- Parameters
a – summand (list of 0/1 in compatible type)
b – summand (list of 0/1 in compatible type)
carry_in – input carry (default 0)
get_carry – add final carry to output
- Returns
list of 0/1 in relevant type
- bit_and(other)¶
AND in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Return type
depending on inputs (secret if any of them is)
- classmethod bit_compose(bits)¶
Compose value from bits.
- Parameters
bits – iterable of any type convertible to sint
- bit_not()¶
NOT in arithmetic circuits.
- bit_or(other)¶
OR in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
type depends on inputs (secret if any of them is)
- bit_xor(other)¶
XOR in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
type depends on inputs (secret if any of them is)
- cond_swap(a, b)¶
Swapping in arithmetic circuits.
- Parameters
a/b – any type supporting the necessary operations
- Returns
(a, b)
ifself
is 0,(b, a)
ifself
is 1, and undefined otherwise- Return type
depending on operands, secret if any of them is
- classmethod dot_product(*args, **kwargs)¶
Secret dot product.
- Parameters
x – Iterable of secret values
y – Iterable of secret values of same length and type
- Return type
same as inputs
- equal(*args, **kwargs)¶
Secret comparison (signed).
- Parameters
other – sint/cint/regint/int
bit_length – bit length of input (default: global bit length)
- Returns
0/1 (sintbit)
- classmethod get_dabit(*args, **kwargs)[source]¶
Bit in arithmetic and binary circuit according to security model
- classmethod get_input_from(*args, **kwargs)[source]¶
Secret input.
- Parameters
player – public (regint/cint/int)
size – vector size (int, default 1)
- classmethod get_random(*args, **kwargs)[source]¶
Secret random ring element according to security model.
- Parameters
size – vector size (int, default 1)
- classmethod get_random_bit(*args, **kwargs)¶
Secret random bit according to security model.
- Returns
0/1 50-50
- Parameters
size – vector size (int, default 1)
- classmethod get_random_input_mask_for(*args, **kwargs)¶
Secret random input mask according to security model.
- Returns
mask (sint), mask (personal cint)
- Parameters
size – vector size (int, default 1)
- classmethod get_random_int(*args, **kwargs)[source]¶
Secret random n-bit number according to security model.
- Parameters
bits – compile-time integer (int)
size – vector size (int, default 1)
- classmethod get_random_inverse(*args, **kwargs)¶
Secret random inverse tuple according to security model.
- Returns
\((a, a^{-1})\)
- Parameters
size – vector size (int, default 1)
- classmethod get_random_square(*args, **kwargs)¶
Secret random square according to security model.
- Returns
\((a, a^2)\)
- Parameters
size – vector size (int, default 1)
- classmethod get_random_triple(*args, **kwargs)¶
Secret random triple according to security model.
- Returns
\((a, b, ab)\)
- Parameters
size – vector size (int, default 1)
- greater_equal(other, bit_length=None, security=None)¶
Secret comparison (signed).
- Parameters
other – sint/cint/regint/int
bit_length – bit length of input (default: global bit length)
- Returns
0/1 (sintbit)
- greater_than(*args, **kwargs)¶
Secret comparison (signed).
- Parameters
other – sint/cint/regint/int
bit_length – bit length of input (default: global bit length)
- Returns
0/1 (sintbit)
- half_adder(other)¶
Half adder in arithmetic circuits.
- Parameters
self/other – 0 or 1 (any compatible type)
- Returns
binary sum, carry
- Return type
depending on inputs, secret if any is
- if_else(a, b)¶
MUX on bit in arithmetic circuits.
- Parameters
a/b – any type supporting the necessary operations
- Returns
a if
self
is 1, b ifself
is 0, undefined otherwise- Return type
depending on operands, secret if any of them is
- classmethod input_tensor_from(player, shape)¶
Input tensor secretly from player.
- Parameters
player – int/regint/cint
shape – tensor shape
- classmethod input_tensor_from_client(client_id, shape)¶
Input tensor secretly from client.
- Parameters
client_id – client identifier (public)
shape – tensor shape
- classmethod input_tensor_via(player, content)¶
Input tensor-like data via a player. This overwrites the input file for the relevant player. The following returns an
sint
matrix of dimension 2 by 2:M = [[1, 2], [3, 4]] sint.input_tensor_via(0, M)
Make sure to copy
Player-Data/Input-P<player>-0
if running on another host.
- int_div(*args, **kwargs)[source]¶
Secret integer division.
- Parameters
other – sint
bit_length – bit length of input (default: global bit length)
- left_shift(other, bit_length=None, security=None)¶
Secret left shift.
- Parameters
other – secret or public integer (sint/cint/regint/int)
bit_length – bit length of input (default: global bit length)
- less_equal(other, bit_length=None, security=None)¶
Secret comparison (signed).
- Parameters
other – sint/cint/regint/int
bit_length – bit length of input (default: global bit length)
- Returns
0/1 (sintbit)
- less_than(*args, **kwargs)¶
Secret comparison (signed).
- Parameters
other – sint/cint/regint/int
bit_length – bit length of input (default: global bit length)
- Returns
0/1 (sintbit)
- classmethod malloc(size, creator_tape=None)¶
Allocate memory (statically).
- Parameters
size – compile-time (int)
- max(other)¶
Maximum.
- Parameters
other – any compatible type
- min(other)¶
Minimum.
- Parameters
other – any compatible type
- mod2m(*args, **kwargs)[source]¶
Secret modulo power of two.
- Parameters
m – secret or public integer (sint/cint/regint/int)
bit_length – bit length of input (default: global bit length)
- not_equal(other, bit_length=None, security=None)¶
Secret comparison (signed).
- Parameters
other – sint/cint/regint/int
bit_length – bit length of input (default: global bit length)
- Returns
0/1 (sintbit)
- pow2(*args, **kwargs)[source]¶
Secret power of two.
- Parameters
bit_length – bit length of input (default: global bit length)
- private_division(divisor, active=True, dividend_length=None, divisor_length=None)[source]¶
Private integer division as per Veugen and Abspoel
- Parameters
divisor – public (cint/regint) or personal value thereof
active – whether to check on the party knowing the divisor (active security)
dividend_length – bit length of the dividend (default: global bit length)
dividend_length – bit length of the divisor (default: global bit length)
- classmethod read_from_file(start, n_items)[source]¶
Read shares from
Persistence/Transactions-P<playerno>.data
.- Parameters
start – starting position in number of shares from beginning (int/regint/cint)
n_items – number of items (int)
- Returns
destination for final position, -1 for eof reached, or -2 for file not found (regint)
- Returns
list of shares
- classmethod read_from_socket(*args, **kwargs)[source]¶
Receive secret-shared value(s) from client.
- Parameters
client_id – Client id (regint)
n – number of values (default 1)
size – vector size of values (default 1)
- Returns
sint (if n=1) or list of sint
- classmethod receive_from_client(*args, **kwargs)[source]¶
Securely obtain shares of values input by a client. This uses the triple-based input protocol introduced by Damgård et al.
- Parameters
n – number of inputs (int)
client_id – regint
size – vector size (default 1)
- Returns
list of sint
- reveal(*args, **kwargs)¶
Reveal secret value publicly.
- Return type
relevant clear type
- reveal_to(*args, **kwargs)[source]¶
Reveal secret value to
player
.- Parameters
player – public integer (int/regint/cint)
- Returns
- classmethod reveal_to_clients(clients, values)[source]¶
Reveal securely to clients.
- Parameters
clients – client ids (list or array)
values – list of sint to reveal
- right_shift(*args, **kwargs)¶
Secret right shift.
- Parameters
other – secret or public integer (sint/cint/regint/int)
bit_length – bit length of input (default: global bit length)
- round(*args, **kwargs)[source]¶
Truncate and maybe round secret
k
-bit integer bym
bits.m
can be secret ifnearest
is false, in which case the truncation will be exact. For publicm
,nearest
chooses between nearest rounding (rounding half up) and probablistic truncation.- Parameters
k – int
m – secret or compile-time integer (sint/int)
kappa – statistical security parameter (int)
nearest – bool
signed – bool
- square(*args, **kwargs)¶
Secret square.
Send shares of a list of values to a specified client socket.
- Parameters
client_id – regint
values – list of sint
Compiler.GC.types module¶
This modules contains basic types for binary circuits. The
fixed-length types obtained by get_type(n)
are the preferred
way of using them, and in some cases required in connection with
container types.
- class Compiler.GC.types.bits(value=None, n=None, size=None)[source]¶
Bases:
Register
,_structure
,_bit
Base class for binary registers.
- class Compiler.GC.types.cbits(value=None, n=None, size=None)[source]¶
Bases:
bits
Clear bits register. Helper type with limited functionality.
- class Compiler.GC.types.sbitfix(**kwargs)[source]¶
Bases:
_fix
Secret signed integer in one binary register. Use
set_precision()
to change the precision.Example:
print_ln('add: %s', (sbitfix(0.5) + sbitfix(0.3)).reveal()) print_ln('mul: %s', (sbitfix(0.5) * sbitfix(0.3)).reveal()) print_ln('sub: %s', (sbitfix(0.5) - sbitfix(0.3)).reveal()) print_ln('lt: %s', (sbitfix(0.5) < sbitfix(0.3)).reveal())
will output roughly:
add: 0.800003 mul: 0.149994 sub: 0.199997 lt: 0
Note that the default precision (16 bits after the dot, 31 bits in total) only allows numbers up to \(2^{31-16-1} \approx 16000\). You can increase this using
set_precision()
.- classmethod set_precision(f, k=None)[source]¶
Set the precision of the integer representation. Note that some operations are undefined when the precision of
sfix
andcfix
differs. The initial defaults are chosen to allow the best optimization of probabilistic truncation in computation modulo 2^64 (2*k < 64). Generally, 2*k must be at most the integer length for rings and at most m-s-1 for computation modulo an m-bit prime and statistical security s (default 40).- Parameters
f – bit length of decimal part (initial default 16)
k – whole bit length of fixed point, defaults to twice
f
if not given (initial default 31)
- class Compiler.GC.types.sbitfixvec(value=None, *args, **kwargs)[source]¶
Bases:
_fix
Vector of fixed-point numbers for parallel binary computation.
Use
set_precision()
to change the precision.Example:
a = sbitfixvec([sbitfix(0.3), sbitfix(0.5)]) b = sbitfixvec([sbitfix(0.4), sbitfix(0.6)]) c = (a + b).elements() print_ln('add: %s, %s', c[0].reveal(), c[1].reveal()) c = (a * b).elements() print_ln('mul: %s, %s', c[0].reveal(), c[1].reveal()) c = (a - b).elements() print_ln('sub: %s, %s', c[0].reveal(), c[1].reveal()) c = (a < b).bit_decompose() print_ln('lt: %s, %s', c[0].reveal(), c[1].reveal())
This should output roughly:
add: 0.699997, 1.10001 mul: 0.119995, 0.300003 sub: -0.0999908, -0.100021 lt: 1, 1
- classmethod set_precision(f, k=None)[source]¶
Set the precision of the integer representation. Note that some operations are undefined when the precision of
sfix
andcfix
differs. The initial defaults are chosen to allow the best optimization of probabilistic truncation in computation modulo 2^64 (2*k < 64). Generally, 2*k must be at most the integer length for rings and at most m-s-1 for computation modulo an m-bit prime and statistical security s (default 40).- Parameters
f – bit length of decimal part (initial default 16)
k – whole bit length of fixed point, defaults to twice
f
if not given (initial default 31)
- class Compiler.GC.types.sbitint(*args, **kwargs)[source]¶
Bases:
_bitint
,_number
,sbits
,_sbitintbase
Secret signed integer in one binary register. Use
get_type()
to specify the bit length:si32 = sbitint.get_type(32) print_ln('add: %s', (si32(5) + si32(3)).reveal()) print_ln('sub: %s', (si32(5) - si32(3)).reveal()) print_ln('mul: %s', (si32(5) * si32(3)).reveal()) print_ln('lt: %s', (si32(5) < si32(3)).reveal())
This should output:
add: 8 sub: 2 mul: 15 lt: 0
- class Compiler.GC.types.sbitintvec(elements=None, length=None, input_length=None)[source]¶
Bases:
sbitvec
,_number
,_bitint
,_sbitintbase
Vector of signed integers for parallel binary computation:
sb32 = sbits.get_type(32) siv32 = sbitintvec.get_type(32) a = siv32([sb32(3), sb32(5)]) b = siv32([sb32(4), sb32(6)]) c = (a + b).elements() print_ln('add: %s, %s', c[0].reveal(), c[1].reveal()) c = (a * b).elements() print_ln('mul: %s, %s', c[0].reveal(), c[1].reveal()) c = (a - b).elements() print_ln('sub: %s, %s', c[0].reveal(), c[1].reveal()) c = (a < b).bit_decompose() print_ln('lt: %s, %s', c[0].reveal(), c[1].reveal())
This should output:
add: 7, 11 mul: 12, 30 sub: -1, 11 lt: 1, 1
- class Compiler.GC.types.sbits(*args, **kwargs)[source]¶
Bases:
bits
Secret bits register. This type supports basic bit-wise operations:
sb32 = sbits.get_type(32) a = sb32(3) b = sb32(5) print_ln('XOR: %s', (a ^ b).reveal()) print_ln('AND: %s', (a & b).reveal()) print_ln('NOT: %s', (~a).reveal())
This will output the following:
XOR: 6 AND: 1 NOT: -4
Instances can be also be initalized from
regint
andsint
.- static bit_adder(*args, **kwargs)[source]¶
Binary adder in binary circuits.
- Parameters
a – summand (list of 0/1 in compatible type)
b – summand (list of 0/1 in compatible type)
carry_in – input carry (default 0)
get_carry – add final carry to output
- Returns
list of 0/1 in relevant type
- class Compiler.GC.types.sbitvec(elements=None, length=None, input_length=None)[source]¶
Bases:
_vec
Vector of registers of secret bits, effectively a matrix of secret bits. This facilitates parallel arithmetic operations in binary circuits. Container types are not supported, use
sbitvec.get_type
for that.You can access the rows by member
v
and the columns by callingelements
.There are three ways to create an instance:
By transposition:
sb32 = sbits.get_type(32) x = sbitvec([sb32(5), sb32(3), sb32(0)]) print_ln('%s', [x.v[0].reveal(), x.v[1].reveal(), x.v[2].reveal()]) print_ln('%s', [x.elements()[0].reveal(), x.elements()[1].reveal()])
This should output:
[3, 2, 1] [5, 3]
Without transposition:
sb32 = sbits.get_type(32) x = sbitvec.from_vec([sb32(5), sb32(3)]) print_ln('%s', [x.v[0].reveal(), x.v[1].reveal()])
This should output:
[5, 3]
From
sint
:y = sint(5) x = sbitvec(y, 3, 3) print_ln('%s', [x.v[0].reveal(), x.v[1].reveal(), x.v[2].reveal()])
This should output:
[1, 0, 1]
- classmethod get_type(n)[source]¶
Create type for fixed-length vector of registers of secret bits.
As with
sbitvec
, you can access the rows by memberv
and the columns by callingelements
.
- popcnt()[source]¶
Population count / Hamming weight.
- Returns
sbitintvec
of required length
Compiler.library module¶
This module defines functions directly available in high-level programs, in particularly providing flow control and output.
- Compiler.library.accept_client_connection(port)[source]¶
Accept client connection on specific port base.
- Parameters
port – port base (int/regint/cint)
- Returns
client id
- Compiler.library.break_point(name='')[source]¶
Insert break point. This makes sure that all following code will be executed after preceding code.
- Parameters
name – Name for identification (optional)
- Compiler.library.check_point()[source]¶
Force MAC checks in current thread and all idle threads if the current thread is the main thread. This implies a break point.
- Compiler.library.crash(condition=None)[source]¶
Crash virtual machine.
- Parameters
condition – crash if true (default: true)
- Compiler.library.do_while(loop_fn, g=None)[source]¶
Do-while loop. The loop is stopped if the return value is zero. It must be public. The following executes exactly once:
@do_while def _(): ... return regint(0)
- Compiler.library.for_range(start, stop=None, step=None)[source]¶
Decorator to execute loop bodies consecutively. Arguments work as in Python
range()
, but they can by any public integer. Information has to be passed out via container types such asArray
or declaring registers asglobal
. Note that changing Python data structures such as lists within the loop is not possible, but the compiler cannot warn about this.- Parameters
start/stop/step – regint/cint/int
Example:
a = sint.Array(n) x = sint(0) @for_range(n) def _(i): a[i] = i global x x += 1
Note that you cannot overwrite data structures such as
Array
in a loop even when usingglobal
. Useassign()
instead.
- Compiler.library.for_range_multithread(n_threads, n_parallel, n_loops, thread_mem_req={})[source]¶
Execute
n_loops
loop bodies in up ton_threads
threads, up ton_parallel
in parallel per thread.- Parameters
n_threads/n_parallel – compile-time (int)
n_loops – regint/cint/int
- Compiler.library.for_range_opt(n_loops, budget=None)[source]¶
Execute loop bodies in parallel up to an optimization budget. This prevents excessive loop unrolling. The budget is respected even with nested loops. Note that the optimization is rather rudimentary for runtime
n_loops
(regint/cint). Consider usingfor_range_parallel()
in this case. Using further control flow constructions inside other thanfor_range_opt()
(e.g,for_range()
) breaks the optimization.- Parameters
n_loops – int/regint/cint
budget – number of instructions after which to start optimization (default is 100,000)
Example:
@for_range_opt(n) def _(i): ...
Multidimensional ranges are supported as well. The following executes
f(0, 0)
tof(4, 2)
in parallel according to the budget.@for_range_opt([5, 3]) def f(i, j): ...
- Compiler.library.for_range_opt_multithread(n_threads, n_loops)[source]¶
Execute
n_loops
loop bodies in up ton_threads
threads, in parallel up to an optimization budget per thread similar tofor_range_opt()
. Note that optimization is rather rudimentary for runtimen_loops
(regint/cint). Consider usingfor_range_multithread()
in this case.- Parameters
n_threads – compile-time (int)
n_loops – regint/cint/int
The following will execute loop bodies 0-9 in one thread, 10-19 in another etc:
@for_range_opt_multithread(8, 80) def _(i): ...
Multidimensional ranges are supported as well. The following executes
f(0, 0)
tof(2, 0)
in one thread andf(2, 1)
tof(4, 2)
in another.@for_range_opt_multithread(2, [5, 3]) def f(i, j): ...
- Compiler.library.for_range_parallel(n_parallel, n_loops)[source]¶
Decorator to execute a loop
n_loops
up ton_parallel
loop bodies in parallel. Using any other control flow instruction inside the loop breaks the optimization.- Parameters
n_parallel – compile-time (int)
n_loops – regint/cint/int or list of int
Example:
@for_range_parallel(n_parallel, n_loops) def _(i): a[i] = a[i] * a[i]
Multidimensional ranges are supported as well. The following executes
f(0, 0)
tof(4, 2)
, two calls in parallel.@for_range_parallel(2, [5, 3]) def f(i, j): ...
- Compiler.library.foreach_enumerate(a)[source]¶
Run-time loop over public data. This uses
Player-Data/Public-Input/<progname>
. Example:@foreach_enumerate([2, 8, 3]) def _(i, j): print_ln('%s: %s', i, j)
This will output:
0: 2 1: 8 2: 3
- Compiler.library.get_player_id()[source]¶
- Returns
player number
- Return type
localint (cannot be used for computation)
- Compiler.library.get_threshold()[source]¶
The threshold is the maximal number of corrupted players.
- Return type
- Compiler.library.if_(condition)[source]¶
Conditional execution without else block.
- Parameters
condition – regint/cint/int
Usage:
@if_(x > 0) def _(): ...
- Compiler.library.if_e(condition)[source]¶
Conditional execution with else block. Use
MemValue
to assign values that live beyond.- Parameters
condition – regint/cint/int
Usage:
y = MemValue(0) @if_e(x > 0) def _(): y.write(1) @else_ def _(): y.write(0)
- Compiler.library.listen_for_clients(port)[source]¶
Listen for clients on specific port base.
- Parameters
port – port base (int/regint/cint)
- Compiler.library.map_sum_opt(n_threads, n_loops, types)[source]¶
Multi-threaded sum reduction. The following computes a sum of ten squares in three threads:
@map_sum_opt(3, 10, [sint]) def summer(i): return sint(i) ** 2 result = summer()
- Parameters
n_threads – number of threads (int)
n_loops – number of loop runs (regint/cint/int)
types – return type, must match the return statement in the loop
- Compiler.library.map_sum_simple(n_threads, n_loops, type, size)[source]¶
Vectorized multi-threaded sum reduction. The following computes a 100 sums of ten squares in three threads:
@map_sum_simple(3, 10, sint, 100) def summer(i): return sint(regint.inc(100, i, 0)) ** 2 result = summer()
- Parameters
n_threads – number of threads (int)
n_loops – number of loop runs (regint/cint/int)
type – return type, must match the return statement in the loop
size – vector size, must match the return statement in the loop
- Compiler.library.multithread(n_threads, n_items=None, max_size=None)[source]¶
Distribute the computation of
n_items
ton_threads
threads, but leave the in-thread repetition up to the user.- Parameters
n_threads – compile-time (int)
n_items – regint/cint/int (default:
n_threads
)
The following executes
f(0, 8)
,f(8, 8)
, andf(16, 9)
in three different threads:@multithread(8, 25) def f(base, size): ...
- Compiler.library.print_float_precision(n)[source]¶
Set the precision for floating-point printing.
- Parameters
n – number of digits (int)
- Compiler.library.print_ln(s='', *args)[source]¶
Print line, with optional args for adding variables/registers with
%s
. By default only player 0 outputs, but the-I
command-line option changes that.- Parameters
s – Python string with same number of
%s
as length ofargs
args – list of public values (regint/cint/int/cfix/cfloat/localint)
Example:
print_ln('a is %s.', a.reveal())
- Compiler.library.print_ln_if(cond, ss, *args)[source]¶
Print line if
cond
is true. The further arguments are treated as inprint_str()
/print_ln()
.- Parameters
cond – regint/cint/int/localint
ss – Python string
args – list of public values
Example:
print_ln_if(get_player_id() == 0, 'Player 0 here')
- Compiler.library.print_ln_to(player, ss, *args)[source]¶
Print line at
player
only. Note that printing is disabled by default except at player 0. Activate interactive mode with -I to enable it for all players.- Parameters
player – int
ss – Python string
args – list of values known to
player
Example:
print_ln_to(player, 'output for %s: %s', player, x.reveal_to(player))
- Compiler.library.print_str(s, *args)[source]¶
Print a string, with optional args for adding variables/registers with
%s
.
- Compiler.library.print_str_if(cond, ss, *args)[source]¶
Print string conditionally. See
print_ln_if()
for details.
- Compiler.library.runtime_error(msg='', *args)[source]¶
Print an error message and abort the runtime. Parameters work as in
print_ln()
- Compiler.library.runtime_error_if(condition, msg='', *args)[source]¶
Conditionally print an error message and abort the runtime.
- Parameters
condition – regint/cint/int/cbit
msg – message
args – list of public values to fit
%s
in the message
- Compiler.library.start_timer(timer_id=0)[source]¶
Start timer. Timer 0 runs from the start of the program. The total time of all used timers is output at the end. Fails if already running.
- Parameters
timer_id – compile-time (int)
- Compiler.library.stop_timer(timer_id=0)[source]¶
Stop timer. Fails if not running.
- Parameters
timer_id – compile-time (int)
- Compiler.library.while_do(condition, *args)[source]¶
While-do loop. The decorator requires an initialization, and the loop body function must return a suitable input for
condition
.- Parameters
condition – function returning public integer (regint/cint/int)
args – arguments given to
condition
and loop body
The following executes an ten-fold loop:
@while_do(lambda x: x < 10, regint(0)) def f(i): ... return i + 1
Compiler.mpc_math module¶
Module for math operations.
Implements trigonometric and logarithmic functions.
This has to imported explicitly.
- Compiler.mpc_math.atan(*args, **kwargs)¶
Returns the arctangent (sfix) of any given fractional value.
- Parameters
x – fractional input (sfix).
- Returns
arctan of
x
(sfix).
- Compiler.mpc_math.acos(x)[source]¶
Returns the arccosine (sfix) of any given fractional value.
- Parameters
x – fractional input (sfix). \(-1 \le x \le 1\)
- Returns
arccos of
x
(sfix).
- Compiler.mpc_math.asin(x)[source]¶
Returns the arcsine (sfix) of any given fractional value.
- Parameters
x – fractional input (sfix). valid interval is \(-1 \le x \le 1\)
- Returns
arcsin of
x
(sfix).
- Compiler.mpc_math.cos(*args, **kwargs)¶
Returns the cosine of any given fractional value.
- Parameters
x – fractional input (sfix, sfloat)
- Returns
cos of
x
(sfix, sfloat)
- Compiler.mpc_math.exp2_fx(self, *args, **kwargs)¶
Power of two for fixed-point numbers.
- Parameters
a – exponent for \(2^a\) (sfix)
zero_output – whether to output zero for very small values. If not, the result will be undefined.
- Returns
\(2^a\) if it is within the range. Undefined otherwise
- Compiler.mpc_math.InvertSqrt(self, *args, **kwargs)¶
Reciprocal square root approximation by Lu et al.
- Compiler.mpc_math.log2_fx(self, *args, **kwargs)¶
Returns the result of \(\log_2(x)\) for any unbounded number. This is achieved by changing
x
into \(f \cdot 2^n\) where f is bounded by \([0.5, 1]\). Then the polynomials are used to calculate \(\log_2(f)\), which is then just added to \(n\).- Parameters
x – input for \(\log_2\) (sfix, sint).
- Returns
(sfix) the value of \(\log_2(x)\)
- Compiler.mpc_math.log_fx(x, b)[source]¶
Returns the value of the expression \(\log_b(x)\) where
x
is secret shared. It useslog2_fx()
to calculate the expression \(\log_b(2) \cdot \log_2(x)\).- Parameters
x – (sfix, sint) secret shared coefficient for log.
b – (float) base for log operation.
- Returns
(sfix) the value of \(log_b(x)\).
- Compiler.mpc_math.pow_fx(x, y)[source]¶
Returns the value of the expression \(x^y\) where both inputs are secret shared. It uses
log2_fx()
together withexp2_fx()
to calculate the expression \(2^{y \log_2(x)}\).- Parameters
x – (sfix) secret shared base.
y – (sfix, clear types) secret shared exponent.
- Returns
\(x^y\) (sfix) if positive and in range
- Compiler.mpc_math.sin(*args, **kwargs)¶
Returns the sine of any given fractional value.
- Parameters
x – fractional input (sfix, sfloat)
- Returns
sin of
x
(sfix, sfloat)
- Compiler.mpc_math.sqrt(self, *args, **kwargs)¶
Returns the square root (sfix) of any given fractional value as long as it can be rounded to a integral value with
f
bits of decimal precision.- Parameters
x – fractional input (sfix).
- Returns
square root of
x
(sfix).
- Compiler.mpc_math.tan(*args, **kwargs)¶
Returns the tangent of any given fractional value.
- Parameters
x – fractional input (sfix, sfloat)
- Returns
tan of
x
(sfix, sfloat)
Compiler.ml module¶
This module contains machine learning functionality. It is work in progress, so you must expect things to change. The only tested functionality for training is using consecutive layers. This includes logistic regression. It can be run as follows:
sgd = ml.SGD([ml.Dense(n_examples, n_features, 1),
ml.Output(n_examples, approx=True)], n_epochs,
report_loss=True)
sgd.layers[0].X.input_from(0)
sgd.layers[1].Y.input_from(1)
sgd.reset()
sgd.run()
This loads measurements from party 0 and labels (0/1) from party
1. After running, the model is stored in sgd.layers[0].W
and
sgd.layers[0].b
. The approx
parameter determines
whether to use an approximate sigmoid function. Setting it to 5 uses
a five-piece approximation instead of a three-piece one.
A simple network for MNIST using two dense layers can be trained as follows:
sgd = ml.SGD([ml.Dense(60000, 784, 128, activation='relu'),
ml.Dense(60000, 128, 10),
ml.MultiOutput(60000, 10)], n_epochs,
report_loss=True)
sgd.layers[0].X.input_from(0)
sgd.layers[1].Y.input_from(1)
sgd.reset()
sgd.run()
See this repository for scripts importing MNIST training data and further examples.
Inference can be run as follows:
data = sfix.Matrix(n_test, n_features)
data.input_from(0)
res = sgd.eval(data)
print_ln('Results: %s', [x.reveal() for x in res])
For inference/classification, this module offers the layers necessary for neural networks such as DenseNet, ResNet, and SqueezeNet. A minimal example using input from player 0 and model from player 1 looks as follows:
graph = Optimizer()
graph.layers = layers
layers[0].X.input_from(0)
for layer in layers:
layer.input_from(1)
graph.forward(1)
res = layers[-1].Y
See the readme for an example of how to run MP-SPDZ on TensorFlow graphs.
- class Compiler.ml.Adam(layers, n_epochs=1, approx=False, amsgrad=False, normalize=False)[source]¶
Bases:
Optimizer
Adam/AMSgrad optimizer.
- Parameters
layers – layers of linear graph
approx – use approximation for inverse square root (bool)
amsgrad – use AMSgrad (bool)
- class Compiler.ml.Add(inputs)[source]¶
Bases:
NoVariableLayer
Fixed-point addition layer.
- Parameters
inputs – two input layers with same shape (tuple/list)
- class Compiler.ml.Argmax(shape)[source]¶
Bases:
NoVariableLayer
Fixed-point Argmax layer.
- Parameters
shape – input shape (tuple/list of two int)
- class Compiler.ml.BatchNorm(shape, approx=True, args=None)[source]¶
Bases:
Layer
Fixed-point batch normalization layer.
- Parameters
shape – input/output shape (tuple/list of four int)
approx – use approximate square root
- class Compiler.ml.Concat(inputs, dimension)[source]¶
Bases:
NoVariableLayer
Fixed-point concatentation layer.
- Parameters
inputs – two input layers (tuple/list)
dimension – dimension for concatenation (must be 3)
- class Compiler.ml.Dense(N, d_in, d_out, d=1, activation='id', debug=False)[source]¶
Bases:
DenseBase
Fixed-point dense (matrix multiplication) layer.
- Parameters
N – number of examples
d_in – input dimension
d_out – output dimension
- class Compiler.ml.Dropout(N, d1, d2=1, alpha=0.5)[source]¶
Bases:
NoVariableLayer
Dropout layer.
- Parameters
N – number of examples
d1 – total dimension
alpha – probability (power of two)
- class Compiler.ml.FixAveragePool2d(input_shape, output_shape, filter_size, strides=(1, 1))[source]¶
Bases:
FixBase
,AveragePool2d
Fixed-point 2D AvgPool layer.
- Parameters
input_shape – input shape (tuple/list of four int)
output_shape – output shape (tuple/list of four int)
filter_size – filter size (tuple/list of two int)
strides – strides (tuple/list of two int)
- class Compiler.ml.FixConv2d(input_shape, weight_shape, bias_shape, output_shape, stride, padding='SAME', tf_weight_format=False, inputs=None)[source]¶
Bases:
Conv2d
,FixBase
Fixed-point 2D convolution layer.
- Parameters
input_shape – input shape (tuple/list of four int)
weight_shape – weight shape (tuple/list of four int)
bias_shape – bias shape (tuple/list of one int)
output_shape – output shape (tuple/list of four int)
stride – stride (tuple/list of two int)
padding –
'SAME'
(default),'VALID'
, or tuple/list of two inttf_weight_format – weight shape format is (height, width, input channels, output channels) instead of the default (output channels, height, width, input channels)
- class Compiler.ml.FusedBatchNorm(shape, inputs=None)[source]¶
Bases:
Layer
Fixed-point fused batch normalization layer (inference only).
- Parameters
shape – input/output shape (tuple/list of four int)
- class Compiler.ml.MaxPool(shape, strides=(1, 2, 2, 1), ksize=(1, 2, 2, 1), padding='VALID')[source]¶
Bases:
NoVariableLayer
Fixed-point MaxPool layer.
- Parameters
shape – input shape (tuple/list of four int)
strides – strides (tuple/list of four int, first and last must be 1)
ksize – kernel size (tuple/list of four int, first and last must be 1)
padding –
'VALID'
(default) or'SAME'
- class Compiler.ml.MultiOutput(N, d_out, approx=False, debug=False)[source]¶
Bases:
MultiOutputBase
Output layer for multi-class classification with softmax and cross entropy.
- Parameters
N – number of examples
d_out – number of classes
approx – use ReLU division instead of softmax for the loss
- class Compiler.ml.Optimizer(report_loss=None)[source]¶
Bases:
object
Base class for graphs of layers.
- eval(**kwargs)[source]¶
Compute evaluation after training.
- Parameters
data – sample data (
Compiler.types.Matrix
with one row per sample)top – return top prediction instead of probability distribution
- forward(**kwargs)[source]¶
Compute graph.
- Parameters
N – batch size (used if batch not given)
batch – indices for computation (
Array
or list)keep_intermediate – do not free memory of intermediate results after use
- property layers¶
Get all layers.
- class Compiler.ml.Output(N, debug=False, approx=False)[source]¶
Bases:
NoVariableLayer
Fixed-point logistic regression output layer.
- Parameters
N – number of examples
approx –
False
(default) or parameter forapprox_sigmoid
- class Compiler.ml.Relu(shape, inputs=None)[source]¶
Bases:
ElementWiseLayer
Fixed-point ReLU layer.
- Parameters
shape – input/output shape (tuple/list of int)
- static f(x)¶
ReLU function (maximum of input and zero).
- static f_prime(x)¶
ReLU derivative.
- class Compiler.ml.ReluMultiOutput(N, d_out, approx=False, debug=False)[source]¶
Bases:
MultiOutputBase
Output layer for multi-class classification with back-propagation based on ReLU division.
- Parameters
N – number of examples
d_out – number of classes
- class Compiler.ml.SGD(layers, n_epochs, debug=False, report_loss=None)[source]¶
Bases:
Optimizer
Stochastic gradient descent.
- Parameters
layers – layers of linear graph
n_epochs – number of epochs for training
report_loss – disclose and print loss
- class Compiler.ml.Square(shape, inputs=None)[source]¶
Bases:
ElementWiseLayer
Fixed-point square layer.
- Parameters
shape – input/output shape (tuple/list of int)
- Compiler.ml.argmax(x)[source]¶
Compute index of maximum element.
- Parameters
x – iterable
- Returns
sint
- Compiler.ml.mr(A, n_iterations, stop=False)[source]¶
Iterative matrix inverse approximation.
- Parameters
A – matrix to invert
n_iterations – maximum number of iterations
stop – whether to stop when converged (implies revealing)
- Compiler.ml.solve_linear(A, b, n_iterations, progress=False, n_threads=None, stop=False, already_symmetric=False, precond=False)[source]¶
Iterative linear solution approximation for \(Ax=b\).
- Parameters
progress – print some information on the progress (implies revealing)
n_threads – number of threads to use
stop – whether to stop when converged (implies revealing)
- Compiler.ml.approx_sigmoid(*args, **kwargs)¶
Piece-wise approximate sigmoid as in Hong et al.
- Parameters
x – input
n – number of pieces, 3 (default) or 5
Compiler.circuit module¶
This module contains functionality using circuits in the so-called
Bristol Fashion format. You can download a few examples including
the ones used below into Programs/Circuits
as follows:
make Programs/Circuits
- class Compiler.circuit.Circuit(name)[source]¶
Use a Bristol Fashion circuit in a high-level program. The following example adds signed 64-bit inputs from two different parties and prints the result:
from circuit import Circuit sb64 = sbits.get_type(64) adder = Circuit('adder64') a, b = [sbitvec(sb64.get_input_from(i)) for i in (0, 1)] print_ln('%s', adder(a, b).elements()[0].reveal())
Circuits can also be executed in parallel as the following example shows:
from circuit import Circuit sb128 = sbits.get_type(128) key = sb128(0x2b7e151628aed2a6abf7158809cf4f3c) plaintext = sb128(0x6bc1bee22e409f96e93d7e117393172a) n = 1000 aes128 = Circuit('aes_128') ciphertexts = aes128(sbitvec([key] * n), sbitvec([plaintext] * n)) ciphertexts.elements()[n - 1].reveal().print_reg()
This executes AES-128 1000 times in parallel and then outputs the last result, which should be
0x3ad77bb40d7a3660a89ecaf32466ef97
, one of the test vectors for AES-128.
- class Compiler.circuit.ieee_float(value)[source]¶
This gives access IEEE754 floating-point operations using Bristol Fashion circuits. The following example computes the standard deviation of 10 integers input by each of party 0 and 1:
from circuit import ieee_float values = [] for i in range(2): for j in range(10): values.append(sbitint.get_type(64).get_input_from(i)) fvalues = [ieee_float(x) for x in values] avg = sum(fvalues) / ieee_float(len(fvalues)) var = sum(x * x for x in fvalues) / ieee_float(len(fvalues)) - avg * avg stddev = var.sqrt() print_ln('avg: %s', avg.reveal()) print_ln('var: %s', var.reveal()) print_ln('stddev: %s', stddev.reveal())
- Compiler.circuit.sha3_256(x)[source]¶
This function implements SHA3-256 for inputs of up to 1080 bits:
from circuit import sha3_256 a = sbitvec.from_vec([]) b = sbitvec(sint(0xcc), 8, 8) for x in a, b: sha3_256(x).elements()[0].reveal().print_reg()
This should output the first two test vectors of SHA3-256 in byte-reversed order:
0x4a43f8804b0ad882fa493be44dff80f562d661a05647c15166d71ebff8c6ffa7 0xf0d7aa0ab2d92d580bb080e17cbb52627932ba37f085d3931270d31c39357067
Note that
sint
tosbitvec
conversion is only implemented for computation modulo a power of two.
Compiler.program module¶
This module contains the building blocks of the compiler such as code
blocks and registers. Most relevant is the central Program
object that holds various properties of the computation.
- class Compiler.program.Program(args, options=<class 'Compiler.program.defaults'>)[source]¶
A program consists of a list of tapes representing the whole computation.
When compiling an
.mpc
file, the single instances is available asprogram
in order. When compiling directly from Python code, an instance has to be created before running any instructions.- join_tapes(thread_numbers)[source]¶
Wait for completion of tapes. See
new_tape()
for an example.- Parameters
thread_numbers – list of thread numbers
- new_tape(function, args=[], name=None, single_thread=False)[source]¶
Create a new tape from a function. See
multithread()
andfor_range_opt_multithread()
for easier-to-use higher-level functionality. The following runs two threads defined by two different functions:def f(): ... def g(): ... tapes = [program.new_tape(x) for x in (f, g)] thread_numbers = program.run_tapes(tapes) program.join_tapes(threads_numbers)
- Parameters
function – Python function defining the thread
args – arguments to the function
name – name used for files
single_thread – Boolean indicating whether tape will never be run in parallel to itself
- Returns
tape handle
- run_tapes(args)[source]¶
Run tapes in parallel. See
new_tape()
for an example.- Parameters
args – list of tape handles or tuples of tape handle and extra argument (for
get_arg()
)- Returns
list of thread numbers
- property security¶
The statistical security parameter for non-linear functions.
- use_dabit¶
Setting whether to use daBits for non-linear functionality.
- use_edabit(change=None)[source]¶
Setting whether to use edaBits for non-linear functionality (default: false).
- Parameters
change – change setting if not
None
- Returns
setting if
change
isNone
- use_split(change=None)[source]¶
Setting whether to use local arithmetic-binary share conversion for non-linear functionality (default: false).
- Parameters
change – change setting if not
None
- Returns
setting if
change
isNone
- use_square(change=None)[source]¶
Setting whether to use preprocessed square tuples (default: false).
- Parameters
change – change setting if not
None
- Returns
setting if
change
isNone
- property use_trunc_pr¶
Setting whether to use special probabilistic truncation.
Compiler.oram module¶
This module contains an implementation of the tree-based oblivious
RAM as proposed by Shi et al. as
well as the straight-forward construction using linear scanning.
Unlike Array
, this allows access by a
secret index:
a = OptimalORAM(1000)
i = sint.get_input_from(0)
a[i] = sint.get_input_from(1)
Virtual Machine¶
Calling compile.py
outputs the computation in a format specific to
MP-SPDZ. This includes a schedule file and one or several bytecode
files. The schedule file can be found at
Programs/Schedules/<progname>.sch
. It contains the names of all
bytecode files found in Programs/Bytecode
and the maximum number
of parallel threads. Each bytecode file represents the complete
computation of one thread, also called tape. The computation of the
main thread is always Programs/Bytecode/<progname>-0.bc
when
compiled by the compiler.
The bytecode is made up of 32-bit units in big-endian byte order. Every unit represents an instruction code (possibly including vector size), register number, or immediate value.
For example, adding the secret integers in registers 1 and 2 and then storing the result at register 0 leads to the following bytecode (in hexadecimal representation):
00 00 00 21 00 00 00 00 00 00 00 01 00 00 00 02
This is because 0x021
is the code of secret integer addition. The
debugging output (compile.py -a <prefix>
) looks as follows:
adds s0, s1, s2 # <instruction number>
There is also a vectorized addition. Adding 10 secret integers in registers 10-19 and 20-29 and then storing the result in registers 0-9 is represented as follows in bytecode:
00 00 28 21 00 00 00 00 00 00 00 0a 00 00 00 14
This is because the vector size is stored in the upper 22 bits of the
first 32-bit unit (instruction codes are up to 10 bits long), and
0x28
equals 40 or 10 shifted by two bits. In the debugging output
the vectorized addition looks as follows:
vadds 10, s0, s10, s20 # <instruction number>
Finally, some instructions have a variable number of arguments to accommodate any number of parallel operations. For these, the first argument usually indicates the number of arguments yet to come. For example, multiplying the secret integers in registers 2 and 3 as well as registers 4 and 5 and the storing the two results in registers 0 and 1 results in the following bytecode:
00 00 00 a6 00 00 00 06 00 00 00 00 00 00 00 02
00 00 00 03 00 00 00 01 00 00 00 04 00 00 00 05
and the following debugging output:
muls 6, s0, s2, s3, s1, s4, s5 # <instruction number>
Note that calling instructions in high-level code never is done with the explicit number of arguments. Instead, this is derived from number of function arguments. The example above would this simply be called as follows:
muls(s0, s2, s3, s1, s4, s5)
Instructions¶
The following table list all instructions except the ones for \(\mathrm{GF}(2^n)\) computation, untested ones, and those considered obsolete.
Name |
Code |
|
---|---|---|
0x0 |
Meta instruction for emulation |
|
0x1 |
Assign (constant) immediate value to clear register (vector) |
|
0x2 |
Assign (constant) immediate value to secret register (vector) |
|
0x3 |
Assign clear memory value(s) to clear register (vector) by immediate address |
|
0x4 |
Assign secret memory value(s) to secret register (vector) by immediate address |
|
0x5 |
Assign clear register (vector) to clear memory value(s) by immediate address |
|
0x6 |
Assign secret register (vector) to secret memory value(s) by immediate address |
|
0x7 |
Assign clear memory value(s) to clear register (vector) by register address |
|
0x8 |
Assign secret memory value(s) to secret register (vector) by register address |
|
0x9 |
Assign clear register (vector) to clear memory value(s) by register address |
|
0xa |
Assign secret register (vector) to secret memory value(s) by register address |
|
0xb |
Copy clear register (vector) |
|
0xc |
Copy secret register (vector) |
|
0x10 |
Store the number of the current thread in clear integer register |
|
0x11 |
Store the argument passed to the current thread in clear integer register |
|
0x12 |
Requirement on computation modulus |
|
0x13 |
Copy clear integer register to the thread argument |
|
0x14 |
Output time since start of computation |
|
0x15 |
Start timer |
|
0x16 |
Stop timer |
|
0x17 |
Offline data usage |
|
0x18 |
Input usage |
|
0x19 |
Start tape/bytecode file in another thread |
|
0x1a |
Join thread |
|
0x1b |
Crash runtime if the value in the register is not zero |
|
0x1c |
Custom preprocessed data usage |
|
0x1f |
Matrix multiplication usage |
|
0x20 |
Clear addition |
|
0x21 |
Secret addition |
|
0x22 |
Mixed addition |
|
0x23 |
Addition of clear register (vector) and (constant) immediate value |
|
0x24 |
Addition of secret register (vector) and (constant) immediate value |
|
0x25 |
Clear subtraction |
|
0x26 |
Secret subtraction |
|
0x27 |
Subtract clear from secret value |
|
0x28 |
Subtract secret from clear value |
|
0x29 |
Subtraction of (constant) immediate value from clear register (vector) |
|
0x2a |
Subtraction of (constant) immediate value from secret register (vector) |
|
0x2b |
Subtraction of clear register (vector) from (constant) immediate value |
|
0x2c |
Subtraction of secret register (vector) from (constant) immediate value |
|
0x30 |
Clear multiplication |
|
0x31 |
Multiply secret and clear value |
|
0x32 |
Multiplication of clear register (vector) and (constant) immediate value |
|
0x33 |
Multiplication of secret register (vector) and (constant) immediate value |
|
0x34 |
Clear division |
|
0x35 |
Division of secret register (vector) and (constant) immediate value |
|
0x36 |
Clear modular reduction |
|
0x37 |
Modular reduction of clear register (vector) and (constant) immediate value |
|
0x38 |
Clear Legendre symbol computation (a/p) over prime p (the computation modulus) |
|
0x39 |
Clear truncated hash computation |
|
0x3a |
Inverse of power of two modulo prime (the computation modulus) |
|
0x3b |
Clear integer floor division |
|
0x50 |
Store fresh random triple(s) in secret register (vectors) |
|
0x51 |
Store fresh random triple(s) in secret register (vectors) |
|
0x52 |
Store fresh random square(s) in secret register (vectors) |
|
0x53 |
Store fresh random inverse(s) in secret register (vectors) |
|
0x56 |
Store fresh random input mask(s) in secret register (vector) and clear register (vector) of the relevant player |
|
0x57 |
Store custom preprocessed data in secret register (vectors) |
|
0x58 |
Store fresh random daBit(s) in secret register (vectors) |
|
0x59 |
Store fresh random loose edaBit(s) in secret register (vectors) |
|
0x5a |
Store fresh random strict edaBit(s) in secret register (vectors) |
|
0x5b |
Store fresh length-restricted random shares(s) in secret register (vectors) |
|
0x5c |
Store fresh random input mask(s) in secret register (vector) and clear register (vector) of the relevant player |
|
0x5d |
Store share(s) of a fresh secret random element in secret register (vectors) |
|
0x63 |
Read a variable number of clear values in internal representation from socket for a specified client id and store them in clear registers |
|
0x64 |
Read a variable number of secret shares (potentially with MAC) from a socket for a client id and store them in registers |
|
0x66 |
Write a variable number of secret shares (potentially with MAC) from registers into a socket for a specified client id |
|
0x69 |
Read a variable number of 32-bit integers from socket for a specified client id and store them in clear integer registers |
|
0x6b |
Write a variable number of shares (without MACs) from secret registers into socket for a specified client id |
|
0x6c |
Open a server socket on a party-specific port number and listen for client connections (non-blocking) |
|
0x6d |
Wait for a connection at the given port and write socket handle to clear integer register |
|
0x6e |
Close connection to client |
|
0x70 |
Logical AND of clear (vector) registers |
|
0x71 |
Logical XOR of clear (vector) registers |
|
0x72 |
Logical OR of clear (vector) registers |
|
0x73 |
Logical AND of clear register (vector) and (constant) immediate value |
|
0x74 |
Logical XOR of clear register (vector) and (constant) immediate value |
|
0x75 |
Logical OR of clear register (vector) and (constant) immediate value |
|
0x76 |
Clear logical NOT of a constant number of bits of clear (vector) register |
|
0x80 |
Bitwise left shift of clear register (vector) |
|
0x81 |
Bitwise right shift of clear register (vector) |
|
0x82 |
Bitwise left shift of clear register (vector) by (constant) immediate value |
|
0x83 |
Bitwise right shift of clear register (vector) by (constant) immediate value |
|
0x84 |
Bitwise right shift of secret register (vector) by (constant) immediate value |
|
0x90 |
Unconditional relative jump in the bytecode (compile-time parameter) |
|
0x91 |
Conditional relative jump in the bytecode |
|
0x92 |
Conditional relative jump in the bytecode |
|
0x93 |
Clear integer zero test |
|
0x94 |
Clear integer less than zero test |
|
0x95 |
Clear integer less-than comparison |
|
0x96 |
Clear integer greater-than comparison |
|
0x97 |
Clear integer equality test |
|
0x98 |
Unconditional relative jump in the bytecode (run-time parameter) |
|
0x99 |
Clear integer bit decomposition |
|
0x9a |
Store (constant) immediate value in clear integer register (vector) |
|
0x9b |
Clear integer register (vector) addition |
|
0x9c |
Clear integer register (vector) subtraction |
|
0x9d |
Clear integer register (element-wise vector) multiplication |
|
0x9e |
Clear integer register (element-wise vector) division with floor rounding |
|
0x9f |
Output clear integer register |
|
0xa5 |
Reveal secret registers (vectors) to clear registers (vectors) |
|
0xa6 |
(Element-wise) multiplication of secret registers (vectors) |
|
0xa7 |
Constant-vector multiplication of secret registers |
|
0xa8 |
Dot product of secret registers (vectors) |
|
0xa9 |
Probabilistic truncation if supported by the protocol |
|
0xaa |
Secret matrix multiplication from registers |
|
0xab |
Secret matrix multiplication reading directly from memory |
|
0xac |
Secret 2D convolution |
|
0xad |
Private input from cint |
|
0xaf |
Force MAC check in current thread and all idle thread if current thread is the main thread |
|
0xb1 |
Debugging output of clear register (vector) |
|
0xb2 |
Store insecure random value of specified length in clear integer register (vector) |
|
0xb3 |
Output clear register |
|
0xb4 |
Output a single byte |
|
0xb5 |
Output four bytes |
|
0xb6 |
Store public input in clear register (vector) |
|
0xbc |
Output floating-number from clear registers |
|
0xbd |
Write shares to |
|
0xbe |
Read shares from |
|
0xbf |
Conditionally output four bytes |
|
0xc0 |
Convert clear integer register (vector) to clear register (vector) |
|
0xc1 |
Convert clear integer register (vector) to clear register (vector) |
|
0xca |
Assign clear integer memory value(s) to clear integer register (vector) by immediate address |
|
0xcb |
Assign clear integer register (vector) to clear integer memory value(s) by immediate address |
|
0xcc |
Assign clear integer memory value(s) to clear integer register (vector) by register address |
|
0xcd |
Assign clear integer register (vector) to clear integer memory value(s) by register address |
|
0xce |
Pushes clear integer register to the thread-local stack |
|
0xcf |
Pops from the thread-local stack to clear integer register |
|
0xd0 |
Copy clear integer register (vector) |
|
0xd1 |
Create incremental clear integer vector |
|
0xd2 |
Randomly shuffles clear integer vector with public randomness |
|
0xe0 |
Set number of digits after decimal point for |
|
0xe1 |
Conditionally output clear register (with precision) |
|
0xe2 |
Store number of players in clear integer register |
|
0xe3 |
Store maximal number of corrupt players in clear integer register |
|
0xe4 |
Store current player number in clear integer register |
|
0xe5 |
edaBit usage |
|
0xe6 |
Binary integer output |
|
0xe7 |
Binary floating-point output |
|
0xf2 |
Store private input in secret registers (vectors) |
|
0xf3 |
Store private input in secret registers (vectors) |
|
0xf4 |
Store private input in secret registers (vectors) |
|
0xf5 |
Private input from cint |
|
0xf6 |
Private input from cint |
|
0x136 |
Clear GF(2^n) by clear GF(2) multiplication |
|
|
0x137 |
Modular reduction of clear register (vector) and (constant) immediate value |
0x200 |
Bitwise XOR of secret bit register vectors |
|
0x201 |
Bitwise XOR of single secret and clear bit registers |
|
0x202 |
Constant-vector AND of secret bit registers |
|
0x203 |
Secret bit register decomposition |
|
0x204 |
Secret bit register decomposition |
|
0x205 |
Copy clear integer register to secret bit register |
|
0x20a |
Store immediate in secret bit register |
|
0x20b |
Bitwise AND of secret bit register vector |
|
0x20c |
Secret bit register vector transpose |
|
0x20d |
Copy fresh secret random bit to secret bit register |
|
0x20e |
Bitwise AND of single secret and clear bit registers |
|
0x20f |
Bitwise NOT of secret register vector |
|
0x210 |
Bitwise XOR of single clear bit register and immediate |
|
0x211 |
Secret bit register decomposition |
|
0x212 |
Bitwise NOT of secret register vector |
|
0x213 |
Copy clear integer register to clear bit register |
|
0x214 |
Reveal secret bit register vectors and copy result to clear bit register vectors |
|
0x217 |
Copy clear bit memory cell with compile-time address to clear bit register |
|
0x218 |
Copy clear bit register to clear bit memory cell with compile-time address |
|
0x219 |
Bitwise XOR of two single clear bit registers |
|
0x21a |
Integer addition two single clear bit registers |
|
0x21b |
Integer addition single clear bit register and immediate |
|
0x21c |
Integer multiplication single clear bit register and immediate |
|
0x21d |
Right shift of clear bit register by immediate |
|
0x21e |
Left shift of clear bit register by immediate |
|
0x21f |
Copy clear register vector by bit to clear bit register vectors |
|
0x220 |
Signed output of clear bit register |
|
0x221 |
Debug output of clear bit register |
|
0x222 |
Output clear bit register |
|
0x223 |
Output floating-number from clear bit registers |
|
0x224 |
Conditionally output four bytes |
|
0x230 |
Copy clear bit register to clear integer register |
|
0x231 |
Copy clear bit register vector to clear register by bit |
|
0x240 |
Copy secret bit memory cell with compile-time address to secret bit register |
|
0x241 |
Copy secret bit register to secret bit memory cell with compile-time address |
|
0x242 |
Copy secret bit memory cell with run-time address to secret bit register |
|
0x243 |
Copy secret bit register to secret bit memory cell with run-time address |
|
0x244 |
Copy secret bit register |
|
0x246 |
Copy private input to secret bit register vectors |
|
0x247 |
Copy private input to secret bit registers bit by bit |
|
0x248 |
Local share conversion |
|
0x249 |
Copy clear bit register vector to secret bit register vector |
|
0x258 |
Copy clear bit memory cell with run-time address to clear bit register |
|
0x259 |
Copy clear bit register to clear bit memory cell with run-time address |
Compiler.instructions module¶
This module contains all instruction types for arithmetic computation and general control of the virtual machine such as control flow.
The parameter descriptions refer to the instruction arguments in the right order.
- class Compiler.instructions.acceptclientconnection(*args, **kwargs)[source]¶
Wait for a connection at the given port and write socket handle to clear integer register.
- Param
client id destination (regint)
- Param
port number (regint)
- class Compiler.instructions.addc(*args, **kwargs)[source]¶
Clear addition.
- Param
result (cint)
- Param
summand (cint)
- Param
summand (cint)
- class Compiler.instructions.addci(*args, **kwargs)[source]¶
Addition of clear register (vector) and (constant) immediate value.
- Param
result (cint)
- Param
summand (cint)
- Param
summand (int)
- class Compiler.instructions.addint(*args, **kwargs)[source]¶
Clear integer register (vector) addition.
- Param
result (regint)
- Param
summand (regint)
- Param
summand (regint)
- op(b, /)¶
Same as a + b.
- class Compiler.instructions.addm(*args, **kwargs)[source]¶
Mixed addition.
- Param
result (sint)
- Param
summand (sint)
- Param
summand (cint)
- class Compiler.instructions.adds(*args, **kwargs)[source]¶
Secret addition.
- Param
result (sint)
- Param
summand (sint)
- Param
summand (sint)
- class Compiler.instructions.addsi(*args, **kwargs)[source]¶
Addition of secret register (vector) and (constant) immediate value.
- Param
result (cint)
- Param
summand (cint)
- Param
summand (int)
- class Compiler.instructions.andc(*args, **kwargs)[source]¶
Logical AND of clear (vector) registers.
- Param
result (cint)
- Param
operand (cint)
- Param
operand (cint)
- class Compiler.instructions.andci(*args, **kwargs)[source]¶
Logical AND of clear register (vector) and (constant) immediate value.
- Param
result (cint)
- Param
operand (cint)
- Param
operand (int)
- class Compiler.instructions.asm_open(*args, **kwargs)[source]¶
Reveal secret registers (vectors) to clear registers (vectors).
- Param
number of argument to follow (multiple of two)
- Param
destination (cint)
- Param
source (sint)
- Param
(repeat the last two)…
- class Compiler.instructions.bit(*args, **kwargs)[source]¶
Store fresh random triple(s) in secret register (vectors).
- Param
destination (sint)
- class Compiler.instructions.bitdecint(*args, **kwargs)[source]¶
Clear integer bit decomposition.
- Param
number of arguments to follow / number of bits minus one (int)
- Param
source (regint)
- Param
destination for least significant bit (regint)
- Param
(destination for one bit higher)…
- class Compiler.instructions.check(*args, **kwargs)[source]¶
Force MAC check in current thread and all idle thread if current thread is the main thread.
- class Compiler.instructions.cisc[source]¶
Meta instruction for emulation. This instruction is only generated when using
-K
withcompile.py
. The header looks as follows:- Param
number of arguments after name plus one
- Param
name (16 bytes, zero-padded)
Currently, the following names are supported:
- LTZ
Less than zero.
- param
number of arguments in this unit (must be 6)
- param
vector size
- param
result (sint)
- param
input (sint)
- param
bit length
- param
(ignored)
- param
(repeat)…
- Trunc
Truncation.
- param
number of arguments in this unit (must be 8)
- param
vector size
- param
result (sint)
- param
input (sint)
- param
bit length
- param
number of bits to truncate
- param
(ignored)
- param
0 for unsigned or 1 for signed
- param
(repeat)…
- FPDiv
Fixed-point division. Division by zero results in zero without error.
- param
number of arguments in this unit (must be at least 7)
- param
vector size
- param
result (sint)
- param
dividend (sint)
- param
divisor (sint)
- param
(ignored)
- param
fixed-point precision
- param
(repeat)…
- exp2_fx
Fixed-point power of two.
- param
number of arguments in this unit (must be at least 6)
- param
vector size
- param
result (sint)
- param
exponent (sint)
- param
(ignored)
- param
fixed-point precision
- param
(repeat)…
- log2_fx
Fixed-point logarithm with base 2.
- param
number of arguments in this unit (must be at least 6)
- param
vector size
- param
result (sint)
- param
input (sint)
- param
(ignored)
- param
fixed-point precision
- param
(repeat)…
- class Compiler.instructions.closeclientconnection(*args, **kwargs)[source]¶
Close connection to client.
- Param
client id (regint)
- class Compiler.instructions.cond_print_plain(*args, **kwargs)[source]¶
Conditionally output clear register (with precision). Outputs \(x \cdot 2^p\) where \(p\) is the precision.
- Param
condition (cint, no output if zero)
- Param
source (cint)
- Param
precision (cint)
- class Compiler.instructions.cond_print_str(cond, val)[source]¶
Conditionally output four bytes.
- Param
condition (cint, no output if zero)
- Param
four bytes (int)
- class Compiler.instructions.conv2ds(*args, **kwargs)[source]¶
Secret 2D convolution.
- Param
result (sint vector in row-first order)
- Param
inputs (sint vector in row-first order)
- Param
weights (sint vector in row-first order)
- Param
output height (int)
- Param
output width (int)
- Param
input height (int)
- Param
input width (int)
- Param
weight height (int)
- Param
weight width (int)
- Param
stride height (int)
- Param
stride width (int)
- Param
number of channels (int)
- Param
padding height (int)
- Param
padding width (int)
- Param
batch size (int)
- class Compiler.instructions.convint(*args, **kwargs)[source]¶
Convert clear integer register (vector) to clear register (vector).
- Param
destination (cint)
- Param
source (regint)
- class Compiler.instructions.convmodp(*args, **kwargs)[source]¶
Convert clear integer register (vector) to clear register (vector). If the bit length is zero, the unsigned conversion is used, otherwise signed conversion is used. This makes a difference when computing modulo a prime \(p\). Signed conversion of \(p-1\) results in -1 while signed conversion results in \((p-1) \mod 2^{64}\).
- Param
destination (regint)
- Param
source (cint)
- Param
bit length (int)
- class Compiler.instructions.crash(*args, **kwargs)[source]¶
Crash runtime if the value in the register is not zero.
- Param
Crash condition (regint)
- class Compiler.instructions.dabit(*args, **kwargs)[source]¶
Store fresh random daBit(s) in secret register (vectors).
- Param
arithmetic part (sint)
- Param
binary part (sbit)
- class Compiler.instructions.digestc(*args, **kwargs)[source]¶
Clear truncated hash computation.
- Param
result (cint)
- Param
input (cint)
- Param
byte length of hash value used (int)
- class Compiler.instructions.divc(*args, **kwargs)[source]¶
Clear division.
- Param
result (cint)
- Param
dividend (cint)
- Param
divisor (cint)
- class Compiler.instructions.divci(*args, **kwargs)[source]¶
Division of secret register (vector) and (constant) immediate value.
- Param
result (cint)
- Param
dividend (cint)
- Param
divisor (int)
- class Compiler.instructions.divint(*args, **kwargs)[source]¶
Clear integer register (element-wise vector) division with floor rounding.
- Param
result (regint)
- Param
dividend (regint)
- Param
divisor (regint)
- op(b, /)¶
Same as a // b.
- class Compiler.instructions.dotprods(*args)[source]¶
Dot product of secret registers (vectors). Note that the vectorized version works element-wise.
- Param
number of arguments to follow (int)
- Param
twice the dot product length plus two (I know…)
- Param
result (sint)
- Param
first factor (sint)
- Param
first factor (sint)
- Param
second factor (sint)
- Param
second factor (sint)
- Param
(remaining factors)…
- Param
(repeat from dot product length)…
- class Compiler.instructions.edabit(*args, **kwargs)[source]¶
Store fresh random loose edaBit(s) in secret register (vectors). The length is the first argument minus one.
- Param
number of arguments to follow / number of bits plus two (int)
- Param
arithmetic (sint)
- Param
binary (sbit)
- Param
(binary)…
- class Compiler.instructions.eqc(*args, **kwargs)[source]¶
Clear integer equality test. The result is 1 if the operands are equal and 0 otherwise.
- Param
destination (regint)
- Param
first operand (regint)
- Param
second operand (regint)
- op(b, /)¶
Same as a == b.
- class Compiler.instructions.eqzc(*args, **kwargs)[source]¶
Clear integer zero test. The result is 1 for true and 0 for false.
- Param
destination (regint)
- Param
operand (regint)
- class Compiler.instructions.floatoutput(*args, **kwargs)[source]¶
Binary floating-point output.
- Param
player (int)
- Param
significand (cint)
- Param
exponent (cint)
- Param
zero bit (cint)
- Param
sign bit (cint)
- class Compiler.instructions.floordivc(*args, **kwargs)[source]¶
Clear integer floor division.
- Param
result (cint)
- Param
dividend (cint)
- Param
divisor (cint)
- class Compiler.instructions.gbitcom(*args, **kwargs)[source]¶
Store the bits $cg_j, dots$ as every $n$-th bit of $cg_i$.
- class Compiler.instructions.gbitdec(*args, **kwargs)[source]¶
Store every $n$-th bit of $cg_i$ in $cg_j, dots$.
- class Compiler.instructions.gbitgf2ntriple(*args, **kwargs)[source]¶
Load secret variables $s_i$, $s_j$ and $s_k$ with the next GF(2) and GF(2^n) multiplication triple.
- class Compiler.instructions.gbittriple(*args, **kwargs)[source]¶
Load secret variables $s_i$, $s_j$ and $s_k$ with the next GF(2) multiplication triple.
- class Compiler.instructions.gconvgf2n(*args, **kwargs)[source]¶
Convert from clear modp register $c_j$ to integer register $ci_i$.
- class Compiler.instructions.gldmci(*args, **kwargs)[source]¶
Assigns register $c_i$ the value in memory verb+C[cj]+.
- direct¶
alias of
GF2N_Instruction
- class Compiler.instructions.gldmsi(*args, **kwargs)[source]¶
Assigns register $s_i$ the value in memory verb+S[cj]+.
- direct¶
alias of
GF2N_Instruction
- class Compiler.instructions.gmulbitc(*args, **kwargs)[source]¶
Clear GF(2^n) by clear GF(2) multiplication
- class Compiler.instructions.gmulbitm(*args, **kwargs)[source]¶
Secret GF(2^n) by clear GF(2) multiplication
- class Compiler.instructions.gstmci(*args, **kwargs)[source]¶
Sets verb+C[cj]+ to be the value $c_i$.
- direct¶
alias of
GF2N_Instruction
- class Compiler.instructions.gstmsi(*args, **kwargs)[source]¶
Sets verb+S[cj]+ to be the value $s_i$.
- direct¶
alias of
GF2N_Instruction
- class Compiler.instructions.gtc(*args, **kwargs)[source]¶
Clear integer greater-than comparison. The result is 1 if the first operand is greater and 0 otherwise.
- Param
destination (regint)
- Param
first operand (regint)
- Param
second operand (regint)
- op(b, /)¶
Same as a > b.
- class Compiler.instructions.incint(*args, **kwargs)[source]¶
Create incremental clear integer vector. For example, vector size 10, base 1, increment 2, repeat 3, and wrap 2 produces the following:
(1, 1, 1, 3, 3, 3, 1, 1, 1, 3)
This is because the first number is always the
base
, every number is repeatedrepeat
times, after whichincrement
is added, and afterwrap
increments the number returns tobase
.- Param
destination (regint)
- Param
base (non-vector regint)
- Param
increment (int)
- Param
repeat (int)
- Param
wrap (int)
- class Compiler.instructions.inputmask(*args, **kwargs)[source]¶
Store fresh random input mask(s) in secret register (vector) and clear register (vector) of the relevant player.
- Param
mask (sint)
- Param
mask (cint, player only)
- Param
player (int)
- class Compiler.instructions.inputmaskreg(*args, **kwargs)[source]¶
Store fresh random input mask(s) in secret register (vector) and clear register (vector) of the relevant player.
- Param
mask (sint)
- Param
mask (cint, player only)
- Param
player (regint)
- class Compiler.instructions.inputmixed(name, *args)[source]¶
Store private input in secret registers (vectors). The input is read as integer or floating-point number and the latter is then converted to the internal representation using the given precision. This instruction uses compile-time player numbers.
- Param
number of arguments to follow (int)
- Param
type (0: integer, 1: fixed-point, 2: floating-point)
- Param
destination (sint)
- Param
destination (sint, only for floating-point)
- Param
destination (sint, only for floating-point)
- Param
destination (sint, only for floating-point)
- Param
fixed-point precision or precision of floating-point significand (int, not with integer)
- Param
input player (int)
- Param
(repeat from type parameter)…
- class Compiler.instructions.inputmixedreg(name, *args)[source]¶
Store private input in secret registers (vectors). The input is read as integer or floating-point number and the latter is then converted to the internal representation using the given precision. This instruction uses run-time player numbers.
- Param
number of arguments to follow (int)
- Param
type (0: integer, 1: fixed-point, 2: floating-point)
- Param
destination (sint)
- Param
destination (sint, only for floating-point)
- Param
destination (sint, only for floating-point)
- Param
destination (sint, only for floating-point)
- Param
fixed-point precision or precision of floating-point significand (int, not with integer)
- Param
input player (regint)
- Param
(repeat from type parameter)…
- class Compiler.instructions.inputpersonal(*args)[source]¶
Private input from cint.
- Param
vector size (int)
- Param
player (int)
- Param
destination (sint)
- Param
source (cint)
- Param
(repeat from vector size)…
- class Compiler.instructions.intoutput(*args, **kwargs)[source]¶
Binary integer output.
- Param
player (int)
- Param
regint
- class Compiler.instructions.inv2m(*args, **kwargs)[source]¶
Inverse of power of two modulo prime (the computation modulus).
- Param
result (cint)
- Param
exponent (int)
- class Compiler.instructions.inverse(*args, **kwargs)[source]¶
Store fresh random inverse(s) in secret register (vectors).
- Param
value (sint)
- Param
inverse (sint)
- class Compiler.instructions.jmp(*args, **kwargs)[source]¶
Unconditional relative jump in the bytecode (compile-time parameter). The parameter is added to the regular jump of one after every instruction. This means that a jump of 0 results in a no-op while a jump of -1 results in an infinite loop.
- Param
number of instructions (int)
- class Compiler.instructions.jmpeqz(*args, **kwargs)[source]¶
Conditional relative jump in the bytecode. The parameter is added to the regular jump of one after every instruction. This means that a jump of 0 results in a no-op while a jump of -1 results in an infinite loop.
- Param
condition (regint, only jump if zero)
- Param
number of instructions (int)
- class Compiler.instructions.jmpi(*args, **kwargs)[source]¶
Unconditional relative jump in the bytecode (run-time parameter). The parameter is added to the regular jump of one after every instruction. This means that a jump of 0 results in a no-op while a jump of -1 results in an infinite loop.
- Param
number of instructions (regint)
- class Compiler.instructions.jmpnz(*args, **kwargs)[source]¶
Conditional relative jump in the bytecode. The parameter is added to the regular jump of one after every instruction. This means that a jump of 0 results in a no-op while a jump of -1 results in an infinite loop.
- Param
condition (regint, only jump if not zero)
- Param
number of instructions (int)
- class Compiler.instructions.join_tape(*args, **kwargs)[source]¶
Join thread.
- Param
virtual machine thread number (int)
- class Compiler.instructions.ldarg(*args, **kwargs)[source]¶
Store the argument passed to the current thread in clear integer register.
- Param
destination (regint)
- class Compiler.instructions.ldi(*args, **kwargs)[source]¶
Assign (constant) immediate value to clear register (vector).
- Param
destination (cint)
- Param
value (int)
- class Compiler.instructions.ldint(*args, **kwargs)[source]¶
Store (constant) immediate value in clear integer register (vector).
- Param
destination (regint)
- Param
immediate (int)
- class Compiler.instructions.ldmc(*args, **kwargs)[source]¶
Assign clear memory value(s) to clear register (vector) by immediate address. The vectorized version starts at the base address and then iterates the memory address.
- Param
destination (cint)
- Param
memory address base (int)
- class Compiler.instructions.ldmci(*args, **kwargs)[source]¶
Assign clear memory value(s) to clear register (vector) by register address. The vectorized version starts at the base address and then iterates the memory address.
- Param
destination (cint)
- Param
memory address base (regint)
- class Compiler.instructions.ldmint(*args, **kwargs)[source]¶
Assign clear integer memory value(s) to clear integer register (vector) by immediate address. The vectorized version starts at the base address and then iterates the memory address.
- Param
destination (regint)
- Param
memory address base (int)
- class Compiler.instructions.ldminti(*args, **kwargs)[source]¶
Assign clear integer memory value(s) to clear integer register (vector) by register address. The vectorized version starts at the base address and then iterates the memory address.
- Param
destination (regint)
- Param
memory address base (regint)
- class Compiler.instructions.ldms(*args, **kwargs)[source]¶
Assign secret memory value(s) to secret register (vector) by immediate address. The vectorized version starts at the base address and then iterates the memory address.
- Param
destination (sint)
- Param
memory address base (int)
- class Compiler.instructions.ldmsi(*args, **kwargs)[source]¶
Assign secret memory value(s) to secret register (vector) by register address. The vectorized version starts at the base address and then iterates the memory address.
- Param
destination (sint)
- Param
memory address base (regint)
- class Compiler.instructions.ldsi(*args, **kwargs)[source]¶
Assign (constant) immediate value to secret register (vector).
- Param
destination (sint)
- Param
value (int)
- class Compiler.instructions.ldtn(*args, **kwargs)[source]¶
Store the number of the current thread in clear integer register.
- Param
destination (regint)
- class Compiler.instructions.legendrec(*args, **kwargs)[source]¶
Clear Legendre symbol computation (a/p) over prime p (the computation modulus).
- Param
result (cint)
- Param
a (int)
- class Compiler.instructions.listen(*args, **kwargs)[source]¶
Open a server socket on a party-specific port number and listen for client connections (non-blocking).
- Param
port number (regint)
- class Compiler.instructions.ltc(*args, **kwargs)[source]¶
Clear integer less-than comparison. The result is 1 if the first operand is less and 0 otherwise.
- Param
destination (regint)
- Param
first operand (regint)
- Param
second operand (regint)
- op(b, /)¶
Same as a < b.
- class Compiler.instructions.ltzc(*args, **kwargs)[source]¶
Clear integer less than zero test. The result is 1 for true and 0 for false.
- Param
destination (regint)
- Param
operand (regint)
- class Compiler.instructions.matmuls(*args, **kwargs)[source]¶
Secret matrix multiplication from registers. All matrices are represented as vectors in row-first order.
- Param
result (sint vector)
- Param
first factor (sint vector)
- Param
second factor (sint vector)
- Param
number of rows in first factor and result (int)
- Param
number of columns in first factor and rows in second factor (int)
- Param
number of columns in second factor and result (int)
- class Compiler.instructions.matmulsm(*args, **kwargs)[source]¶
Secret matrix multiplication reading directly from memory.
- Param
result (sint vector in row-first order)
- Param
base address of first factor (regint value)
- Param
base address of second factor (regint value)
- Param
number of rows in first factor and result (int)
- Param
number of columns in first factor and rows in second factor (int)
- Param
number of columns in second factor and result (int)
- Param
rows of first factor to use (regint vector, length as number of rows in first factor)
- Param
columns of first factor to use (regint vector, length below)
- Param
rows of second factor to use (regint vector, length below)
- Param
columns of second factor to use (regint vector, length below)
- Param
number of columns of first / rows of second factor to use (int)
- Param
number of columns of second factor to use (int)
- class Compiler.instructions.modc(*args, **kwargs)[source]¶
Clear modular reduction.
- Param
result (cint)
- Param
dividend (cint)
- Param
divisor (cint)
- class Compiler.instructions.modci(*args, **kwargs)[source]¶
Modular reduction of clear register (vector) and (constant) immediate value.
- Param
result (cint)
- Param
dividend (cint)
- Param
divisor (int)
- class Compiler.instructions.movc(*args, **kwargs)[source]¶
Copy clear register (vector).
- Param
destination (cint)
- Param
source (cint)
- class Compiler.instructions.movint(*args, **kwargs)[source]¶
Copy clear integer register (vector).
- Param
destination (regint)
- Param
source (regint)
- class Compiler.instructions.movs(*args, **kwargs)[source]¶
Copy secret register (vector).
- Param
destination (cint)
- Param
source (cint)
- class Compiler.instructions.mulc(*args, **kwargs)[source]¶
Clear multiplication.
- Param
result (cint)
- Param
factor (cint)
- Param
factor (cint)
- class Compiler.instructions.mulci(*args, **kwargs)[source]¶
Multiplication of clear register (vector) and (constant) immediate value.
- Param
result (cint)
- Param
factor (cint)
- Param
factor (int)
- class Compiler.instructions.mulint(*args, **kwargs)[source]¶
Clear integer register (element-wise vector) multiplication.
- Param
result (regint)
- Param
factor (regint)
- Param
factor (regint)
- op(b, /)¶
Same as a * b.
- class Compiler.instructions.mulm(*args, **kwargs)[source]¶
Multiply secret and clear value.
- Param
result (sint)
- Param
factor (sint)
- Param
factor (cint)
- class Compiler.instructions.mulrs(res, x, y)[source]¶
Constant-vector multiplication of secret registers.
- Param
number of arguments to follow (multiple of four)
- Param
vector size (int)
- Param
result (sint)
- Param
vector factor (sint)
- Param
constant factor (sint)
- Param
(repeat the last four)…
- class Compiler.instructions.muls(*args, **kwargs)[source]¶
(Element-wise) multiplication of secret registers (vectors).
- Param
number of arguments to follow (multiple of three)
- Param
result (sint)
- Param
factor (sint)
- Param
factor (sint)
- Param
(repeat the last three)…
- class Compiler.instructions.mulsi(*args, **kwargs)[source]¶
Multiplication of secret register (vector) and (constant) immediate value.
- Param
result (sint)
- Param
factor (sint)
- Param
factor (int)
- class Compiler.instructions.notc(*args, **kwargs)[source]¶
Clear logical NOT of a constant number of bits of clear (vector) register.
- Param
result (cint)
- Param
operand (cint)
- Param
bit length (int)
- class Compiler.instructions.nplayers(*args, **kwargs)[source]¶
Store number of players in clear integer register.
- Param
destination (regint)
- class Compiler.instructions.orc(*args, **kwargs)[source]¶
Logical OR of clear (vector) registers.
- Param
result (cint)
- Param
operand (cint)
- Param
operand (cint)
- class Compiler.instructions.orci(*args, **kwargs)[source]¶
Logical OR of clear register (vector) and (constant) immediate value.
- Param
result (cint)
- Param
operand (cint)
- Param
operand (int)
- class Compiler.instructions.playerid(*args, **kwargs)[source]¶
Store current player number in clear integer register.
- Param
destination (regint)
- class Compiler.instructions.popint(*args, **kwargs)[source]¶
Pops from the thread-local stack to clear integer register.
- Param
destination (regint)
- class Compiler.instructions.prep(*args, **kwargs)[source]¶
Store custom preprocessed data in secret register (vectors).
- Param
number of arguments to follow (int)
- Param
tag (16 bytes / 4 units, cut off at first zero byte)
- Param
destination (sint)
- Param
(repeat destination)…
- class Compiler.instructions.print_float_plain(*args, **kwargs)[source]¶
Output floating-number from clear registers.
- Param
significand (cint)
- Param
exponent (cint)
- Param
zero bit (cint, zero output if bit is one)
- Param
sign bit (cint, negative output if bit is one)
- Param
NaN (cint, regular number if zero)
- class Compiler.instructions.print_float_prec(*args, **kwargs)[source]¶
Set number of digits after decimal point for
print_float_plain
.- Param
number of digits (int)
- class Compiler.instructions.print_int(*args, **kwargs)[source]¶
Output clear integer register.
- Param
source (regint)
- class Compiler.instructions.print_reg(reg, comment='')[source]¶
Debugging output of clear register (vector).
- Param
source (cint)
- Param
comment (4 bytes / 1 unit)
- class Compiler.instructions.print_reg_plain(*args, **kwargs)[source]¶
Output clear register.
- Param
source (cint)
- class Compiler.instructions.privateoutput(*args)[source]¶
Private input from cint.
- Param
vector size (int)
- Param
player (int)
- Param
destination (cint)
- Param
source (sint)
- Param
(repeat from vector size)…
- class Compiler.instructions.pubinput(*args, **kwargs)[source]¶
Store public input in clear register (vector).
- Param
destination (cint)
- class Compiler.instructions.pushint(*args, **kwargs)[source]¶
Pushes clear integer register to the thread-local stack.
- Param
source (regint)
- class Compiler.instructions.rand(*args, **kwargs)[source]¶
Store insecure random value of specified length in clear integer register (vector).
- Param
destination (regint)
- Param
length (regint)
- class Compiler.instructions.randomfulls(*args, **kwargs)[source]¶
Store share(s) of a fresh secret random element in secret register (vectors).
- Param
destination (sint)
- class Compiler.instructions.randoms(*args, **kwargs)[source]¶
Store fresh length-restricted random shares(s) in secret register (vectors). This is only implemented for protocols that also implement local share conversion with
split
.- Param
destination (sint)
- Param
length (int)
- class Compiler.instructions.rawinput(*args, **kwargs)[source]¶
Store private input in secret registers (vectors). The input is read in the internal binary format according to the protocol.
- Param
number of arguments to follow (multiple of two)
- Param
player number (int)
- Param
destination (sint)
Read shares from
Persistence/Transactions-P<playerno>.data
.- Param
number of arguments to follow / number of shares plus two (int)
- Param
starting position in number of shares from beginning (regint)
- Param
destination for final position, -1 for eof reached, or -2 for file not found (regint)
- Param
destination for share (sint)
- Param
(repeat from destination for share)…
- class Compiler.instructions.readsocketc(*args, **kwargs)[source]¶
Read a variable number of clear values in internal representation from socket for a specified client id and store them in clear registers.
- Param
number of arguments to follow / number of inputs minus one (int)
- Param
client id (regint)
- Param
vector size (int)
- Param
destination (cint)
- Param
(repeat destination)…
- class Compiler.instructions.readsocketint(*args, **kwargs)[source]¶
Read a variable number of 32-bit integers from socket for a specified client id and store them in clear integer registers.
- Param
number of arguments to follow / number of inputs minus one (int)
- Param
client id (regint)
- Param
vector size (int)
- Param
destination (regint)
- Param
(repeat destination)…
- class Compiler.instructions.readsockets(*args, **kwargs)[source]¶
Read a variable number of secret shares (potentially with MAC) from a socket for a client id and store them in registers. If the protocol uses MACs, the client should be different for every party.
- Param
client id (regint)
- Param
vector size (int)
- Param
source (sint)
- Param
(repeat source)…
- class Compiler.instructions.reqbl(*args, **kwargs)[source]¶
Requirement on computation modulus. Minimal bit length of prime if positive, minus exact bit length of power of two if negative.
- Param
requirement (int)
- class Compiler.instructions.run_tape(*args, **kwargs)[source]¶
Start tape/bytecode file in another thread.
- Param
number of arguments to follow (multiple of three)
- Param
virtual machine thread number (int)
- Param
tape number (int)
- Param
tape argument (int)
- Param
(repeat the last three)…
- class Compiler.instructions.sedabit(*args, **kwargs)[source]¶
Store fresh random strict edaBit(s) in secret register (vectors). The length is the first argument minus one.
- Param
number of arguments to follow / number of bits plus two (int)
- Param
arithmetic (sint)
- Param
binary (sbit)
- Param
(binary)…
- class Compiler.instructions.sendpersonal(*args)[source]¶
Private input from cint.
- Param
vector size (int)
- Param
destination player (int)
- Param
destination (cint)
- Param
source player (int)
- Param
source (cint)
- Param
(repeat from vector size)…
- class Compiler.instructions.shlc(*args, **kwargs)[source]¶
Bitwise left shift of clear register (vector).
- Param
result (cint)
- Param
first operand (cint)
- Param
second operand (cint)
- class Compiler.instructions.shlci(*args, **kwargs)[source]¶
Bitwise left shift of clear register (vector) by (constant) immediate value.
- Param
result (cint)
- Param
first operand (cint)
- Param
second operand (int)
- class Compiler.instructions.shrc(*args, **kwargs)[source]¶
Bitwise right shift of clear register (vector).
- Param
result (cint)
- Param
first operand (cint)
- Param
second operand (cint)
- class Compiler.instructions.shrci(*args, **kwargs)[source]¶
Bitwise right shift of clear register (vector) by (constant) immediate value.
- Param
result (cint)
- Param
first operand (cint)
- Param
second operand (int)
- class Compiler.instructions.shrsi(*args, **kwargs)[source]¶
Bitwise right shift of secret register (vector) by (constant) immediate value. This only makes sense in connection with protocols allowing local share conversion (i.e., based on additive secret sharing modulo a power of two). Moreover, the result is not a secret sharing of the right shift of the secret value but needs to be corrected using the overflow. This is explained by Dalskov et al. in the appendix.
- Param
result (sint)
- Param
first operand (sint)
- Param
second operand (int)
- class Compiler.instructions.shuffle(*args, **kwargs)[source]¶
Randomly shuffles clear integer vector with public randomness.
- Param
destination (regint)
- Param
source (regint)
- class Compiler.instructions.square(*args, **kwargs)[source]¶
Store fresh random square(s) in secret register (vectors).
- Param
value (sint)
- Param
square (sint)
- class Compiler.instructions.starg(*args, **kwargs)[source]¶
Copy clear integer register to the thread argument.
- Param
source (regint)
- class Compiler.instructions.stmc(*args, **kwargs)[source]¶
Assign clear register (vector) to clear memory value(s) by immediate address. The vectorized version starts at the base address and then iterates the memory address.
- Param
source (cint)
- Param
memory address base (int)
- class Compiler.instructions.stmci(*args, **kwargs)[source]¶
Assign clear register (vector) to clear memory value(s) by register address. The vectorized version starts at the base address and then iterates the memory address.
- Param
source (cint)
- Param
memory address base (regint)
- class Compiler.instructions.stmint(*args, **kwargs)[source]¶
Assign clear integer register (vector) to clear integer memory value(s) by immediate address. The vectorized version starts at the base address and then iterates the memory address.
- Param
source (regint)
- Param
memory address base (int)
- class Compiler.instructions.stminti(*args, **kwargs)[source]¶
Assign clear integer register (vector) to clear integer memory value(s) by register address. The vectorized version starts at the base address and then iterates the memory address.
- Param
source (regint)
- Param
memory address base (regint)
- class Compiler.instructions.stms(*args, **kwargs)[source]¶
Assign secret register (vector) to secret memory value(s) by immediate address. The vectorized version starts at the base address and then iterates the memory address.
- Param
source (sint)
- Param
memory address base (int)
- class Compiler.instructions.stmsi(*args, **kwargs)[source]¶
Assign secret register (vector) to secret memory value(s) by register address. The vectorized version starts at the base address and then iterates the memory address.
- Param
source (sint)
- Param
memory address base (regint)
- class Compiler.instructions.subc(*args, **kwargs)[source]¶
Clear subtraction.
- Param
result (cint)
- Param
first operand (cint)
- Param
second operand (cint)
- class Compiler.instructions.subcfi(*args, **kwargs)[source]¶
Subtraction of clear register (vector) from (constant) immediate value.
- Param
result (cint)
- Param
first operand (int)
- Param
second operand (cint)
- class Compiler.instructions.subci(*args, **kwargs)[source]¶
Subtraction of (constant) immediate value from clear register (vector).
- Param
result (cint)
- Param
first operand (cint)
- Param
second operand (int)
- class Compiler.instructions.subint(*args, **kwargs)[source]¶
Clear integer register (vector) subtraction.
- Param
result (regint)
- Param
first operand (regint)
- Param
second operand (regint)
- op(b, /)¶
Same as a - b.
- class Compiler.instructions.subml(*args, **kwargs)[source]¶
Subtract clear from secret value.
- Param
result (sint)
- Param
first operand (sint)
- Param
second operand (cint)
- class Compiler.instructions.submr(*args, **kwargs)[source]¶
Subtract secret from clear value.
- Param
result (sint)
- Param
first operand (cint)
- Param
second operand (sint)
- class Compiler.instructions.subs(*args, **kwargs)[source]¶
Secret subtraction.
- Param
result (sint)
- Param
first operand (sint)
- Param
second operand (sint)
- class Compiler.instructions.subsfi(*args, **kwargs)[source]¶
Subtraction of secret register (vector) from (constant) immediate value.
- Param
result (sint)
- Param
first operand (int)
- Param
second operand (sint)
- class Compiler.instructions.subsi(*args, **kwargs)[source]¶
Subtraction of (constant) immediate value from secret register (vector).
- Param
result (sint)
- Param
first operand (sint)
- Param
second operand (int)
- class Compiler.instructions.threshold(*args, **kwargs)[source]¶
Store maximal number of corrupt players in clear integer register.
- Param
destination (regint)
- class Compiler.instructions.triple(*args, **kwargs)[source]¶
Store fresh random triple(s) in secret register (vectors).
- Param
factor (sint)
- Param
factor (sint)
- Param
product (sint)
- class Compiler.instructions.trunc_pr(*args, **kwargs)[source]¶
Probabilistic truncation if supported by the protocol.
- Param
number of arguments to follow (multiple of four)
- Param
destination (sint)
- Param
source (sint)
- Param
bit length of source (int)
- Param
number of bits to truncate (int)
- class Compiler.instructions.use(*args, **kwargs)[source]¶
Offline data usage. Necessary to avoid reusage while using preprocessing from files. Also used to multithreading for expensive preprocessing.
- Param
domain (0: integer, 1: \(\mathrm{GF}(2^n)\), 2: bit)
- Param
type (0: triple, 1: square, 2: bit, 3: inverse, 6: daBit)
- Param
number (int, -1 for unknown)
- class Compiler.instructions.use_edabit(*args, **kwargs)[source]¶
edaBit usage. Necessary to avoid reusage while using preprocessing from files. Also used to multithreading for expensive preprocessing.
- Param
loose/strict (0/1)
- Param
length (int)
- Param
number (int, -1 for unknown)
- class Compiler.instructions.use_inp(*args, **kwargs)[source]¶
Input usage. Necessary to avoid reusage while using preprocessing from files.
- Param
domain (0: integer, 1: \(\mathrm{GF}(2^n)\), 2: bit)
- Param
input player (int)
- Param
number (int, -1 for unknown)
- class Compiler.instructions.use_matmul(*args, **kwargs)[source]¶
Matrix multiplication usage. Used for multithreading of preprocessing.
- Param
number of left-hand rows (int)
- Param
number of left-hand columns/right-hand rows (int)
- Param
number of right-hand columns (int)
- Param
number (int, -1 for unknown)
- class Compiler.instructions.use_prep(*args, **kwargs)[source]¶
Custom preprocessed data usage.
- Param
tag (16 bytes / 4 units, cut off at first zero byte)
- Param
number of items to use (int, -1 for unknown)
Write shares to
Persistence/Transactions-P<playerno>.data
(appending at the end).- Param
number of arguments to follow / number of shares plus one (int)
- Param
position (regint, -1 for appending)
- Param
source (sint)
- Param
(repeat from source)…
- class Compiler.instructions.writesockets(*args, **kwargs)[source]¶
Write a variable number of secret shares (potentially with MAC) from registers into a socket for a specified client id. If the protocol uses MACs, the client should be different for every party.
- Param
client id (regint)
- Param
message type (must be 0)
- Param
vector size (int)
- Param
source (sint)
- Param
(repeat source)…
Write a variable number of shares (without MACs) from secret registers into socket for a specified client id.
- Param
client id (regint)
- Param
message type (must be 0)
- Param
vector size (int)
- Param
source (sint)
- Param
(repeat source)…
Compiler.GC.instructions module¶
This module constrains instructions for binary circuits. Unlike arithmetic instructions, they generally do not use the vector size in the instruction code field. Instead the number of bits affected is given as an extra argument. Also note that a register holds 64 values instead of just one as is the case for arithmetic instructions. Therefore, an instruction for 65-128 bits will affect two registers etc. Similarly, a memory cell holds 64 bits.
- class Compiler.GC.instructions.addcb(*args, **kwargs)[source]¶
Integer addition two single clear bit registers.
- Param
result (cbit)
- Param
summand (cbit)
- Param
summand (cbit)
- class Compiler.GC.instructions.addcbi(*args, **kwargs)[source]¶
Integer addition single clear bit register and immediate.
- Param
result (cbit)
- Param
summand (cbit)
- Param
summand (int)
- class Compiler.GC.instructions.andm(*args, **kwargs)[source]¶
Bitwise AND of single secret and clear bit registers.
- Param
number of bits (less or equal 64)
- Param
result (sbit)
- Param
operand (sbit)
- Param
operand (cbit)
- class Compiler.GC.instructions.andrs(*args, **kwargs)[source]¶
Constant-vector AND of secret bit registers.
- Param
number of arguments to follow (multiple of four)
- Param
number of bits (int)
- Param
result vector (sbit)
- Param
vector operand (sbit)
- Param
single operand (sbit)
- Param
(repeat from number of bits)…
- class Compiler.GC.instructions.ands(*args, **kwargs)[source]¶
Bitwise AND of secret bit register vector.
- Param
number of arguments to follow (multiple of four)
- Param
number of bits (int)
- Param
result (sbit)
- Param
operand (sbit)
- Param
operand (sbit)
- Param
(repeat from number of bits)…
- class Compiler.GC.instructions.bitb(*args, **kwargs)[source]¶
Copy fresh secret random bit to secret bit register.
- Param
destination (sbit)
- class Compiler.GC.instructions.bitcoms(*args, **kwargs)[source]¶
Secret bit register decomposition.
- Param
number of arguments to follow / number of bits plus one (int)
- Param
destination (sbit)
- Param
source for least significant bit (sbit)
- Param
(source for one bit higher)…
- class Compiler.GC.instructions.bitdecc(*args, **kwargs)[source]¶
Secret bit register decomposition.
- Param
number of arguments to follow / number of bits plus one (int)
- Param
source (sbit)
- Param
destination for least significant bit (sbit)
- Param
(destination for one bit higher)…
- class Compiler.GC.instructions.bitdecs(*args, **kwargs)[source]¶
Secret bit register decomposition.
- Param
number of arguments to follow / number of bits plus one (int)
- Param
source (sbit)
- Param
destination for least significant bit (sbit)
- Param
(destination for one bit higher)…
- class Compiler.GC.instructions.cond_print_strb(cond, val)[source]¶
Conditionally output four bytes.
- Param
condition (cbit, no output if zero)
- Param
four bytes (int)
- class Compiler.GC.instructions.convcbit(*args, **kwargs)[source]¶
Copy clear bit register to clear integer register.
- Param
destination (regint)
- Param
source (cbit)
- class Compiler.GC.instructions.convcbit2s(*args, **kwargs)[source]¶
Copy clear bit register vector to secret bit register vector.
- Param
number of bits (int)
- Param
destination (sbit)
- Param
source (cbit)
- class Compiler.GC.instructions.convcbitvec(*args)[source]¶
Copy clear bit register vector to clear register by bit. This means that every element of the destination register vector will hold one bit.
- Param
number of bits / vector length (int)
- Param
destination (regint)
- Param
source (cbit)
- class Compiler.GC.instructions.convcint(*args, **kwargs)[source]¶
Copy clear integer register to clear bit register.
- Param
number of bits (int)
- Param
destination (cbit)
- Param
source (regint)
- class Compiler.GC.instructions.convcintvec(*args, **kwargs)[source]¶
Copy clear register vector by bit to clear bit register vectors. This means that the first destination will hold the least significant bits of all inputs etc.
- Param
number of arguments to follow / number of bits plus one (int)
- Param
source (cint)
- Param
destination for least significant bits (sbit)
- Param
(destination for bits one step higher)…
- class Compiler.GC.instructions.convsint(*args, **kwargs)[source]¶
Copy clear integer register to secret bit register.
- Param
number of bits (int)
- Param
destination (sbit)
- Param
source (regint)
- class Compiler.GC.instructions.inputb(*args, **kwargs)[source]¶
Copy private input to secret bit register vectors. The input is read as floating-point number, multiplied by a power of two, and then rounded to an integer.
- Param
number of arguments to follow (multiple of four)
- Param
player number (int)
- Param
number of bits in output (int)
- Param
exponent to power of two factor (int)
- Param
destination (sbit)
- class Compiler.GC.instructions.inputbvec(*args, **kwargs)[source]¶
Copy private input to secret bit registers bit by bit. The input is read as floating-point number, multiplied by a power of two, rounded to an integer, and then decomposed into bits.
- Param
total number of arguments to follow (int)
- Param
number of arguments to follow for one input / number of bits plus three (int)
- Param
exponent to power of two factor (int)
- Param
player number (int)
- Param
destination for least significant bit (sbit)
- Param
(destination for one bit higher)…
- Param
(repeat from number of arguments to follow for one input)…
- class Compiler.GC.instructions.ldbits(*args, **kwargs)[source]¶
Store immediate in secret bit register.
- Param
destination (sbit)
- Param
number of bits (int)
- Param
immediate (int)
- class Compiler.GC.instructions.ldmcb(*args, **kwargs)[source]¶
Copy clear bit memory cell with compile-time address to clear bit register.
- Param
destination (cbit)
- Param
memory address (int)
- class Compiler.GC.instructions.ldmcbi(*args, **kwargs)[source]¶
Copy clear bit memory cell with run-time address to clear bit register.
- Param
destination (cbit)
- Param
memory address (regint)
- class Compiler.GC.instructions.ldmsb(*args, **kwargs)[source]¶
Copy secret bit memory cell with compile-time address to secret bit register.
- Param
destination (sbit)
- Param
memory address (int)
- class Compiler.GC.instructions.ldmsbi(*args, **kwargs)[source]¶
Copy secret bit memory cell with run-time address to secret bit register.
- Param
destination (sbit)
- Param
memory address (regint)
- class Compiler.GC.instructions.movsb(*args, **kwargs)[source]¶
Copy secret bit register.
- Param
destination (sbit)
- Param
source (sbit)
- class Compiler.GC.instructions.mulcbi(*args, **kwargs)[source]¶
Integer multiplication single clear bit register and immediate.
- Param
result (cbit)
- Param
factor (cbit)
- Param
factor (int)
- class Compiler.GC.instructions.notcb(*args, **kwargs)[source]¶
Bitwise NOT of secret register vector.
- Param
number of bits
- Param
result (cbit)
- Param
operand (cbit)
- class Compiler.GC.instructions.nots(*args, **kwargs)[source]¶
Bitwise NOT of secret register vector.
- Param
number of bits (less or equal 64)
- Param
result (sbit)
- Param
operand (sbit)
- class Compiler.GC.instructions.print_float_plainb(*args, **kwargs)[source]¶
Output floating-number from clear bit registers.
- Param
significand (cbit)
- Param
exponent (cbit)
- Param
zero bit (cbit, zero output if bit is one)
- Param
sign bit (cbit, negative output if bit is one)
- Param
NaN (cbit, regular number if zero)
- class Compiler.GC.instructions.print_reg_plainb(*args, **kwargs)[source]¶
Output clear bit register.
- Param
source (cbit)
- class Compiler.GC.instructions.print_reg_signed(*args, **kwargs)[source]¶
Signed output of clear bit register.
- Param
bit length (int)
- Param
source (cbit)
- class Compiler.GC.instructions.print_regb(reg, comment='')[source]¶
Debug output of clear bit register.
- Param
source (cbit)
- Param
comment (4 bytes / 1 unit)
- class Compiler.GC.instructions.reveal(*args, **kwargs)[source]¶
Reveal secret bit register vectors and copy result to clear bit register vectors.
- Param
number of arguments to follow (multiple of three)
- Param
number of bits (int)
- Param
destination (cbit)
- Param
source (sbit)
- Param
(repeat from number of bits)…
- class Compiler.GC.instructions.shlcbi(*args, **kwargs)[source]¶
Left shift of clear bit register by immediate.
- Param
destination (cbit)
- Param
source (cbit)
- Param
number of bits to shift (int)
- class Compiler.GC.instructions.shrcbi(*args, **kwargs)[source]¶
Right shift of clear bit register by immediate.
- Param
destination (cbit)
- Param
source (cbit)
- Param
number of bits to shift (int)
- class Compiler.GC.instructions.split(*args, **kwargs)[source]¶
Local share conversion. This instruction use the vector length in the instruction code field.
- Param
number of arguments to follow (number of bits times number of additive shares plus one)
- Param
source (sint)
- Param
first share of least significant bit
- Param
second share of least significant bit
- Param
(remaining share of least significant bit)…
- Param
(repeat from first share for bit one step higher)…
- class Compiler.GC.instructions.stmcb(*args, **kwargs)[source]¶
Copy clear bit register to clear bit memory cell with compile-time address.
- Param
source (cbit)
- Param
memory address (int)
- class Compiler.GC.instructions.stmcbi(*args, **kwargs)[source]¶
Copy clear bit register to clear bit memory cell with run-time address.
- Param
source (cbit)
- Param
memory address (regint)
- class Compiler.GC.instructions.stmsb(*args, **kwargs)[source]¶
Copy secret bit register to secret bit memory cell with compile-time address.
- Param
source (sbit)
- Param
memory address (int)
- class Compiler.GC.instructions.stmsbi(*args, **kwargs)[source]¶
Copy secret bit register to secret bit memory cell with run-time address.
- Param
source (sbit)
- Param
memory address (regint)
- class Compiler.GC.instructions.trans(*args)[source]¶
Secret bit register vector transpose. The first destination vector will contain the least significant bits of all source vectors etc.
- Param
number of arguments to follow (int)
- Param
number of outputs (int)
- Param
destination for least significant bits (sbit)
- Param
(destination for bits one step higher)…
- Param
source (sbit)
- Param
(source)…
- class Compiler.GC.instructions.xorcb(*args, **kwargs)[source]¶
Bitwise XOR of two single clear bit registers.
- Param
result (cbit)
- Param
operand (cbit)
- Param
operand (cbit)
- class Compiler.GC.instructions.xorcbi(*args, **kwargs)[source]¶
Bitwise XOR of single clear bit register and immediate.
- Param
result (cbit)
- Param
operand (cbit)
- Param
immediate (int)
Low-Level Interface¶
In the following we will explain the basic of the C++ interface by
walking trough Utils/paper-example.cpp
.
template<class T>
void run(char** argv, int prime_length);
MP-SPDZ heavily uses templating to allow to reuse code between
different protocols. run()
is a simple example of this. The
entire virtual machine in the Processor
directory is built on
the same principle. The central type is a type representing a share in
a particular type.
// bit length of prime
const int prime_length = 128;
// compute number of 64-bit words needed
const int n_limbs = (prime_length + 63) / 64;
Computation modulo a prime requires to fix the number of limbs (64-bit words) at compile time. This allows for optimal memory usage and computation.
if (protocol == "MASCOT")
run<Share<gfp_<0, n_limbs>>>(argv, prime_length);
else if (protocol == "CowGear")
run<CowGearShare<gfp_<0, n_limbs>>>(argv, prime_length);
Share types for computation module a prime (and in
\(\mathrm{GF}(2^n)\)) generally take one parameter for the
computation domain. gfp_
in turn takes two parameters, a
counter and the number of limbs. The counter allows to use several
instances with different parameters. It can be chosen freely, but the
convention is to use 0 for the online phase and 1 for the offline
phase where required.
else if (protocol == "SPDZ2k")
run<Spdz2kShare<64, 64>>(argv, 0);
Share types for computation modulo a power of two simply take the exponent as parameter, and some take an additional security parameter.
int my_number = atoi(argv[1]);
int n_parties = atoi(argv[2]);
int port_base = 9999;
Names N(my_number, n_parties, "localhost", port_base);
All implemented protocols require point-to-point connections between
all parties. Names
objects represent a setup of hostnames and
IPs used to set up the actual
connections. The chosen initialization provides a way where
every party connects to party 0 on a specified location (localhost in
this case), which then broadcasts the locations of all parties. The
base port number is used to derive the port numbers for the parties to
listen on (base + party number). See the the Names
class for
other possibilities such as a text file containing hostname and port
number for each party.
CryptoPlayer P(N);
The networking setup is used to set up the actual
connections. CryptoPlayer
uses encrypted connection while
PlainPlayer
does not. If you use several instances (for
several threads for example), you must use an integer identifier as
the second parameter, which must differ from any other by at least the
number of parties.
ProtocolSetup<T> setup(P, prime_length);
We have to use a specific prime for computation modulo a prime. This deterministically generates one of the desired length if necessary. For computation modulo a power of two, this does not do anything. Some protocols use an information-theoretic tag that is constant throughout the protocol. This code reads it from storage if available or generates a fresh one otherwise.
ProtocolSet<T> set(P, setup);
auto& input = set.input;
auto& protocol = set.protocol;
auto& output = set.output;
The ProtocolSet
contains one instance for every essential
protocol step.
int n = 1000;
vector<T> a(n), b(n);
T c;
typename T::clear result;
Remember that T
stands for a share in the protocol. The
derived type T::clear
stands for the cleartext domain. Share
types support linear operations such as addition, subtraction, and
multiplication with a constant. Use T::constant()
to convert a
constant to a share type.
input.reset_all(P);
for (int i = 0; i < n; i++)
input.add_from_all(i);
input.exchange();
for (int i = 0; i < n; i++)
{
a[i] = input.finalize(0);
b[i] = input.finalize(1);
}
The interface for all protocols proceeds in four stages:
Initialization. This is required to initialize and reset data structures in consecutive use.
Local data preparation
Communication
Output extraction
This blueprint allows for a minimal number of communication rounds.
protocol.init_dotprod(&processor);
for (int i = 0; i < n; i++)
protocol.prepare_dotprod(a[i], b[i]);
protocol.next_dotprod();
protocol.exchange();
c = protocol.finalize_dotprod(n);
The initialization of the multiplication sets the preprocessing and
output instances to use in Beaver multiplication. next_dotprod()
separates dot products in the data preparation phase.
protocol.check();
Some protocols require a check of all multiplications up to a certain point. To guarantee that outputs do not reveal secret information, it has to be run before using the output protocol.
output.init_open(P);
output.prepare_open(c);
output.exchange(P);
result = output.finalize_open();
cout << "result: " << result << endl;
output.Check(P);
The output protocol follows the same blueprint as the multiplication protocol.
T::LivePrep::teardown();
This frees the memory used for global key material when using homomorphic encryption. Otherwise, this does not do anything.
Domain Types¶
|
Computation modulo a prime. |
|
Computation modulo \(2^K\). This is not a field. |
|
\(GF(2^n)\). |
Protocol Setup¶
-
template<class T>
class ProtocolSetup¶ Global setup for an arithmetic share type
Subclassed by MixedProtocolSetup< T >
-
template<class T>
class ProtocolSet¶ Input, multiplication, and output protocol instance for an arithmetic share type
Public Functions
-
inline ProtocolSet(Player &P, const ProtocolSetup<T> &setup)¶
- Parameters
P – communication instance
setup – one-time setup instance
-
inline void check()¶
Run all protocol checks
-
inline ProtocolSet(Player &P, const ProtocolSetup<T> &setup)¶
-
template<class T>
class BinaryProtocolSetup¶ Global setup for a binary share type
-
template<class T>
class BinaryProtocolSet¶ Input, multiplication, and output protocol instance for a binary share type
Public Functions
-
inline BinaryProtocolSet(Player &P, const BinaryProtocolSetup<T> &setup)¶
- Parameters
P – communication instance
setup – one-time setup instance
-
inline void check()¶
Run all protocol checks
-
inline BinaryProtocolSet(Player &P, const BinaryProtocolSetup<T> &setup)¶
-
template<class T>
class MixedProtocolSetup : public ProtocolSetup<T>¶ Global setup for an arithmetic share type and the corresponding binary one
-
template<class T>
class MixedProtocolSet¶ Input, multiplication, and output protocol instance for an arithmetic share type and the corresponding binary one
Public Functions
-
inline MixedProtocolSet(Player &P, const MixedProtocolSetup<T> &setup)¶
- Parameters
P – communication instance
setup – one-time setup instance
-
inline void check()¶
Run all protocol checks
-
inline MixedProtocolSet(Player &P, const MixedProtocolSetup<T> &setup)¶
Protocol Interfaces¶
-
template<class T>
class ProtocolBase¶ Abstract base class for multiplication protocols
Subclassed by Replicated< T >
Public Functions
-
inline virtual void init(Preprocessing<T>&, typename T::MAC_Check&)¶
Initialize protocol if needed (repeated call possible)
-
virtual void init_mul() = 0¶
Initialize multiplication round.
-
virtual void prepare_mul(const T &x, const T &y, int n = -1) = 0¶
Schedule multiplication of operand pair.
-
virtual void exchange() = 0¶
Run multiplication protocol.
-
inline void init_dotprod()¶
Initialize dot product round.
-
inline void next_dotprod()¶
Finish dot product.
-
inline virtual void init(Preprocessing<T>&, typename T::MAC_Check&)¶
-
template<class T>
class InputBase¶ Abstract base for input protocols
Subclassed by Input< T >
Public Functions
-
virtual void reset(int player) = 0¶
Initialize input round for
player
-
virtual void add_mine(const typename T::open_type &input, int n_bits = -1) = 0¶
Schedule input from me.
-
virtual void add_other(int player, int n_bits = -1) = 0¶
Schedule input from other player.
-
void add_from_all(const typename T::open_type &input, int n_bits = -1)¶
Schedule input from all players.
-
virtual void exchange()¶
Run input protocol for all players.
-
virtual void reset(int player) = 0¶
-
template<class T>
class MAC_Check_Base¶ Abstract base class for opening protocols
-
template<class T>
class Preprocessing : public PrepBase¶ Abstract base class for preprocessing
Subclassed by BufferPrep< T >, Sub_Data_Files< T >
-
template<class T>
class BufferPrep : public Preprocessing<T>¶ Abstract base class for live preprocessing
Subclassed by BitPrep< T >
Machine Learning¶
MP-SPDZ supports a limited subset of the Keras interface for machine learning. This includes the SGD and Adam optimizers and the following layer types: dense, 2D convolution, 2D max-pooling, and dropout.
In the following we will walk through the example code in
keras_mnist_dense.mpc
, which trains a dense neural network for
MNIST. It starts by defining tensors to hold data:
training_samples = sfix.Tensor([60000, 28, 28])
training_labels = sint.Tensor([60000, 10])
test_samples = sfix.Tensor([10000, 28, 28])
test_labels = sint.Tensor([10000, 10])
The tensors are then filled with inputs from party 0 in the order that is used by the preparation script:
training_labels.input_from(0)
training_samples.input_from(0)
test_labels.input_from(0)
test_samples.input_from(0)
This is followed by Keras-like code setting up the model and training it:
from Compiler import ml
tf = ml
layers = [
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
]
model = tf.keras.models.Sequential(layers)
optim = tf.keras.optimizers.SGD(momentum=0.9, learning_rate=0.01)
model.compile(optimizer=optim)
opt = model.fit(
training_samples,
training_labels,
epochs=1,
batch_size=128,
validation_data=(test_samples, test_labels)
)
Lastly, the model is stored on disk in secret-shared form:
for var in model.trainable_variables:
var.write_to_file()
Prediction¶
The example code in keras_mnist_dense_predict.mpc
uses the model
stored above for prediction. Much of the setup is the same, but
instead of training it reads the model from disk:
model.build(test_samples.sizes)
start = 0
for var in model.trainable_variables:
start = var.read_from_file(start)
Then it runs the prediction:
guesses = model.predict(test_samples)
Using var.input_from(player)
instead the model would be input
privately by a party.
Networking¶
All protocols in MP-SPDZ rely on point-to-point connections between
all pairs of parties. This is realized using TCP, which means that
every party must be reachable under at least one TCP port. The default
is to set this port to a base plus the player number. This allows for
easily running all parties on the same host. The base defaults to 5000,
which can be changed with the command-line option
--portnumbase
. However, the scripts in Scripts
use a random
base port number, which can be changed using the same option.
There are two ways of communicating hosts and individually setting ports:
All parties first to connect to a coordination server, which broadcasts the data for all parties. This is the default with the coordination server being run as a thread of party 0. The hostname of the coordination server has to be given with the command-line parameter
--hostname
, and the coordination server runs on the base port number, thus defaulting to 5000. Furthermore, you can specify a party’s listening port using--my-port
.The parties read the information from a local file, which needs to be the same everywhere. The file can be specified using
--ip-file-name
and has the following format:<host0>[:<port0>] <host1>[:<port1>] ...
The hosts can be both hostnames and IP addresses. If not given, the ports default to base plus party number.
Whether or not encrypted connections are used depends on the security
model of the protocol. Honest-majority protocols default to encrypted
whereas dishonest-majority protocols default to unencrypted. You
change this by either using --encrypted/-e
or
--unencrypted/-u
.
If using encryption, the certificates (Player-Data/*.pem
) must be
the same on all hosts, and you have to run c_rehash Player-Data
on
all of them. Scripts/setup-ssl.sh
can be used to generate the
necessary certificates. The common name has to be P<player number>
for computing parties and C<client number>
for clients.
Internal Infrastructure¶
The internal networking infrastructure of MP-SPDZ reflects the needs of the various multi-party computation. For example, some protocols require a simultaneous broadcast from all parties whereas other protocols require that every party sends different information to different parties (include none at all). The infrastructure makes sure to send and receive in parallel whenever possible.
All communication is handled through two subclasses of Player
defined in Networking/Player.h
. PlainPlayer
communicates
in cleartext while CryptoPlayer
uses TLS encryption. The
former uses the same BSD socket for sending and receiving but the
latter uses two different connections for sending and receiving. This
is because TLS communication is never truly one-way due key renewals
etc., so the only way for simultaneous sending and receiving we found
was to use two connections in two threads.
If you wish to use a different networking facility, we recommend to
subclass Player
and fill in the virtual-only functions
required by the compiler (e.g., send_to_no_stats()
for
sending to one other party). Note that not all protocols require all
functions, so you only need to properly implement those you need. You
can then replace uses of PlainPlayer
or
CryptoPlayer
by your own class. Furthermore, you might
need to extend the Names
class to suit your purpose. By
default, Names
manages one TCP port that a party is
listening on for connections. If this suits you, you don’t need to
change anything
Reference¶
-
class Names¶
Network setup (hostnames and port numbers)
Public Functions
-
void init(int player, int pnb, int my_port, const char *servername, bool setup_socket = true)¶
Initialize with central server
- Parameters
player – my number
pnb – base port number (server listens one below)
my_port – my port number (
DEFAULT_PORT
for default, which is base port number plus player number)servername – location of server
setup_socket – whether to start listening
-
inline Names(int player, int pnb, int my_port, const char *servername)¶
-
Names(int player, int nplayers, const string &servername, int pnb, int my_port = DEFAULT_PORT)¶
Initialize with central server running on player 0
- Parameters
player – my number
nplayers – number of players
servername – location of player 0
pnb – base port number
my_port – my port number (
DEFAULT_PORT
for default, which is base port number plus player number)
-
void init(int player, int pnb, vector<string> Nms)¶
Initialize without central server
- Parameters
player – my number
pnb – base port number
Nms – locations of all parties
-
inline Names(int player, int pnb, vector<string> Nms)¶
-
void init(int player, int pnb, const string &hostsfile, int players = 0)¶
Initialize from file. One party per line, format
<hostname>[:<port>]
- Parameters
player – my number
pnb – base port number
hostsfile – filename
players – number of players (0 to take from file)
-
inline Names(int player, int pnb, const string &hostsfile)¶
-
Names(ez::ezOptionParser &opt, int argc, const char **argv, int default_nplayers = 2)¶
Initialize from command-line options
- Parameters
opt – option parser instance
argc – number of command-line arguments
argv – command-line arguments
default_nplayers – default number of players (used if not given in arguments)
-
inline Names()¶
-
~Names()¶
-
inline int num_players() const¶
-
inline int my_num() const¶
-
inline const string get_name(int i) const¶
-
inline int get_portnum_base() const¶
Public Static Attributes
-
static const int DEFAULT_PORT = -1¶
-
void init(int player, int pnb, int my_port, const char *servername, bool setup_socket = true)¶
-
class Player : public PlayerBase¶
Abstract class for multi-player communication.
*_no_stats
functions are called by their equivalents after accounting for communications statistics.Subclassed by MultiPlayer< T >, MultiPlayer< int >, MultiPlayer< ssl_socket *>
Public Functions
-
inline virtual int num_players() const¶
Get number of players
-
inline virtual int my_num() const¶
Get my player number
-
virtual void send_all(const octetStream &o) const¶
Send the same to all other players
-
void send_to(int player, const octetStream &o) const¶
Send to a specific player
-
void receive_all(vector<octetStream> &os) const¶
Receive from all other players. Information from player 0 at
os[0]
etc.
-
void receive_player(int i, octetStream &o) const¶
Receive from a specific player
-
void send_relative(const vector<octetStream> &o) const¶
Send to all other players by offset.
o[0]
gets sent to the next player etc.
-
void receive_relative(vector<octetStream> &o) const¶
Receive from all other players by offset.
o[0]
will contain data from the next player etc.
-
void receive_relative(int offset, octetStream &o) const¶
Receive from other player specified by offset. 1 stands for the next player etc.
-
void exchange(int other, const octetStream &to_send, octetStream &ot_receive) const¶
Exchange information with one other party, reusing the buffer if possible.
-
void exchange(int other, octetStream &o) const¶
Exchange information with one other party, reusing the buffer.
-
void exchange_relative(int offset, octetStream &o) const¶
Exchange information with one other party specified by offset, reusing the buffer if possible.
-
inline virtual void pass_around(octetStream &o, int offset = 1) const¶
Send information to a party while receiving from another by offset, The default is to send to the next party while receiving from the previous. The buffer is reused.
-
void pass_around(octetStream &to_send, octetStream &to_receive, int offset) const¶
Send information to a party while receiving from another by offset. The default is to send to the next party while receiving from the previous.
-
virtual void unchecked_broadcast(vector<octetStream> &o) const¶
Broadcast and receive data to/from all players. Assumes o[player_no] contains the data to be broadcast by me.
-
virtual void Broadcast_Receive(vector<octetStream> &o) const¶
Broadcast and receive data to/from all players with eventual verification. Assumes o[player_no] contains the data to be broadcast by me.
-
virtual void Check_Broadcast() const¶
Run protocol to verify broadcast is correct
-
void send_receive_all(const vector<octetStream> &to_send, vector<octetStream> &to_receive) const¶
Send something different to each player.
-
void send_receive_all(const vector<bool> &senders, const vector<octetStream> &to_send, vector<octetStream> &to_receive) const¶
Specified senders only send something different to each player.
- Parameters
senders – set whether a player sends or not, must be equal on all players
to_send – data to send by player number
to_receive – received data by player number
-
void send_receive_all(const vector<vector<bool>> &channels, const vector<octetStream> &to_send, vector<octetStream> &to_receive) const¶
Send something different only one specified channels.
- Parameters
channels –
channel[i][j]
indicates whether partyi
sends to partyj
to_send – data to send by player number
to_receive – received data by player number
-
virtual void partial_broadcast(const vector<bool> &senders, const vector<bool> &receivers, vector<octetStream> &os) const¶
Specified senders broadcast information to specified receivers.
- Parameters
senders – specify which parties do send
receivers – specify which parties do send
os – data to send at
os[my_number]
, received data elsewhere
-
inline virtual int num_players() const¶
-
template<class T>
class MultiPlayer : public Player¶ Multi-player communication helper class.
T = int
for unencrypted BSD sockets andT = ssl_socket*
for Boost SSL streams.
-
class PlainPlayer : public MultiPlayer<int>¶
Plaintext multi-player communication
Subclassed by ThreadPlayer
-
class CryptoPlayer : public MultiPlayer<ssl_socket*>¶
Encrypted multi-party communication. Uses OpenSSL and certificates issued to “P<player_no>”. Sending and receiving is done in separate threads to allow for bidirectional communication.
Public Functions
-
CryptoPlayer(const Names &Nms, const string &id)¶
Start a new set of encrypted connections.
- Parameters
Nms – network setup
id – unique identifier
-
virtual void partial_broadcast(const vector<bool> &my_senders, const vector<bool> &my_receivers, vector<octetStream> &os) const¶
Specified senders broadcast information to specified receivers.
- Parameters
senders – specify which parties do send
receivers – specify which parties do send
os – data to send at
os[my_number]
, received data elsewhere
-
CryptoPlayer(const Names &Nms, const string &id)¶
-
class octetStream¶
Buffer for network communication with a pointer for sequential reading. When sent over the network or stored in a file, the length is prefixed as eight bytes in little-endian order.
Public Functions
-
inline void resize(size_t l)¶
Increase allocation if needed.
-
void clear()¶
Free memory.
-
octetStream(size_t maxlen)¶
Initial allocation.
-
octetStream(size_t len, const octet *source)¶
Initial buffer.
-
octetStream(const string &other)¶
Initial buffer.
-
inline size_t get_ptr() const¶
Number of bytes already read.
-
inline size_t get_length() const¶
Length.
-
inline size_t get_total_length() const¶
Length including size tag.
-
inline size_t get_max_length() const¶
Allocation.
-
inline octet *get_data() const¶
Data pointer.
-
inline octet *get_data_ptr() const¶
Read pointer.
-
inline bool done() const¶
Whether done reading.
-
inline bool empty() const¶
Whether empty.
-
inline size_t left() const¶
Bytes left to read.
-
string str() const¶
Convert to string.
-
octetStream hash() const¶
Hash content.
-
void concat(const octetStream &os)¶
Append other buffer.
-
inline void reset_read_head()¶
Reset reading.
-
inline void reset_write_head()¶
Set length to zero but keep allocation.
-
inline bool operator==(const octetStream &a) const¶
Equality test.
-
void append_random(size_t num)¶
Append
num
random bytes.
-
inline void append(const octet *x, const size_t l)¶
Append
l
bytes fromx
-
inline void consume(octet *x, const size_t l)¶
Read
l
bytes tox
-
inline void store(unsigned int a)¶
Append 4-byte integer.
-
void store(int a)¶
Append 4-byte integer.
-
inline void get(unsigned int &a)¶
Read 4-byte integer.
-
void get(int &a)¶
Read 4-byte integer.
-
inline void store(size_t a)¶
Append 8-byte integer.
-
inline void get(size_t &a)¶
Read 8-byte integer.
-
inline void store_int(size_t a, int n_bytes)¶
Append integer of
n_bytes
bytes.
-
inline size_t get_int(int n_bytes)¶
Read integer of
n_bytes
bytes.
-
template<int N_BYTES>
inline void store_int(size_t a)¶ Append integer of
N_BYTES
bytes.
-
template<int N_BYTES>
inline size_t get_int()¶ Read integer of
N_BYTES
bytes.
-
void store(const bigint &x)¶
Append big integer.
-
void get(bigint &ans)¶
Read big integer.
-
template<class T>
void get(vector<T> &v, const T &init = {})¶ Read vector of type implementing
unpack
- Parameters
v – results
init – initialization if required
-
template<class T>
void get_no_resize(vector<T> &v)¶ Read vector of type implementing
unpack
if vector already has the right size
-
inline void consume(octetStream &s, size_t l)¶
Read
l
bytes into separate buffer.
-
template<class T>
inline void Receive(T socket_num)¶ Receive on
socket_num
, overwriting current content.
-
void input(istream &s)¶
Input from stream, overwriting current content.
-
void output(ostream &s)¶
Output to stream.
-
template<class T>
inline void exchange(T send_socket, T receive_socket)¶ Send on
socket_num
while receiving onreceiving_socket
, overwriting current content
-
template<class T>
void exchange(T send_socket, T receive_socket, octetStream &receive_stream) const¶ Send this buffer on
socket_num
while receiving toreceive_stream
onreceiving_socket
-
inline void resize(size_t l)¶
Input/Output¶
This section gives an overview over the input/output facilities.
Private Inputs from Computing Parties¶
All secret types have an input function
(e.g. Compiler.types.sint.get_input_from()
or
Compiler.types.sfix.get_input_from()
). Inputs are read as
whitespace-separated text in order (independent of the data type) from
Player-Data/Input-P<player>-<thread>
, where thread
is 0
for
the main thread. You can change the prefix (Player-Data/Input
)
using the -IF
option on the virtual machine binary. You can also
use -I
to read inputs from the command line.
Compiler.types.sint.input_tensor_from()
and
Compiler.types.sfix.input_tensor_from()
allow inputting a
tensor.
Compile-Time Data via Private Input¶
input_tensor_via()
is a convenience
function that allows to use data available at compile-time via
private input.
Public Inputs¶
All types can be assigned a hard-coded value at compile time, e.g.
sint(1)
. This is impractical for larger amounts of
data. foreach_enumerate()
provides a
facility for this case. It uses
public_input
internally, which reads
from Programs/Public-Input/<progname>
.
Public Outputs¶
By default, print_ln()
and related
functions only output to the terminal on party 0. This allows to run
several parties in one terminal without spoiling the output. You can
use interactive mode with option -I
in order to output on all
parties. Note that this also to reading inputs from the command line
unless you specify -IF
as well. You can also specify a file prefix
with -OF
, so that outputs are written to
<prefix>-P<player>-<thread>
.
Private Outputs to Computing Parties¶
Some types provide a function to reveal a value only to a specific
party (e.g., Compiler.types.sint.reveal_to()
). It can be used
conjunction with print_ln_to()
in order to
output it.
Binary Output¶
Most types returned by reveal()
or reveal_to()
feature a binary_output()
method, which writes to
Player-Data/Binary-Output-P<playerno>-<threadno>
. The format is
either signed 64-bit integer or double-precision floating-point in
machine byte order (usually little endian).
Clients (Non-computing Parties)¶
Compiler.types.sint.receive_from_client()
and
Compiler.types.sint.reveal_to_clients()
allow
communicating securely with the clients. See this example
covering both client code and server-side high-level code.
Compiler.types.sint.input_tensor_from_client()
and
Compiler.types.MultiArray.reveal_to_clients()
. The same
functions are available for sfix
and
Array
, respectively.
See also Reference below.
Reference¶
-
class Client¶
Client-side interface
Public Functions
-
Client(const vector<string> &hostnames, int port_base, int my_client_id)¶
Start a new set of connections to computing parties.
- Parameters
hostnames – location of computing parties
port_base – port base
my_client_id – client identifier
Public Members
-
vector<ssl_socket*> sockets¶
Sockets for cleartext communication
-
octetStream specification¶
Specification of computation domain
-
Client(const vector<string> &hostnames, int port_base, int my_client_id)¶
Non-linear Computation¶
While the computation of addition and multiplication varies from protocol, non-linear computation such as comparison in arithmetic domains (modulus other than two) only comes in three flavors throughout MP-SPDZ:
- Unknown prime modulus
This approach goes back to Catrina and de Hoogh. It crucially relies on the use of secret random bits in the arithmetic domain. Enough such bits allow to mask a secret value so that it is secure to reveal the masked value. This can then be split in bits as it is public. The public bits and the secret mask bits are then used to compute a number of non-linear functions. The same idea has been used to implement fixed-point and floating-point computation. We call this method “unknown prime modulus” because it only mandates a minimum modulus size for a given cleartext range, which is roughly the cleartext bit length plus a statistical security parameter. It has the downside that there is implicit enforcement of the cleartext range.
- Known prime modulus
Damgård et al. have proposed non-linear computation that involves an exact prime modulus. We have implemented the refined bit decomposition by Nishide and Ohta, which enables further non-linear computation. Our assumption with this method is that the cleartext space is slightly smaller the full range modulo the prime. This allows for comparison by taking a difference and extracting the most significant bit, which is different than the above works that implement comparison between two positive numbers modulo the prime. We also used an idea by Makri et al., namely that a random \(k\)-bit number is indistinguishable from a random number modulo \(p\) if the latter is close enough to \(2^k\).
- Power-of-two modulus
In the context of non-linear computation, there are two important differences to prime modulus setting:
Multiplication with a power of two effectively erases some of the most significant bits.
There is no right shift using multiplication. Modulo a prime, multiplying with a power of the inverse of two allows to right-shift numbers with enough zeros as least significant bits.
Taking this differences into account, Dalskov et al. have adapted the mask-and-reveal approach above to the setting of computation modulo a power of two.
Mixed-Circuit Computation¶
Another approach to non-linear computation is switching to binary computation for parts of the computation. MP-SPDZ implements protocols proposed for particular security models by a number of works: Demmler et al., Mohassel and Rindal, and Dalskov et al. MP-SPDZ also implements more general methods such as daBits and edaBits.
Protocol Pairs¶
The following table lists the matching arithmetic and binary protocols.
Arithmetic |
Binary |
---|---|
MASCOT, SPDZ2k, LowGear, HighGear, CowGear, ChaiGear |
Tinier with improved cut-and-choose analysis by Furukawa et al. |
Semi, Hemi, Temi, Soho, Semi2k |
SemiBin (Beaver triples modulo 2 using OT) |
Malicious Shamir over \(GF(2^{40})\) for secure sacrificing |
|
Malicious Rep3, Post-Sacrifice, SPDZ-wise replicated |
|
Rep4 modulo 2 |
|
Shamir over \(GF(2^8)\) |
|
ATLAS over \(GF(2^8)\) |
|
Rep3 |
Preprocessing¶
Many protocols in MP-SPDZ use preprocessing, that is, producing secret shares that are independent of the actual data but help with the computation. Due to the independence, this can be done in batches to save communication rounds and even communication when using homomorphic encryption that works with large vectors such as LWE-based encryption.
Generally, preprocessing is done on demand and per computation
threads. On demand means that batches of preprocessing data are
computed whenever there is none in storage, and a computation thread
is a thread created by control flow instructions such as
for_range_multithread()
.
The exceptions to the general rule are edaBit generation with malicious security and AND triples with malicious security and honest majority, both when using bucket size three. Bucket size three implies batches of over a million to achieve 40-bit statistical security, and in honest-majority binary computation the item size is 64, which makes the actual batch size 64 million triples. In multithreaded programs, the preprocessing is run centrally using the threads as helpers.
The batching means that the cost in terms of time and communication
jump whenever another batch is generated. Note that, while some
protocols are flexible with the batch size and can thus be controlled
using -b
, others mandate a batch size, which can be as large as a
million.
Separate preprocessing¶
It is possible to separate out the preprocessing from the
input-dependent (“online”) phase. This is done by either option -F
or -f
on the virtual machines. In both cases, the preprocessing
data is read from files, either all data per type from a single file
(-F
) or one file per thread (-f
). The latter allows to use
named pipes.
The file name depends on the protocol and the computation domain. It
is generally <prefix>/<number of players>-<protocol
shorthand>-<domain length>/<preprocessing type>-<protocol
shorthand>-P<player number>[-T<thread number>]
. For example, the
triples for party 1 in SPDZ modulo a 128-bit prime can be found in
Player-Data/2-p-128/Triples-p-P1
. The protocol shorthand can be
found by calling <share type>::type_short()
. See
Share Types for a description of the share types.
Preprocessing files start with a header describing the protocol and computation domain to avoid errors due to mismatches. The header is as follows:
Length to follow (little-endian 8-byte number)
Protocol descriptor
Domain descriptor
The protocol descriptor is defined by <share
type>::type_string()
. For SPDZ modulo a prime it is SPDZ gfp
.
The domain descriptor depends on the kind of domain:
- Modulo a prime
Serialization of the prime
Sign bit (0 as 1 byte)
Length to follow (little-endian 4-byte number)
Prime (big-endian)
- Modulo a power of two:
Exponent (little-endian 4-byte number)
- \(GF(2^n)\)
Storage size in bytes (little-endian 8-byte number). Default is 16.
\(n\) (little-endian 4-byte number)
As an example, the following output of hexdump -C
describes SPDZ
modulo the default 128-bit prime
(170141183460469231731687303715885907969):
00000000 1d 00 00 00 00 00 00 00 53 50 44 5a 20 67 66 70 |........SPDZ gfp|
00000010 00 10 00 00 00 80 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 1b 80 01 |.....|
00000025
The actual data is stored is by simple concatenation. For example,
triples are stored as repetitions of a, b, ab
, and daBits are
stored as repetitions of a, b
where a
is the arithmetic
share and b
is the binary share.
For protocols with MAC, the value share is stored before the MAC share.
Values are generally stored in little-endian order. Note the following domain specifics:
- Modulo a prime
Values are stored in Montgomery representation with \(R\) being the smallest power of \(2^{64}\) larger than the prime. For example, \(R = 2^{128}\) for a 128-bit prime. Furthermore, the values are stored in the smallest number of 8-byte blocks necessary, all in little-endian order.
- Modulo a power of two:
Values are stored in the smallest number of 8-byte blocks necessary, all in little-endian order.
- \(GF(2^n)\)
Values are stored in blocks according to the storage size above, all in little-endian order.
For further details, have a look at Utils/Fake-Offline.cpp
, which
contains code that generates preprocessing data insecurely for a range
of protocols (underlying the binary Fake-Offline.x
).
{mascot,cowgear,mal-shamir}-offline.x
generate
sufficient preprocessing data for a specific high-level program with
MASCOT, CowGear, and malicious Shamir secret sharing, respectively.
Adding a Protocol¶
In order to illustrate how to create a virtual machine for a new protocol, we have created one with blanks to be filled in. It is defined in the following files:
Machines/no-party.cpp
Contains the main function.
Protocols/NoShare.h
Contains the
NoShare
class, which is supposed to hold one share.NoShare
takes the cleartext type as a template parameter.Protocols/NoProtocol.h
Contains a number of classes representing instances of protocols:
NoInput
Private input.
NoProtocol
Multiplication protocol.
NoOutput
Public output.
Protocols/NoLivePrep.h
Contains the
NoLivePrep
class, representing a preprocessing instance.
The number of blanks can be overwhelming. We therefore recommend the
following approach to get started. If the desired protocol resembles
one that is already implemented, you can check its code for
inspiration. The main function of <protocol>-party.x
can be found
in Machines/<protocol>-party.cpp
, which in turns contains the name
of the share class. For example replicated-ring-party.x
is
implemented in Machines/replicated-ring-party.cpp
, which refers to
Rep3Share2()
in Protocols/Rep3Share2.h
. There you will
find that it uses Replicated()
for multiplication, which is
found in Protocols/Replicated.h
.
Fill in the
constant()
static member function ofNoShare
as well as theexchange()
member function ofNoOutput
. Check outDirectSemiMC<T>::exchange_()
inProtocols/SemiMC.hpp
for a simple example. It opens an additive secret sharing by sending all shares to all other parties and then summing up the received. See this reference for documentation on the necessary infrastructure. Constant sharing and public output allows to execute the following program:print_ln('%s', sint(123).reveal())
This allows to check the correct execution of further functionality.
Fill in the operator functions in
NoShare
and check them:print_ln('%s', (sint(2) + sint(3)).reveal()) print_ln('%s', (sint(2) - sint(3)).reveal()) print_ln('%s', (sint(2) * cint(3)).reveal())
Many protocols use these basic operations, which makes it beneficial to check the correctness
Fill in
NoProtocol
. Alternatively, if the desired protocol is based on Beaver multiplication, you can specify the following inNoShare
:typedef Beaver<This> Protocol;
Then add the desired triple generation to
NoLivePrep::buffer_triples()
. In any case you should then be able to execute:print_ln('%s', (sint(2) * sint(3)).reveal())
In order to execute many kinds of non-linear computation, random bits are needed. After filling in
NoLivePrep::buffer_bits()
, you should be able to execute:print_ln('%s', (sint(2) < sint(3)).reveal()
Troubleshooting¶
This section shows how to solve some common issues.
Crash without error message or bad_alloc
¶
Some protocols require several gigabytes of memory, and the virtual
machine will crash if there is not enough RAM. You can reduce the
memory usage for some malicious protocols with -B 5
.
Furthermore, every computation thread requires
separate resources, so consider reducing the number of threads with
for_range_multithreads()
and similar.
List indices must be integers or slices¶
You cannot access Python lists with runtime variables because the
lists only exists at compile time. Consider using
Array
.
compile.py
takes too long or runs out of memory¶
If you use Python loops (for
), they are unrolled at compile-time,
resulting in potentially too much virtual machine code. Consider using
for_range()
or similar. You can also use
-l
when compiling, which will replace simple loops by an optimized
version.
Order of memory instructions not preserved¶
By default, the compiler runs optimizations that in some corner case
can introduce errors with memory accesses such as accessing an
Array
. If you encounter such errors, you
can fix this either with -M
when compiling or placing
break_point() around memory accesses.
Odd timings¶
Many protocols use preprocessing, which means they execute expensive
computation to generates batches of information that can be used for
computation until the information is used up. An effect of this is
that computation can seem oddly slow or fast. For example, one
multiplication has a similar cost then some thousand multiplications
when using homomorphic encryption because one batch contains
information for more than than 10,000 multiplications. Only when a
second batch is necessary the cost shoots up. Other preprocessing
methods allow for a variable batch size, which can be changed using
-b
. Smaller batch sizes generally reduce the communication cost
while potentially increasing the number of communication rounds. Try
adding -b 10
to the virtual machine (or script) arguments for very
short computations.
Disparities in round figures¶
The number of virtual machine rounds given by the compiler are not an exact prediction of network rounds but the number of relevant protocol calls (such as multiplication, input, output etc) in the program. The actual number of network rounds is determined by the choice of protocol, which might use several rounds per protocol call. Furthermore, communication at the beginning and the end of a computation such as random key distribution and MAC checks further increase the number of network rounds.
Handshake failures¶
If you run on different hosts, the certificates
(Player-Data/*.pem
) must be the same on all of them. Furthermore,
party <i>
requires Player-Data/P<i>.key
that must match
Player-Data/P<i>.pem
, that is, they have to be generated to
together. The easiest way of setting this up is to run
Scripts/setup-ssl.sh
on one host and then copy all
Player-Data/*.{pem,key}
to all other hosts. This is not secure
but it suffices for experiments. A secure setup would generate every
key pair locally and then distributed only the public keys. Finally,
run c_rehash Player-Data
on all hosts. The certificates generated
by Scripts/setup-ssl.sh
expire after a month, so you need to
regenerate them. The same holds for Scripts/setup-client.sh
if you
use the client facility.
Connection failures¶
MP-SPDZ requires one TCP port per party to be open to other
parties. In the default setting, it’s 5000 on party 0, and
5001 on party 1 etc. You change change the base port (5000) using
--portnumbase
and individual ports for parties using
--my-port
. The scripts in use a random base port number, which you
can also change with --portnumbase
.
Internally called tape has unknown offline data usage¶
Certain computations are not compatible with reading preprocessing
from disk. You can compile the binaries with MY_CFLAGS +=
-DINSECURE
in CONFIG.mine
in order to execute the computation in
a way that reuses preprocessing.
Illegal instruction¶
By default, the binaries are optimized for the machine they are
compiled on. If you try to run them an another one, make sure set
ARCH
in CONFIG
accordingly. Furthermore, if you run on an x86
processor without AVX (produced before 2011), you need to set
AVX_OT = 0
to run dishonest-majority protocols.
Invalid instruction¶
The compiler code and the virtual machine binary have to be from the same version because most version slightly change the bytecode. This mean you can only use the precompiled binaries with the Python code in the same release.
Computation used more preprocessing than expected¶
This indicates an error in the internal accounting of preprocessing. Please file a bug report.
mac_fail
¶
This is a catch-all failure in protocols with malicious protocols that can be caused by something being wrong at any level. Please file a bug report with the specifics of your case.