MPyC package

MPyC is a Python package for secure multiparty computation (MPC).

MPyC provides a runtime for performing computations on secret-shared values, where parties interact by exchanging messages via peer-to-peer connections. The MPC protocols are based on Shamir’s threshold secret sharing scheme and withstand passive adversaries controlling less than half of the parties.

Secure integer and fixed-point arithmetic are supported for parameterized number ranges, also including support for comparison and bitwise operations. Secure finite field arithmetic is supported for fields of arbitrary order. Secure NumPy arrays over these basic types are available as well.

Basic support for secure floating-point arithmetic is provided. Moreover, support for secure finite group operations is built-in for a range of groups, particularly for use in threshold cryptography (e.g., Schnorr groups and elliptic curves).

The above operations are all available via Python’s operator overloading.

Secure drop-in replacements for lots of Python built-in functions, such as all(), any(), sum(), min(), max(), sorted() are provided, mimicking the Python APIs as much as possible. Further operations for container datatypes holding secret-shared data items are provided as well (e.g., matrix-vector operations like secure dot products), next to the support for NumPy arrays.

And much more functionality still in a couple of extension modules: seclists (secure lists with oblivious access and updates), mpctools (reduce and accumulate with log round complexity), random (securely mimicking Python’s random module), and statistics (securely mimicking Python’s statistics module).

mpyc.numpy

This module acts as a stub to avoid a (hard) dependency for the numpy package.

If the numpy package is not available, MPyC still runs but with less functionality. Use of NumPy can be disabled to avoid loading the numpy package.

If NumPy is enabled (available and not disabled), the MPyC runtime supports array types—along with vectorized implementations—for secure numbers and the underlying finite field types. The array types are accessible through the ‘array’ attribute, e.g., for secint48=mpc.SecInt(48), the array type is secint48.array and the array type for the underlying prime field is secint48.field.array.

mpyc.gmpy

This module collects all gmpy2 functions used by MPyC.

Stubs only using Python built-ins are provided in case the gmpy2 package is not available. Efficient functions for factoring prime powers and rational reconstruction are also provided.

mpyc.gmpy.factor_prime_power(x)

Return p and d for a prime power x = p**d.

mpyc.gmpy.gcdext(a, b)

Return a 3-element tuple (g, s, t) such that g == gcd(a, b) and g == a*s + b*t.

The particular values output for s and t are consistent with gmpy2, satisfying the following convention inherited from the GMP library, defining s and t uniquely.

Normally, abs(s) < abs(b)/(2g) and abs(t) < abs(a)/(2g) will hold. When no such s and t exist, we put s=0 and t=sign(b), if this is because abs(a)=abs(b)=g. Otherwise, we put s=sign(a), if b=0 or abs(b)=2g, and we put t=sign(b), if a=0 or abs(a)=2g.

mpyc.gmpy.invert(x, m)

Return y such that x*y == 1 modulo m.

Raises ZeroDivisionError if no inverse y exists (or, if m is zero).

mpyc.gmpy.iroot(x, n)

Return (y, b) where y is the integer nth root of x and b is True if y is exact.

mpyc.gmpy.is_prime(x, n=25)

Return True if x is probably prime, else False if x is definitely composite, performing up to n Miller-Rabin primality tests.

mpyc.gmpy.is_square(x)

Return True if x is a perfect square, False otherwise.

mpyc.gmpy.isqrt(x)

Return integer square root of nonnegative x.

mpyc.gmpy.jacobi(x, y)

Return the Jacobi symbol (x|y), assuming y > 0 is odd.

mpyc.gmpy.kronecker(x, y)

Return the Kronecker symbol (x|y).

mpyc.gmpy.legendre(x, y)

Return the Legendre symbol (x|y), assuming y is an odd prime.

mpyc.gmpy.mpz(x)

Return Python int(x) as stub for gmpy2’s mpz(x).

mpyc.gmpy.next_prime(x)

Return the next probable prime number > x.

mpyc.gmpy.powmod(x, y, m)

Return (x**y) mod m.

mpyc.gmpy.prev_prime(x)

Return the greatest probable prime number < x, if any.

mpyc.gmpy.ratrec(x, y, N=None, D=None)

Return rational reconstruction (n, d) of x modulo y. That is, n/d = x (mod y) with -N <= n <= N and 0 < d <= D, provided 2*N*D < y.

Default N=D=None will set both N and D to sqrt(y/2) approximately.

mpyc.gfpx

This module supports arithmetic with polynomials over GF(p).

Polynomials over GF(p) are represented as coefficient lists. The polynomial a_0 + a_1 X + … + a_n X^n corresponds to the list [a_0, a_1, … , a_n] of integers in {0, … , p-1}. Leading coefficient a_n is nonzero, using [] for the zero polynomial.

However, binary polynomials (over GF(2)) are represented as integers. The polynomial a_0 + a_1 X + … + a_n X^n corresponds to the integer a_0 + a_1 2 + … + a_n 2^n. Leading coefficient a_n is 1, using 0 for the zero polynomial.

The operators +,-,*,<<,//,%, and function divmod are overloaded. The operators <,<=,>,>=,==,!= are overloaded as well, using the lexicographic order for polynomials (zero polynomial is the smallest). Plus some SageMath-style functionality, for instance, to access coefficients using Python indexing and to reverse a polynomial.

GCD, extended GCD, modular inverse and powers are all supported. A simple irreducibility test is provided as well as a basic routine to find the next largest irreducible polynomial.

class mpyc.gfpx.BinaryPolynomial(value=0, check=True)

Polynomials over GF(2) represented as nonnegative integers.

to_bytes(length, byteorder)

Return a bytes object representing a polynomial.

mpyc.gfpx.GFpX(p)

Create type for polynomials over GF(p).

class mpyc.gfpx.Polynomial(value=0, check=True)

Polynomials over GF(p) represented as lists of integers in {0, … , p-1}.

Invariant: last element of attribute ‘value’ is a nonzero integer (if ‘value’ nonempty).

classmethod add(a, b)

Add polynomials a and b.

classmethod deg(a)

Degree of polynomial a (-1 if a is zero polynomial).

degree()

Degree of polynomial (-1 for zero polynomial).

classmethod divmod(a, b)

Divide polynomial a by polynomial b with remainder, for nonzero b.

classmethod from_terms(s, x='x')

Convert string s with sum of powers of x to a polynomial.

classmethod gcd(a, b)

Greatest common divisor of polynomials a and b.

classmethod gcdext(a, b)

Extended GCD for polynomials a and b.

Return d, s, t satisfying s a + t b = d = gcd(a,b).

classmethod invert(a, b)

Inverse of polynomial a modulo polynomial b, for nonzero b.

classmethod is_irreducible(a)

Test polynomial a for irreducibility.

classmethod lshift(a, n)

Multiply polynomial a by X^n.

classmethod mod(a, b)

Reduce polynomial a modulo polynomial b, for nonzero b.

monic(lc_pinv=False)

Monic version of polynomial.

Zero polynomial remains unchanged. If lc_pinv is set, inverse of leading coefficient is also returned (0 for zero polynomial).

classmethod mul(a, b)

Multiply polynomials a and b.

classmethod next_irreducible(a)

Return lexicographically next monic irreducible polynomial > a.

E.g., X < X+1 < X^2+X+1 < X^3+X+1 < X^3+X^2+1 < … for p=2.

classmethod powmod(a, n, b)

Polynomial a to the power of n modulo polynomial b, for nonzero b.

reverse(d=None)

Reverse of polynomial (basically, coefficients in reverse order).

For example, reverse of x + 2x^2 + 3x^3 is 3 + 2x + x^2. If d is None (default), d is set to the degree of the given poynomial. Otherwise, the given polynomial is first padded with zeros or truncated to attain the given degree d, d>=-1, before it is reversed.

classmethod rshift(a, n)

Quotient for polynomial a divided by X^n, assuming a is multiple of X^n.

classmethod sub(a, b)

Subtract polynomials a and b.

to_bytes(length, byteorder)

Return a bytes object representing a polynomial.

classmethod to_terms(a, x='x')

Convert polynomial a to a string with sum of powers of x.

mpyc.finfields

This module supports finite (Galois) fields.

Function GF creates types implementing finite fields. Instantiate an object from a field and subsequently apply overloaded operators such as +,-,*,/ etc., to compute with field elements. In-place versions of the field operators are also provided. Taking square roots and quadratic residuosity tests supported as well.

Moreover, (multidimensional) arrays over finite fields are available with operators like +,-,*,/ for convenient and efficient NumPy-based vectorized processing next to operator @ for matrix multiplication. Much of the NumPy API can be used to manipulate these arrays as well.

class mpyc.finfields.BinaryFieldArray(value, check=True, copy=False)
class mpyc.finfields.BinaryFieldElement(value)

Common base class for binary field elements.

class mpyc.finfields.ExtensionFieldArray(value, check=True, copy=False)
class mpyc.finfields.ExtensionFieldElement(value)

Common base class for extension field elements.

static createGF(modulus)

Create new object for use by pickle module.

class mpyc.finfields.FiniteFieldArray(value, check=True, copy=False)

Common base class for finite field arrays.

An array over finite field F behaves much like a NumPy array with dtype=F. Conceptually, an array a over F can be thought of as, for example

“a = np.array([[F(1), F(2)], [F(0), F(3)]], dtype=F)”

Internally, however, arrays over a finite field F are represented by NumPy arrays with dtype=object storing just the values of the finite field elements:

“a = (field=F, value=np.array([[1, 2], [0, 3]], dtype=object))”

Invariant: elements of array ‘value’ are reduced w.r.t. modulus.

static gauss_det(a)

Determinant by Gaussian elimination on (last 2 dimensions of) array a.

static gauss_inv(A)

Inverse by Gaussian elimination on augmented matrix (A | I).

static gauss_solve(A, B)

Linear solve by Gaussian elimination on matrix (A | B).

is_sqr()

Test for quadratic residuosity (0 is also square).

reciprocal()

Multiplicative inverse.

sqrt(INV=False)

Modular (inverse) square root.

class mpyc.finfields.FiniteFieldElement(value)

Abstract base class for finite field elements.

Invariant: ‘value’ is reduced w.r.t. modulus.

classmethod from_bytes(data)

Return the list of integers represented by the given byte string.

is_sqr()

Test for quadratic residuosity (0 is also square).

reciprocal()

Multiplicative inverse.

sqrt(INV=False)

Modular (inverse) square root.

classmethod to_bytes(x)

Return byte string representing the given list/ndarray of integers x.

mpyc.finfields.GF(modulus)

Create a finite (Galois) field for given modulus (prime number or irreducible polynomial).

Also creates corresponding array type.

class mpyc.finfields.PrimeFieldArray(value, check=True, copy=False)
classmethod intarray(a)

Extract finite field array as a (signed) integer array.

signed_()

Return signed integer representation, symmetric around zero.

unsigned_()

Return unsigned integer representation.

class mpyc.finfields.PrimeFieldElement(value)

Common base class for prime field elements.

static createGF(p, n, w)

Create new object for use by pickle module.

signed_()

Return signed integer representation, symmetric around zero.

unsigned_()

Return unsigned integer representation.

mpyc.finfields.find_irreducible(p, d)

Find smallest irreducible polynomial of degree d over GF(p).

mpyc.finfields.find_prime_root(l, blum=True, n=1)

Find prime of bit length at least l satisfying given constraints.

Default is to return Blum primes (primes p with p % 4 == 3). Also, a primitive root w is returned of prime order at least n (0 < w < p).

mpyc.finfields.pGF(p, n, w)

Create a finite field for given prime modulus p.

mpyc.finfields.xGF(modulus)

Create a finite field for given irreducible polynomial.

mpyc.fingroups

This module supports several types of finite groups.

A finite group is a set of group elements together with a group operation. The group operation is a binary operation, usually written multiplicatively (optionally, the group operation can be written additively).

The default Python operators to manipulate group elements are the (binary) operator @ for the group operation, the (unary) operator ~ for inversion of group elements, and the (binary) operator ^ for repeated application of the group operation. The alternative Python operators used for additive and multiplicative notation are:

  • default: a @ b, ~a, a^n (a^-1 = ~a)

  • additive: a + b, -a, n*a (-1*a = -a)

  • multiplicative: a * b, 1/a, a**n (a**-1 = 1/a)

for arbitrary group elements a, b, and integer n.

Five types of groups are currently supported, aimed mainly at applications in cryptography:

  • symmetric groups of any degree n (n>=0)

  • quadratic residue groups modulo a safe prime

  • Schnorr groups (prime-order subgroups of the multiplicative group of a finite field)

  • elliptic curve groups (Edwards curves, a Koblitz curve, and Barreto-Naehrig curves)

  • class groups of imaginary quadratic fields

The structure of most of these groups will be trivial, preferably cyclic or even of prime order. Where applicable, a generator of the group (or a sufficiently large subgroup) is provided to accommodate discrete log and Diffie-Hellman hardness assumptions.

mpyc.fingroups.ClassGroup(Delta=None, l=None)

Create type for class group, given (bit length l of) discriminant Delta.

The following conditions are imposed on discriminant Delta:

  • Delta < 0, only supporting class groups of imaginary quadratic field

  • Delta = 1 (mod 4), preferably Delta = 1 (mod 8)

  • -Delta is prime

This implies that Delta is a fundamental discriminant.

class mpyc.fingroups.ClassGroupForm(value=None, check=True)

Common base class for class groups of imaginary quadratic fields.

Represented by primitive positive definite forms (a,b,c) of discriminant D<0. That is, all forms (a,b,c) with D=b^2-4ac<0 satisfying gcd(a,b,c)=1 and a>0.

classmethod encode(m)

Encode message m in the first coefficient of a form.

classmethod equality(f1, f2, /)

Return a == b.

classmethod inversion(f, /)

Return @-inverse of a (written ~a).

classmethod operation(f1, f2, /)

Return a @ b.

classmethod operation2(f, /)

Return a @ a.

class mpyc.fingroups.EdwardsAffine(value=None, check=True)

Edwards curves with affine coordinates.

classmethod equality(pt1, pt2, /)

Return a == b.

classmethod inversion(pt, /)

Return @-inverse of a (written ~a).

normalize()

Convert to unique affine representation.

classmethod operation(pt1, pt2, /)

Add Edwards points using affine coordinates (projective with z=1).

class mpyc.fingroups.EdwardsCurvePoint(value=None, check=True)

Common base class for (twisted) Edwards curves.

classmethod ysquared(x)

Return value of y^2 as a function of x, for a point (x, y) on the curve.

class mpyc.fingroups.EdwardsExtended(value=None, check=True)

Edwards curves with extended coordinates.

classmethod equality(pt1, pt2, /)

Return a == b.

classmethod inversion(pt, /)

Return @-inverse of a (written ~a).

normalize()

Convert to unique affine representation.

classmethod operation(pt1, pt2, /)

Add (twisted a=-1) Edwards points in extended projective coordinates.

classmethod operation2(pt, /)

Doubling (twisted a=-1) Edwards point in extended projective coordinates.

class mpyc.fingroups.EdwardsProjective(value=None, check=True)

Edwards curves with projective coordinates.

classmethod equality(pt1, pt2, /)

Return a == b.

classmethod inversion(pt, /)

Return @-inverse of a (written ~a).

normalize()

Convert to unique affine representation.

classmethod operation(pt1, pt2, /)

Add Edwards points with (homogeneous) projective coordinates.

mpyc.fingroups.EllipticCurve(curvename='Ed25519', coordinates=None)

Create elliptic curve type for a selection of built-in curves. The default coordinates used with these curves are ‘affine’.

The following Edwards curves and Weierstrass curves are built-in:

These curves can be used with ‘affine’ (default) and ‘projective’ coordinates. The Edwards curves can also be used with ‘extended’ coordinates, and the Weierstrass curves with ‘jacobian’ coordinates.

class mpyc.fingroups.EllipticCurvePoint

Common base class for elliptic curve groups.

classmethod encode(m)

Encode message m in x-coordinate of a point on the curve.

normalize()

Convert to unique affine representation.

classmethod ysquared(x)

Return value of y^2 as a function of x, for a point (x, y) on the curve.

class mpyc.fingroups.FiniteGroupElement

Abstract base class for finite groups.

Overview Python operators for group operation, inverse, and repeated operation:

  • default notation: @, ~, ^ (matmul, invert, xor).

  • additive notation: +, -, * (add, sub, mul)

  • multiplicative notation: , 1/ (or, *-1), ** (mul, truediv (or, pow), pow)

classmethod equality(a, b, /)

Return a == b.

inverse()

For convenience.

classmethod inversion(a, /)

Return @-inverse of a (written ~a).

classmethod operation(a, b, /)

Return a @ b.

classmethod operation2(a, /)

Return a @ a.

static repeat(a, n)

Return nth @-power of a (written a^n), for any integer n.

class mpyc.fingroups.QuadraticResidue(value=1, check=True)

Common base class for groups of quadratic residues modulo an odd prime.

Quadratic residues modulo p represented by GF(p)* elements.

classmethod encode(m)

Encode message m in a quadratic residue.

classmethod equality(a, b, /)

Return a == b.

classmethod inversion(a, /)

Return @-inverse of a (written ~a).

classmethod operation(a, b, /)

Return a @ b.

classmethod repeat(a, n)

Return nth @-power of a (written a^n), for any integer n.

mpyc.fingroups.QuadraticResidues(p=None, l=None)

Create type for quadratic residues group given (bit length l of) odd prime modulus p.

The group of quadratic residues modulo p is of order n=(p-1)/2. Given bit length l>2, p will be chosen such that n is also an odd prime. If l=2, the only possibility is p=3, hence n=1.

mpyc.fingroups.SchnorrGroup(p=None, q=None, g=None, l=None, n=None)

Create type for Schnorr group of odd prime order q.

If q is not given, q will be the largest n-bit prime, n>=2. If p is not given, p will be the least l-bit prime, l>n, such that q divides p-1.

If l and/or n are not given, default bit lengths will be set (2<=n<l).

class mpyc.fingroups.SchnorrGroupElement(value=1, check=True)

Common base class for prime-order subgroups of the multiplicative group of a finite field.

classmethod encode(m)

Encode message m in group element g^m.

classmethod equality(a, b, /)

Return a == b.

classmethod inversion(a, /)

Return @-inverse of a (written ~a).

classmethod operation(a, b, /)

Return a @ b.

classmethod repeat(a, n)

Return nth @-power of a (written a^n), for any integer n.

mpyc.fingroups.SymmetricGroup(n)

Create type for symmetric group of degree n, n>=0.

class mpyc.fingroups.SymmetricGroupElement(value=None, check=True)

Common base class for symmetric groups.

Symmetric groups contains all permutations of a fixed length (degree). Permutations of {0,…,n-1} represented as length-n tuples with unique entries in {0,…,n-1}, n>=0.

classmethod equality(p, q, /)

Return a == b.

classmethod inversion(p, /)

Return @-inverse of a (written ~a).

classmethod operation(p, q, /)

First p then q.

class mpyc.fingroups.WeierstrassAffine(value=None, check=True)

Short Weierstrass curves with affine coordinates.

classmethod equality(pt1, pt2, /)

Return a == b.

classmethod inversion(pt, /)

Return @-inverse of a (written ~a).

normalize()

Convert to unique affine representation.

classmethod operation(pt1, pt2, /)

Add Weierstrass points with affine coordinates.

classmethod operation2(pt, /)

Double Weierstrass point with affine coordinates.

class mpyc.fingroups.WeierstrassCurvePoint(value=None, check=True)

Common base class for (short) Weierstrass curves.

classmethod ysquared(x)

Return value of y^2 as a function of x, for a point (x, y) on the curve.

class mpyc.fingroups.WeierstrassJacobian(value=None, check=True)

Short Weierstrass curves with Jacobian coordinates.

classmethod equality(pt1, pt2, /)

Return a == b.

classmethod inversion(pt, /)

Return @-inverse of a (written ~a).

normalize()

Convert to unique affine representation.

classmethod operation(pt1, pt2, /)

Add Weierstrass points with Jacobian coordinates.

classmethod operation2(pt, /)

Double Weierstrass point with Jacobian coordinates.

class mpyc.fingroups.WeierstrassProjective(value=None, check=True)

Short Weierstrass curves with projective coordinates.

classmethod equality(pt1, pt2, /)

Return a == b.

classmethod inversion(pt, /)

Return @-inverse of a (written ~a).

normalize()

Convert to unique affine representation.

classmethod operation(pt1, pt2, /)

Add Weierstrass points with projective coordinates.

classmethod operation2(pt, /)

Double Weierstrass point with projective coordinates.

mpyc.thresha

Module for information-theoretic and pseudorandom threshold secret sharing.

Threshold secret sharing assumes secure channels for communication. Pseudorandom secret sharing (PRSS) allows one to share pseudorandom secrets without any communication, as long as the parties agree on a (unique) common public input for each secret.

PRSS relies on parties having agreed upon the keys for a pseudorandom function (PRF).

class mpyc.thresha.PRF(key, bound)

A pseudorandom function (PRF).

A PRF is determined by a secret key and a public maximum.

mpyc.thresha.np_pseudorandom_share(field, m, i, prfs, uci, n)

Return pseudorandom Shamir shares for party i for n random numbers.

The shares are based on the pseudorandom functions for party i, given in prfs, which maps subsets of parties to PRF instances. Input uci is used to evaluate the PRFs on a unique common input.

mpyc.thresha.np_pseudorandom_share_0(field, m, i, prfs, uci, n)

Return pseudorandom Shamir shares for party i for n sharings of 0.

The shares are based on the pseudorandom functions for party i, given in prfs, which maps subsets of parties to PRF instances. Input uci is used to evaluate the PRFs on a unique common input.

mpyc.thresha.np_random_split(field, s, t, m)

Split each secret given in s into m random Shamir shares.

The (maximum) degree for the Shamir polynomials is t, 0 <= t < m. Return matrix of shares, one row per party.

mpyc.thresha.np_recombine(field, points, x_rs=0)

Recombine shares given by points into secrets.

Recombination is done for x-coordinates x_rs.

mpyc.thresha.pseudorandom_share(field, m, i, prfs, uci, n)

Return pseudorandom Shamir shares for party i for n random numbers.

The shares are based on the pseudorandom functions for party i, given in prfs, which maps subsets of parties to PRF instances. Input uci is used to evaluate the PRFs on a unique common input.

mpyc.thresha.pseudorandom_share_zero(field, m, i, prfs, uci, n)

Return pseudorandom Shamir shares for party i for n sharings of 0.

The shares are based on the pseudorandom functions for party i, given in prfs, which maps subsets of parties to PRF instances. Input uci is used to evaluate the PRFs on a unique common input.

mpyc.thresha.random_split(field, s, t, m)

Split each secret given in s into m random Shamir shares.

The (maximum) degree for the Shamir polynomials is t, 0 <= t < m. Return matrix of shares, one row per party.

mpyc.thresha.recombine(field, points, x_rs=0)

Recombine shares given by points into secrets.

Recombination is done for x-coordinates x_rs.

mpyc.asyncoro

This module provides basic support for asynchronous communication and computation of secret-shared values.

class mpyc.asyncoro.MessageExchanger(rt, peer_pid=None)

Send and receive messages.

Bidirectional connection with one of the other parties (peers).

close_connection()

Close connection with the peer.

connection_lost(exc)

Called when the connection with the peer is lost or closed.

If the connection is closed normally (during shutdown) then exc is None. Otherwise, if the connection is lost unexpectedly, exc may indicate the cause.

connection_made(transport)

Called when a connection is made.

If this party is a client for this connection, it sends its identity to the peer as well as any PRSS keys.

data_received(data)

Called when data is received from the peer.

Received bytes are unpacked as a program counter and the payload (actual data). The payload is passed to the appropriate Future, if any.

First message from peer is processed differently if peer is a client.

receive(pc)

Receive payload labeled with given pc from the peer.

send(pc, payload)

Send payload labeled with pc to the peer.

Message format consists of three parts:
  1. pc (8 bytes signed int)

  2. payload_size (4 bytes unsigned int)

  3. payload (byte string of length payload_size).

class mpyc.asyncoro.SecureObject(value=None)

A secret-shared object.

An MPC protocol operates on secret-shared objects of type SecureObject. The basic Python operators are overloaded by SecureObject classes. An expression like a * b will create a new SecureObject, which will eventually contain the product of a and b. The product is computed asynchronously, using an instance of a specific cryptographic protocol.

set_share(value)

Set share to the given value.

The share is set directly (or recursively, for a composite SecureObject), using callbacks if value contains Futures that are not yet done.

mpyc.asyncoro.exception_handler(loop, context)

Handle some MPyC coroutine related exceptions.

mpyc.asyncoro.gather_shares(rt, *obj)

Gather all results for the given futures (shares).

mpyc.asyncoro.mpc_coro(func, pc=True)

Decorator turning coroutine func into an MPyC coroutine.

An MPyC coroutine is evaluated asynchronously, returning empty placeholders. The type of the placeholders is defined either by a return annotation of the form “-> expression” or by the first await expression in func. Return annotations can only be used for static types.

mpyc.asyncoro.returnType(*args, wrap=True)

Define return type for MPyC coroutines.

Used in first await expression in an MPyC coroutine.

mpyc.sectypes

This module collects basic secure (secret-shared) types for MPyC.

Secure number (array) types all use common base classes, which ensures that operators such as +,*,>= are defined by operator overloading.

mpyc.sectypes.SecFld(order=None, modulus=None, char=None, ext_deg=None, min_order=None, signed=False)

Secure finite field of order q = p**d.

Order q >= min_order. Field is prime (d = 1) by default and if modulus is prime. Extension degree d > 1 if order is a prime power p**d with d > 1, if modulus is a polynomial or a string or an integer > char, or if ext_deg is an integer > 1, or if min_order > char.

mpyc.sectypes.SecFlt(l=None, s=None, e=None)

Secure l-bit floating-point number with s-bit significand and e-bit exponent, where l=s+e.

The significand is an (s+1)-bit secure (signed) fixed-point number. The absolute value of a nonzero significand is normalized between 0.5 and 1.0. Here, both 0.5 and 1.0 are included and therefore one extra bit is used. The exponent is an e-bit secure (signed) integer.

mpyc.sectypes.SecFxp(l=None, f=None, p=None, n=2)

Secure l-bit fixed-point numbers with f-bit fractional part.

NB: if dividing secure fixed-point numbers, make sure that l =~ 2f.

mpyc.sectypes.SecInt(l=None, p=None, n=2)

Secure l-bit integers.

class mpyc.sectypes.SecureArray(value=None, shape=None)

Base class for secure (secret-shared) number arrays.

argmax(*args, **kwargs)

Returns the indices of the maximum values along an axis.

If no axis is given (default), array is flattened first.

By default, the indices are returned as unit vectors. Also, by default, the maximum values are returned (next to the indices).

NB: Different defaults than for np_argmax(). Latter behaves like np.argmax() for NumPy arrays, returning the indices as numbers and omitting the maximum values.

argmin(*args, **kwargs)

Returns the indices of the minimum values along an axis.

If no axis is given (default), array is flattened first.

By default, the indices are returned as unit vectors. Also, by default, the minimum values are returned (next to the indices).

NB: Different defaults than for np_argmin(). Latter behaves like np.argmin() for NumPy arrays, returning the indices as numbers and omitting the minimum values.

sort(*args, **kwargs)

Returns new array sorted along an axis.

By default, axis=-1. If axis is None, the array is flattened.

class mpyc.sectypes.SecureFiniteField(value=None)

Base class for secure (secret-shared) finite field elements.

NB: bit-oriented operations will be supported for prime fields.

class mpyc.sectypes.SecureFiniteFieldArray(value=None, shape=None)

Base class for secure (secret-shared) arrays of finite field elements.

class mpyc.sectypes.SecureFixedPoint(value=None, integral=None)

Base class for secure (secret-shared) fixed-point numbers.

class mpyc.sectypes.SecureFixedPointArray(value=None, shape=None, integral=None)

Base class for secure (secret-shared) arrays of fixed-point numbers.

class mpyc.sectypes.SecureFloat(value=None)

Base class for secure (secret-shared) floating-point numbers.

Basic arithmetic +,-,*,/ and comparisons <,<=,–,>,>=,!= are supported for secure floats, as well as input()/output() and sorting operations like min()/argmax()/sorted(). Other operations like sum()/prod()/all()/any()/in_prod() are currently not supported for secure floats.

Implementation is kept simple, representing a secure float as a pair consisting of a secure fixed-point number for the significand and a secure integer for the exponent. Note, however, that even basic arithmetic +,-,*,/ with secure floats is very demanding performance-wise (due to dependence on secure bitwise operations).

static is_zero_public(a)

Called by runtime.is_zero_public().

reciprocal()

Secure reciprocal (multiplicative inverse).

set_share(value)

Set share to the given value.

The share is set directly (or recursively, for a composite SecureObject), using callbacks if value contains Futures that are not yet done.

class mpyc.sectypes.SecureInteger(value=None)

Base class for secure (secret-shared) integers.

class mpyc.sectypes.SecureIntegerArray(value=None, shape=None)

Base class for secure (secret-shared) integer arrays.

class mpyc.sectypes.SecureNumber(value=None)

Base class for secure (secret-shared) numbers.

if_else(x, y)

Use SecureNumber as condition for secure selection between x and y.

if_swap(x, y)

Use SecureNumber as condition for secure swap of x and y.

mpyc.runtime

The MPyC runtime module is used to execute secure multiparty computations.

Parties perform computations on secret-shared values by exchanging messages. Shamir’s threshold secret sharing scheme is used for finite fields of any order exceeding the number of parties. MPyC provides many secure data types, ranging from numeric types to more advanced types, for which the corresponding operations are made available through Python’s mechanism for operator overloading.

class mpyc.runtime.Party(pid: int, host: str | None = None, port: int | None = None)

Information about party with identity pid in the MPC protocol.

class mpyc.runtime.Runtime(pid, parties, options)

MPyC runtime secure against passive attacks.

The runtime maintains basic information such as a program counter, the list of parties, etc., and handles secret-shared objects of type SecureObject.

1-party case is supported (with option to disable asynchronous evaluation). Threshold 0 (no corrupted parties) is supported for m-party case as well to enable distributed computation (without secret sharing).

static SecClassGroup(Delta=None, l=None)

Call SecClassGroup(…) is equivalent to SecGrp(ClassGroup(…)), returning secure version of ClassGroup from mpyc.fingroups.

ClassGroup(Delta=None, l=None):

Create type for class group, given (bit length l of) discriminant Delta.

The following conditions are imposed on discriminant Delta:

  • Delta < 0, only supporting class groups of imaginary quadratic field

  • Delta = 1 (mod 4), preferably Delta = 1 (mod 8)

  • -Delta is prime

This implies that Delta is a fundamental discriminant.

static SecEllipticCurve(curvename='Ed25519', coordinates=None)

Call SecEllipticCurve(…) is equivalent to SecGrp(EllipticCurve(…)), returning secure version of EllipticCurve from mpyc.fingroups.

EllipticCurve(curvename=’Ed25519’, coordinates=None):

Create elliptic curve type for a selection of built-in curves. The default coordinates used with these curves are ‘affine’.

The following Edwards curves and Weierstrass curves are built-in:

These curves can be used with ‘affine’ (default) and ‘projective’ coordinates. The Edwards curves can also be used with ‘extended’ coordinates, and the Weierstrass curves with ‘jacobian’ coordinates.

static SecFld(order=None, modulus=None, char=None, ext_deg=None, min_order=None, signed=False)

Secure finite field of order q = p**d.

Order q >= min_order. Field is prime (d = 1) by default and if modulus is prime. Extension degree d > 1 if order is a prime power p**d with d > 1, if modulus is a polynomial or a string or an integer > char, or if ext_deg is an integer > 1, or if min_order > char.

static SecFlt(l=None, s=None, e=None)

Secure l-bit floating-point number with s-bit significand and e-bit exponent, where l=s+e.

The significand is an (s+1)-bit secure (signed) fixed-point number. The absolute value of a nonzero significand is normalized between 0.5 and 1.0. Here, both 0.5 and 1.0 are included and therefore one extra bit is used. The exponent is an e-bit secure (signed) integer.

static SecFxp(l=None, f=None, p=None, n=2)

Secure l-bit fixed-point numbers with f-bit fractional part.

NB: if dividing secure fixed-point numbers, make sure that l =~ 2f.

static SecGrp(group)

Secure version of given finite group.

static SecInt(l=None, p=None, n=2)

Secure l-bit integers.

static SecQuadraticResidues(p=None, l=None)

Call SecQuadraticResidues(…) is equivalent to SecGrp(QuadraticResidues(…)), returning secure version of QuadraticResidues from mpyc.fingroups.

QuadraticResidues(p=None, l=None):

Create type for quadratic residues group given (bit length l of) odd prime modulus p.

The group of quadratic residues modulo p is of order n=(p-1)/2. Given bit length l>2, p will be chosen such that n is also an odd prime. If l=2, the only possibility is p=3, hence n=1.

static SecSchnorrGroup(p=None, q=None, g=None, l=None, n=None)

Call SecSchnorrGroup(…) is equivalent to SecGrp(SchnorrGroup(…)), returning secure version of SchnorrGroup from mpyc.fingroups.

SchnorrGroup(p=None, q=None, g=None, l=None, n=None):

Create type for Schnorr group of odd prime order q.

If q is not given, q will be the largest n-bit prime, n>=2. If p is not given, p will be the least l-bit prime, l>n, such that q divides p-1.

If l and/or n are not given, default bit lengths will be set (2<=n<l).

static SecSymmetricGroup(n)

Call SecSymmetricGroup(…) is equivalent to SecGrp(SymmetricGroup(…)), returning secure version of SymmetricGroup from mpyc.fingroups.

SymmetricGroup(n):

Create type for symmetric group of degree n, n>=0.

class SecureArray(value=None, shape=None)

Base class for secure (secret-shared) number arrays.

argmax(*args, **kwargs)

Returns the indices of the maximum values along an axis.

If no axis is given (default), array is flattened first.

By default, the indices are returned as unit vectors. Also, by default, the maximum values are returned (next to the indices).

NB: Different defaults than for np_argmax(). Latter behaves like np.argmax() for NumPy arrays, returning the indices as numbers and omitting the maximum values.

argmin(*args, **kwargs)

Returns the indices of the minimum values along an axis.

If no axis is given (default), array is flattened first.

By default, the indices are returned as unit vectors. Also, by default, the minimum values are returned (next to the indices).

NB: Different defaults than for np_argmin(). Latter behaves like np.argmin() for NumPy arrays, returning the indices as numbers and omitting the minimum values.

sort(*args, **kwargs)

Returns new array sorted along an axis.

By default, axis=-1. If axis is None, the array is flattened.

class SecureFiniteField(value=None)

Base class for secure (secret-shared) finite field elements.

NB: bit-oriented operations will be supported for prime fields.

class SecureFiniteFieldArray(value=None, shape=None)

Base class for secure (secret-shared) arrays of finite field elements.

class SecureFiniteGroup(value=None)

Abstract base class for secure (secret-shared) finite groups elements.

classmethod equality(a, b, /)

Return a == b.

classmethod if_else(c, a, b)

Secure selection based on binary condition c between group elements a and b.

Condition c must be of a secure number type compatible with the group, and its value should be 0 or 1. Input a must be compatible with the group as well, either of the secure type cls or of type cls.group. Same for input b.

inverse()

For ease of use.

classmethod inversion(a, /)

Return @-inverse of a (written ~a).

classmethod operation(a, b, /)

Return a @ b.

classmethod operation2(a, /)

Return a @ a.

classmethod repeat(a, x)

Return xth @-power of a (written a^x), for any integral number x.

Base a is either a public or a secure group element. Exponent x is either a public or a secure integral number. Possibly a, x are lists (of same length)

class SecureFixedPoint(value=None, integral=None)

Base class for secure (secret-shared) fixed-point numbers.

class SecureFixedPointArray(value=None, shape=None, integral=None)

Base class for secure (secret-shared) arrays of fixed-point numbers.

class SecureFloat(value=None)

Base class for secure (secret-shared) floating-point numbers.

Basic arithmetic +,-,*,/ and comparisons <,<=,–,>,>=,!= are supported for secure floats, as well as input()/output() and sorting operations like min()/argmax()/sorted(). Other operations like sum()/prod()/all()/any()/in_prod() are currently not supported for secure floats.

Implementation is kept simple, representing a secure float as a pair consisting of a secure fixed-point number for the significand and a secure integer for the exponent. Note, however, that even basic arithmetic +,-,*,/ with secure floats is very demanding performance-wise (due to dependence on secure bitwise operations).

static is_zero_public(a)

Called by runtime.is_zero_public().

reciprocal()

Secure reciprocal (multiplicative inverse).

set_share(value)

Set share to the given value.

The share is set directly (or recursively, for a composite SecureObject), using callbacks if value contains Futures that are not yet done.

class SecureInteger(value=None)

Base class for secure (secret-shared) integers.

class SecureIntegerArray(value=None, shape=None)

Base class for secure (secret-shared) integer arrays.

class SecureNumber(value=None)

Base class for secure (secret-shared) numbers.

if_else(x, y)

Use SecureNumber as condition for secure selection between x and y.

if_swap(x, y)

Use SecureNumber as condition for secure swap of x and y.

class SecureObject(value=None)

A secret-shared object.

An MPC protocol operates on secret-shared objects of type SecureObject. The basic Python operators are overloaded by SecureObject classes. An expression like a * b will create a new SecureObject, which will eventually contain the product of a and b. The product is computed asynchronously, using an instance of a specific cryptographic protocol.

set_share(value)

Set share to the given value.

The share is set directly (or recursively, for a composite SecureObject), using callbacks if value contains Futures that are not yet done.

abs(a, l=None)

Secure absolute value of a.

add(a, b)

Secure addition of a and b.

add_bits(x, y)

Secure binary addition of bit vectors x and y.

all(x)

Secure all of elements in x, similar to Python’s built-in all().

Elements of x are assumed to be either 0 or 1 (Boolean). Runs in log_2 len(x) rounds.

and_(a, b)

Secure bitwise and of a and b.

any(x)

Secure any of elements in x, similar to Python’s built-in any().

Elements of x are assumed to be either 0 or 1 (Boolean). Runs in log_2 len(x) rounds.

argmax(*x, key=None)

Secure argmax of all given elements in x.

See runtime.sorted() for details on key etc. In case of multiple occurrences of the maximum values, the index of the first occurrence is returned.

argmin(*x, key=None)

Secure argmin of all given elements in x.

See runtime.sorted() for details on key etc. In case of multiple occurrences of the minimum values, the index of the first occurrence is returned.

async barrier(name=None)

Barrier for runtime, using optional string name for easy identification.

convert(x, t_type)

Secure conversion of (elements of) x to given t_type.

Value x is a secure number, or a list of secure numbers. Converted values assumed to fit in target type.

static coroutine(func, pc=True)

Decorator turning coroutine func into an MPyC coroutine.

An MPyC coroutine is evaluated asynchronously, returning empty placeholders. The type of the placeholders is defined either by a return annotation of the form “-> expression” or by the first await expression in func. Return annotations can only be used for static types.

cos(a)

Secure cosine of fixed-point number a.

div(a, b)

Secure division of a by b, for nonzero b.

eq(a, b)

Secure comparison a == b.

eq_public(a, b)

Secure public equality test of a and b.

find(x, a, bits=True, e='len(x)', f=None, cs_f=None)

Return index ix of the first occurrence of a in list x.

The elements of x and a are assumed to be in {0, 1}, by default. Set Boolean flag bits=False for arbitrary inputs.

If a is not present in x, then ix=len(x) by default. Set flag e=E to get ix=E instead if a is not present in x. Set e=None to get the “raw” output as a pair (nf, ix), where the indicator bit nf=1 if and only if a is not found in x.

For instance, E=-1 can be used to mimic Python’s find() methods. If E is a string, i=eval(E) will be returned where E is an expression in terms of len(x). As a simple example, E=’len(x)-1’ will enforce that a is considered to be present in any case as the last element of x, if not earlier.

The return value is index ix, by default. If function f is set, the value of f(ix) is returned instead. Even though index ix is a secure number, however, the computation of f(ix) does not incur any communication costs, requiring local computation only. For example, with f=lambda i: 2^i we would save the work for a secure exponentiation, which would otherwise require a call to runtime.to_bits(ix), say.

Also, function cs_f can be set instead of specifying function f directly. Function cs_f(b, i) will take as input a (secure) bit b and a (public) index i. The relationship between function f and its “conditional-step function” cs_f is given by:

cs_f(b, i) = f(i+b), for b in {0, 1} (*)

For example, for f(i) = i, we get cs_f(b, i) = i+b. And, for f(i) = 2^i, we get cs_f(b, i) = 2^(i+b) = (b+1) 2^i. In general, we have:

cs_f(b, i) = b (f(i+1) - f(i)) + f(i), for b in {0, 1} (**)

For this reason, cs_f(b, i) can be computed locally indeed.

A few more examples:

f(i) = i | 2^i | n-i | 2^-i | (i, 2^i)

cs_f(b, i) = i+b | (b+1) 2^i | n-i-b | (2-b) 2^-(i+1) | (i+b, (b+1) 2^i)

In the last example, f(i) is a tuple containing two values. In general, f(i) can be a single number or a tuple/list of numbers.

Note that it suffices to specify either f or cs_f, as (*) implies that f(i) = cs_f(0, i). If cs_f is not set, it will be computed from f using (**), incurring some overhead.

from_bits(x)

Recover secure number from its binary representation x.

gather(*obj)

Gather all results for the given futures (shares).

gauss(A, d, b, c)

Secure Gaussian elimination A d - b c.

gcd(a, b, l=None)

Secure greatest common divisor of a and b.

If provided, l should be an upper bound on the bit lengths of both a and b.

gcdext(a, b, l=None)

Secure extended GCD of secure integers a and b. Return triple (g, s, t) such that g = gcd(a,b) = s*a + t*b.

If provided, l should be an upper bound on the bit lengths of a and b.

gcp2(a, b, l=None)

Secure greatest common power of 2 dividing a and b.

ge(a, b)

Secure comparison a >= b.

if_else(c, x, y)

Secure selection between x and y based on condition c.

if_swap(c, x, y)

Secure swap of x and y based on condition c.

in_prod(x, y)

Secure dot product of x and y (one resharing).

indexOf(x, a, bits=False)

Return index of the first occurrence of a in x.

Raise ValueError if a is not present.

input(x, senders=None)

Input x to the computation.

Value x is a secure object, or a list of secure objects. The senders are the parties that provide an input. The default is to let every party be a sender.

Except for secure integers, secure fixed-point numbers, and secure finite field elements, which are handled directly, the input of secure objects is controlled by their _input() method. For instance, mpyc.sectypes.SecureFloat._input() does this for secure floating-point numbers.

inverse(a, b, l=None)

Secure inverse of a modulo b, assuming a>=0, b>0, and gcd(a,b)=1. The result is nonnegative and less than b (inverse is 0 only when b=1).

If provided, l should be an upper bound on the bit lengths of both a and b.

To compute inverses for negative b, use -b instead of b, and to compute inverses for arbitrary nonzero b, use abs(b) instead of b.

invert(a)

Secure bitwise inverse (not) of a.

is_zero(a)

Secure zero test a == 0.

is_zero_public(a) Future

Secure public zero test of a.

lcm(a, b, l=None)

Secure least common multiple of a and b.

If provided, l should be an upper bound on the bit lengths of both a and b.

logging(enable=None)

Toggle/enable/disable logging.

lsb(a)

Secure least significant bit of a.

lt(a, b)

Secure comparison a < b.

matrix_add(A, B, tr=False)

Secure addition of matrices A and (transposed) B.

matrix_prod(A, B, tr=False)

Secure matrix product of A with (transposed) B.

matrix_sub(A, B, tr=False)

Secure subtraction of matrices A and (transposed) B.

max(*x, key=None)

Secure maximum of all given elements in x, similar to Python’s built-in max().

See runtime.sorted() for details on key etc.

min(*x, key=None)

Secure minimum of all given elements in x, similar to Python’s built-in min().

See runtime.sorted() for details on key etc.

min_max(*x, key=None)

Secure minimum and maximum of all given elements in x.

Saves 25% compared to calling min(x) and max(x) separately. Total number of comparisons is only (3n-3)//2, compared to 2n-2 for the obvious approach. This is optimal as shown by Ira Pohl in “A sorting problem and its complexity”, Communications of the ACM 15(6), pp. 462-464, 1972.

mod(a, b)

Secure modulo reduction.

mul(a, b)

Secure multiplication of a and b.

neg(a)

Secure negation (additive inverse) of a.

np_absolute(a, l=None)

Secure elementwise absolute value of a.

np_add(a, b)

Secure addition of a and b, elementwise with broadcast.

np_all(a, axis=None)

Secure all-predicate for array a, entirely or along the given axis (or axes).

If axis is None (default) all is evaluated over the entire array (returning a scalar). If axis is an int or a tuple of ints, all is evaluated along all specified axes. The shape of the result is the shape of a with all specified axes removed (converted to a scalar if no dimensions remain).

np_amax(a, axis=None, keepdims=False)

Secure maximum of array a, entirely or along the given axis (or axes).

If axis is None (default) the maximum of the array is returned. If axis is an int or a tuple of ints, the minimum along all specified axes is returned.

If keepdims is not set (default), the shape of the result is the shape of a with all specified axes removed (converted to a scalar if no dimensions remain). Otherwise, if keepdims is set, the axes along which the maximum is taken are left in the result as dimensions of size 1.

np_amin(a, axis=None, keepdims=False)

Secure minimum of array a, entirely or along the given axis (or axes).

If axis is None (default) the minimum of the array is returned. If axis is an int or a tuple of ints, the minimum along all specified axes is returned.

If keepdims is not set (default), the shape of the result is the shape of a with all specified axes removed (converted to a scalar if no dimensions remain). Otherwise, if keepdims is set, the axes along which the minimum is taken are left in the result as dimensions of size 1.

np_any(a, axis=None)

Secure any-predicate for array a, entirely or along the given axis (or axes).

If axis is None (default) any is evaluated over the entire array (returning a scalar). If axis is an int or a tuple of ints, any is evaluated along all specified axes. The shape of the result is the shape of a with all specified axes removed (converted to a scalar if no dimensions remain).

np_append(arr, values, axis=None)

Append values to the end of array arr.

If axis is None (default), arr and values are flattened first. Otherwise, arr and values must all be of the same shape, except along the given axis.

np_argmax(a, axis=None, keepdims=False, key=None, arg_unary=False, arg_only=True)

Returns the indices of the maximum values along an axis.

Default behavior similar to np.argmax() for NumPy arrays:

  • the indices are returned as numbers (not as unit vectors),

  • only the indices are returned (maximum values omitted).

NB: Different defaults than for method call a.argmax().

If no axis is given (default), array a is flattened first.

If the indices are returned as unit vectors in an array u say, then u is always of the same shape as the (possibly flattened) input array a.

If the indices are returned as numbers, the shape of the array of indices is controlled by parameter keepdims. If keepdims is not set (default), the shape of the indices is the shape of a with the specified axis removed (converted to a scalar if no dimensions remain). Otherwise, if keepdims is set, the axis along which the maximum is taken is left in the result as dimension of size 1.

If the maximum values are returned as well, the shape of this part of the output is also controlled by parameter keepdims. If keepdims is not set (default), a 1D array of maximum values is returned with one entry per element of the given array a with the given axis removed; if axis is None, the maximum is returned as a scalar. Otherwise, if keepdims is set, the array of maximum values is of the same shape as the given array a except that the dimension of the given axis is reduced to 1; if axis is None, all axes are present as dimensions of size 1.

np_argmin(a, axis=None, keepdims=False, key=None, arg_unary=False, arg_only=True)

Returns the indices of the minimum values along an axis.

Default behavior similar to np.argmin() for NumPy arrays:

  • the indices are returned as numbers (not as unit vectors),

  • only the indices are returned (minimum values omitted).

NB: Different defaults than for method call a.argmin().

If no axis is given (default), array a is flattened first.

If the indices are returned as unit vectors in an array u say, then u is always of the same shape as the (possibly flattened) input array a.

If the indices are returned as numbers, the shape of the array of indices is controlled by parameter keepdims. If keepdims is not set (default), the shape of the indices is the shape of a with the specified axis removed (converted to a scalar if no dimensions remain). Otherwise, if keepdims is set, the axis along which the minimum is taken is left in the result as dimension of size 1.

If the minimum values are returned as well, the shape of this part of the output is also controlled by parameter keepdims. If keepdims is not set (default), a 1D array of minimum values is returned with one entry per element of the given array a with the given axis removed; if axis is None, the minimum is returned as a scalar. Otherwise, if keepdims is set, the array of minimum values is of the same shape as the given array a except that the dimension of the given axis is reduced to 1; if axis is None, all axes are present as dimensions of size 1.

np_block(arrays)

Assemble an array from nested lists of blocks given by arrays.

Blocks in the innermost lists are concatenated along the last axis, then these are concatenated along the second to last axis, and so on until the outermost list is reached.

np_concatenate(arrays, axis=0)

Join a sequence of arrays along an existing axis.

If axis is None, arrays are flattened before use. Default axis is 0.

np_det(A)

Secure determinant for nonsingular matrices.

np_divide(a, b)

Secure division of a and b, for nonzero b, elementwise with broadcast.

np_dsplit(ary, indices_or_sections)

Split array into multiple sub-arrays along the 3rd axis (depth).

np_dstack(tup)

Stack arrays in sequence depth wise (along third axis).

This is equivalent to concatenation along the third axis after 2D arrays of shape (M,N) have been reshaped to (M,N,1) and 1D arrays of shape (N,) have been reshaped to (1,N,1). Rebuilds arrays divided by dsplit.

np_equal(a, b)

Secure comparison a == b, elementwise with broadcast.

np_flatten(a, order='C')

Return 1D copy of a.

Default ‘C’ for row-major order (C style). Alternative ‘F’ for column-major order (Fortran style).

np_fliplr(a)

Reverse the order of elements along axis 1 (left/right).

For a 2D array, this flips the entries in each row in the left/right direction. Columns are preserved, but appear in a different order than before.

np_from_bits(x)

Recover secure numbers from their binary representations in x.

np_fromlist(x)

List of secure numbers to 1D array.

np_getitem(a, key)

Secure array a, index/slice key.

np_hsplit(ary, indices_or_sections)

Split an array into multiple sub-arrays horizontally (column-wise).

np_hstack(tup)

Stack arrays in sequence horizontally (column wise).

This is equivalent to concatenation along the second axis, except for 1D arrays where it concatenates along the first axis. Rebuilds arrays divided by hsplit.

np_is_zero_public(a) Future

Secure public zero test of a, elementwise.

np_less(a, b)

Secure comparison a < b, elementwise with broadcast.

np_matmul(A, B)

Secure matrix product of arrays A and B, with broadcast.

np_maximum(a, b)

Secure elementwise maximum of a and b.

If a and b are of different shapes, they must be broadcastable to a common shape (which is scalar if both a and b are scalars).

np_minimum(a, b)

Secure elementwise minimum of a and b.

If a and b are of different shapes, they must be broadcastable to a common shape (which is scalar if both a and b are scalars).

np_multiply(a, b)

Secure multiplication of a and b, elementwise with broadcast.

np_negative(a)

Secure elementwise negation -a (additive inverse) of a.

np_outer(a, b)

Secure outer product of vectors a and b.

Input arrays a and b are flattened if not already 1D.

np_pow(a, b)

Secure elementwise exponentiation a raised to the power of b, for public integer b.

np_prod(a, axis=None)

Secure product of array elements over a given axis (or axes).

np_random_bits(sftype, n, signed=False)

Return shape-(n,) secure array with uniformly random bits of given type.

np_reciprocal(a)

Secure elementwise reciprocal (multiplicative field inverse) of a, for nonzero a.

np_roll(a, shift, axis=None)

Roll array elements (cyclically) along a given axis.

If axis is None (default), array is flattened before cyclic shift, and original shape is restored afterwards.

np_sgn(a, l=None, LT=False, EQ=False)

Secure elementwise sign(um) of array a.

Return -1 if a < 0 else 0 if a == 0 else 1.

If integer flag l=L is set, it is assumed that -2^(L-1) <= a < 2^(L-1) to save work (compared to the default l=type(a).bit_length).

If Boolean flag LT is set, perform a secure less than zero test instead, and return 1 if a < 0 else 0, saving the work for a secure equality test. If Boolean flag EQ is set, perform a secure equal to zero test instead, and return 1 if a == 0 else 0, saving the work for a secure comparison.

np_sort(a, axis=-1, key=None)

“Returns new array sorted along given axis.

By default, axis=-1. If axis is None, the array is flattened.

Same sorting network as in self._sort().

np_split(ary, indices_or_sections, axis=0)

Split an array into multiple sub-arrays as views into ary.

np_stack(arrays, axis=0)

Join a sequence of arrays along a new axis.

The axis parameter specifies the index of the new axis in the shape of the result. For example, if axis=0 it will be the first dimension and if axis=-1 it will be the last dimension.

np_subtract(a, b)

Secure subtraction of a and b, elementwise with broadcast.

np_sum(a, axis=None, keepdims=False, initial=0)

Secure sum of array elements over a given axis (or axes).

np_swapaxes(a, axis1, axis2)

Interchange two given axes of array a.

For 2D arrays, same as the usual matrix transpose.

np_to_bits(a, l=None)

Secure extraction of l (or all) least significant bits of a.

np_tolist(a)

Return array a as an nested list of Python scalars.

The nested list is a.ndim levels deep (scalar if a.ndim is zero).

np_transpose(a, axes=None)

Reverse (default) or permute the axes of array a.

For 2D arrays, default result is the usual matrix transpose. Parameter axes can be any permutation of 0,…,n-1 for n-dimensional array a.

np_trunc(a, f=None, l=None)

Secure truncation of f least significant bits of (elements of) a.

Probabilistic rounding of a / 2**f (elementwise).

np_unit_vector(a, n)

Length-n unit vector [0]*a + [1] + [0]*(n-1-a) for secret a, assuming 0 <= a < n.

Unit vector returned as secure NumPy array.

NB: Value of a is reduced modulo n (almost for free).

np_update(a, key, value)

Return secure array modified by update a[key]=value.

Also value can be a secure array or object. But key is in the clear.

Differs from __setitem__() which works in-place, returning None. MUST be used as follows: a = np_update(a, key, value).

np_vsplit(ary, indices_or_sections)

Split an array into multiple sub-arrays vertically (row-wise).

np_where(c, a, b)

Return elements chosen from a or b depending on condition c.

The shapes of a, b, and c are broadcast together.

or_(a, b)

Secure bitwise or of a and b.

output(x, receivers=None, threshold=None, raw=False)

Output the value of x to the receivers specified.

Value x is a secure object, or a list of secure objects. The receivers are the parties that will obtain the output. The default is to let every party be a receiver.

A secure integer is output as a Python int, a secure fixed-point number is output as a Python float, and a secure finite field element is output as an MPyC finite field element. Set flag raw=True to suppress output conversion.

For all other types of secure objects their _output() method controls what is output. For instance, mpyc.sectypes.SecureFloat._output() outputs secure floating-point numbers as Python floats. The flag raw is ignored for these types.

pos(a)

Secure unary + applied to a.

pow(a, b)

Secure exponentiation a raised to the power of b, for public integer b.

prfs(bound)

PRFs with codomain range(bound) for pseudorandom secret sharing.

Return a mapping from sets of parties to PRFs.

prod(x, start=1)

Secure product of all elements in x, similar to Python’s math.prod().

Runs in log_2 len(x) rounds).

random = <module 'mpyc.random' from '/home/docs/checkouts/readthedocs.org/user_builds/mpyc/checkouts/latest/mpyc/random.py'>
random_bit(stype, signed=False)

Secure uniformly random bit of the given type.

random_bits(sftype, n, signed=False)

Return n secure uniformly random bits of the given type.

reciprocal(a)

Secure reciprocal (multiplicative field inverse) of a, for nonzero a.

static returnType(*args, wrap=True)

Define return type for MPyC coroutines.

Used in first await expression in an MPyC coroutine.

run(f)

Run the given coroutine or future until it is done.

scalar_mul(a, x)

Secure scalar multiplication of scalar a with vector x.

schur_prod(x, y)

Secure entrywise multiplication of vectors x and y.

class seclist(x=(), sectype=None)
append(other)

Append object to the end of the list.

contains(item)

Check if item occurs in self.

copy()

Return a shallow copy of the list.

count(value)

Return the number of occurrences of value.

extend(other)

Extend list by appending elements from the iterable.

find(value)

Return index of the first occurrence of value.

If value is not present, then index is equal to -1.

index(value)

Return index of the first occurrence of value.

Raise ValueError if value is not present.

insert(key, value)

Insert value before position given by key, where key is either public or secret. The key should fit with the length of the list: 0 <= key <= len(self). The type of value should fit with the type of the list.

If key is a public integer, the behavior is the same as for ordinary lists. If key is a secure number or index, the value is inserted at the secret position.

pop(key=-1)

Remove and return value at position given by key, where key is either public or secret.

If key is a public integer, the behavior is the same as for ordinary lists. If key is a secure number or index, the item at the secret position is removed, where 0 <= key < len(self).

remove(value) Future

Remove first occurrence of value.

Raise ValueError if value is not present.

sort(key=None, reverse=False)

Sort the list in-place, similar to Python’s list.sort().

See runtime.sorted() for details on key etc.

sgn(a, l=None, LT=False, EQ=False)

Secure sign(um) of a, return -1 if a < 0 else 0 if a == 0 else 1.

If integer flag l=L is set, it is assumed that -2^(L-1) <= a < 2^(L-1) to save work (compared to the default l=type(a).bit_length).

If Boolean flag LT is set, perform a secure less than zero test instead, and return 1 if a < 0 else 0, saving the work for a secure equality test. If Boolean flag EQ is set, perform a secure equal to zero test instead, and return 1 if a == 0 else 0, saving the work for a secure comparison.

async shutdown()

Shutdown the MPyC runtime.

Close all connections, if any.

sin(a)

Secure sine of fixed-point number a.

sincos(a)

Secure sine and cosine of fixed-point number a.

See “New Approach for Sine and Cosine in Secure Fixed-Point Arithmetic” by Stan Korzilius and Berry Schoenmakers, which appeared in the proceedings of CSCML 2023, 7th International Symposium on Cyber Security, Cryptology and Machine Learning, LNCS 13914, pp. 307-319, Springer (see https://doi.org/10.1007/978-3-031-34671-2).

sorted(x, key=None, reverse=False)

Return a new securely sorted list with elements from x in ascending order.

Similar to Python’s built-in sorted(), but not stable.

Elements of x are either secure numbers or lists of secure numbers.

Argument key specifies a function applied to all elements of x before comparing them, using only < comparisons (that is, using only the __lt__() method, as for Python’s list.sort()). Default key compares elements of x directly (using identity function ‘lambda a: a’).

async start()

Start the MPyC runtime.

Open connections with other parties, if any.

statistics = <module 'mpyc.statistics' from '/home/docs/checkouts/readthedocs.org/user_builds/mpyc/checkouts/latest/mpyc/statistics.py'>
sub(a, b)

Secure subtraction of a and b.

sum(x, start=0)

Secure sum of all elements in x, similar to Python’s built-in sum().

tan(a)

Secure tangent of fixed-point number a.

property threshold

Threshold for MPC.

async throttler(load_percentage=1.0, name=None)

Throttle runtime by given percentage (default 1.0), using optional name for barrier.

to_bits(a, l=None)

Secure extraction of l (or all) least significant bits of a.

trailing_zeros(a, l=None)

Secure extraction of l least significant (or all) bits of a, only correct up to and including the least significant 1 (if any).

transfer(obj, senders=None, receivers=None, sender_receivers=None) Future

Transfer pickable Python objects between specified parties.

The senders are the parties that provide input. The receivers are the parties that will obtain output. The default is to let every party be a sender as well as a receiver.

The (directed) communication graph specifying which parties sends their message given as obj to which receivers is represented by:

  • either the senders/receivers arguments for a complete bipartite graph,

  • or the sender_receivers argument for an arbitrary graph.

Each party i corresponds to a node in the communication graph. The senders/receivers arguments represent subsets of nodes, in the form of a list, a Python range object, or a Python int. The sender_receivers argument represents a set of arcs, in the form of a list of node pairs or as a Python dict mapping nodes to subsets of nodes.

trunc(x, f=None, l=None)

Secure truncation of f least significant bits of (elements of) x.

Probabilistic rounding of a / 2**f for a in x.

unit_vector(a, n)

Length-n unit vector [0]*a + [1] + [0]*(n-1-a) for secret a, assuming 0 <= a < n.

NB: If a = n, unit vector [1] + [0]*(n-1) is returned. See mpyc.statistics.

vector_add(x, y)

Secure addition of vectors x and y.

vector_sub(x, y)

Secure subtraction of vectors x and y.

xor(a, b)

Secure bitwise xor of a and b.

mpyc.runtime.generate_configs(m, addresses)

Generate party configurations.

Generates m-party configurations from the addresses given as a list of ‘(host, port)’ pairs, specifying the hostnames and port numbers for each party.

Returns a list of ConfigParser instances, which can be saved in m separate INI-files. The party owning an INI-file is indicated by not specifying its hostname (host=’’).

mpyc.runtime.setup()

Setup a runtime.

mpyc.mpctools

This module currently provides alternative implementations for two functions in Python’s itertools and functools modules, respectively.

The alternative implementations can be used as drop-in replacements, however, potentially enhancing the performance when used in secure computations. More specifically, these implementations are aimed at reducing the overall round complexity, possible at the expense of increasing overall space complexity, time complexity, and communication complexity.

mpyc.mpctools.accumulate(x, f=<built-in function add>, initial=<no value>)

For associative function f of two arguments, make an iterator that returns the accumulated results over all (nonempty) prefixes of the given iterable x.

The applications of f are arranged such that the maximum depth is logarithmic in the number of elements of x, potentially at the cost of increasing the total number of applications of f by a logarithmic factor as well.

In contrast, Python’s itertools.accumulate() higher-order function arranges the applications of f in a linear fashion, as in general it cannot be assumed that f is associative (and that the arguments to f are even of the same type).

If initial is provided (possibly equal to None), the accumulation leads off with this initial value so that the output has one more element than the input iterable. Otherwise, the number of elements output matches the input iterable x.

mpyc.mpctools.reduce(f, x, initial=<no value>)

Apply associative function f of two arguments to the items of iterable x.

The applications of f are arranged in a binary tree of logarithmic depth, thus limiting the overall round complexity of the secure computation.

In contrast, Python’s functools.reduce() higher-order function arranges the applications of f in a linear chain (a binary tree of linear depth), and in this case f is not required to be associative; the arguments to f may even be of different types.

If initial is provided (possibly equal to None), it is placed before the items of x (hence effectively serves as a default when x is empty). If no initial value is given and x contains only one item, that item is returned.

mpyc.random

This module provides secure versions of several functions for generating pseudorandom numbers, cf. the random module of Python’s standard library. Each function behaves like its Python counterpart, except that a secure type is required as additional (first) argument.

Additionally, random_unit_vector() generates a random bit vector with exactly one bit set to 1, using approximately log_2 n secure random bits for a bit vector of length n.

Also, random_permutation() and random_derangement() are provided as convenience functions.

Main concern for the implementations is to minimize the randomness complexity, that is, to limit the usage of secure random bits as provided by runtime.random_bits(). Other than this, the code is relatively simple for now.

NB: runtime._random(sectype, n) cannot be used as an alternative to _randbelow(sectype, n) as its output is not uniformly random, except when n is equal to the order of sectype’s finite field.

mpyc.random.choice(sectype, seq)

Uniformly random secret element chosen from seq.

Given seq may contain public and/or secret elements.

If seq is empty, raises IndexError.

mpyc.random.choices(sectype, population, weights=None, *, cum_weights=None, k=1)

List of k uniformly random secret elements chosen from population.

Choices are made with replacement.

Given population may contain public and/or secret elements.

If the relative weights or cumulative weights are not specified, the choices are made with equal probability.

mpyc.random.getrandbits(sectype, k, bits=False)

Uniformly random nonnegative k-bit integer value.

Return bits (instead of number) if requested.

mpyc.random.randint(sectype, a, b)

Uniformly random secret integer between a and b, incl. both endpoints.

mpyc.random.random(sectype)

Uniformly random secret fixed-point number in the range [0.0, 1.0).

mpyc.random.random_derangement(sectype, x)

Uniformly random derangement of given sequence x or range(x).

A derangement is a permutation without fixed points.

mpyc.random.random_permutation(sectype, x)

Uniformly random permutation of given sequence x or range(x).

mpyc.random.random_unit_vector(sectype, n)

Uniformly random secret rotation of [1] + [0]*(n-1).

Expected number of secret random bits needed is ceil(log_2 n) + c, with c a small constant, c < 3.

mpyc.random.randrange(sectype, start, stop=None, step=1)

Uniformly random secret integer in range(start, stop[, step]).

mpyc.random.sample(sectype, population, k)

List of k uniformly random secret elements chosen from population.

Choices are made without replacement.

Given population may contain public and/or secret elements.

If the population contains repeats, then each occurrence is a possible selection in the sample.

To choose a sample in a range of integers, use range as an argument. This is especially fast and space efficient for sampling from a large population, e.g.: sample(sectype, range(10000000), 60).

mpyc.random.shuffle(sectype, x)

Shuffle list x secretly in-place, and return None.

Given list x may contain public or secret elements. Elements of x are all numbers or all lists (of the same length) of numbers.

mpyc.random.uniform(sectype, a, b)

Uniformly random secret fixed-point number N such that a <= N <= b for a <= b and b <= N <= a for b < a.

mpyc.seclists

This module provides a secure (oblivious) alternative to Python lists.

A secure list contains secret-shared numbers. Apart from hiding the contents of the list, however, it is also possible to hide which items are accessed and which items are updated. In principle, only the length of a secure list remains public.

A secure list x can be cast to an ordinary list by using list(x), without affecting the contents of the list. Also, public access to a secure list proceeds the same as for ordinary Python lists, using an index or a slice.

For secure (oblivious) access to a secure list, however, one uses a secret-shared index i, which is either a secure number or a secure unit vector. Index i must be compatible with the secure list x: the type of i must fit with the type of the elements of x and the value of i must fit with the length of list x, that is, 0 <= i < len(x).

Common usage scenarios of secure lists are supported through methods such as sort(), count(), and index(), or can be coded easily. For example, the frequency of values in a list x of secure integers (whose values are known to be between 0 and n-1) is computed by:

s = seclist([0]*n, secint)

for a in x: s[a] += 1

Current implementation is basic, taking advantage of cheap secure dot products, as provided by runtime.in_prod(). Performance for modestly sized lists of lengths 10 to 1000 should be adequate. Later: With better amortized complexity, e.g., square root ORAM.

class mpyc.seclists.secindex(*args, offset=0, sectype=None)

Provisional class to facilitate more efficient manipulation of secure indices.

class mpyc.seclists.seclist(x=(), sectype=None)
append(other)

Append object to the end of the list.

contains(item)

Check if item occurs in self.

copy()

Return a shallow copy of the list.

count(value)

Return the number of occurrences of value.

extend(other)

Extend list by appending elements from the iterable.

find(value)

Return index of the first occurrence of value.

If value is not present, then index is equal to -1.

index(value)

Return index of the first occurrence of value.

Raise ValueError if value is not present.

insert(key, value)

Insert value before position given by key, where key is either public or secret. The key should fit with the length of the list: 0 <= key <= len(self). The type of value should fit with the type of the list.

If key is a public integer, the behavior is the same as for ordinary lists. If key is a secure number or index, the value is inserted at the secret position.

pop(key=-1)

Remove and return value at position given by key, where key is either public or secret.

If key is a public integer, the behavior is the same as for ordinary lists. If key is a secure number or index, the item at the secret position is removed, where 0 <= key < len(self).

remove(value) Future

Remove first occurrence of value.

Raise ValueError if value is not present.

sort(key=None, reverse=False)

Sort the list in-place, similar to Python’s list.sort().

See runtime.sorted() for details on key etc.

mpyc.secgroups

This module provides secure (secret-shared) types of finite groups in MPyC.

Secure versions of all groups supported by the module mpyc.fingroups are available: symmetric groups, quadratic residues, elliptic curve groups, and class groups.

mpyc.secgroups.SecClassGroup(Delta=None, l=None)

Call SecClassGroup(…) is equivalent to SecGrp(ClassGroup(…)), returning secure version of ClassGroup from mpyc.fingroups.

ClassGroup(Delta=None, l=None):

Create type for class group, given (bit length l of) discriminant Delta.

The following conditions are imposed on discriminant Delta:

  • Delta < 0, only supporting class groups of imaginary quadratic field

  • Delta = 1 (mod 4), preferably Delta = 1 (mod 8)

  • -Delta is prime

This implies that Delta is a fundamental discriminant.

mpyc.secgroups.SecEllipticCurve(curvename='Ed25519', coordinates=None)

Call SecEllipticCurve(…) is equivalent to SecGrp(EllipticCurve(…)), returning secure version of EllipticCurve from mpyc.fingroups.

EllipticCurve(curvename=’Ed25519’, coordinates=None):

Create elliptic curve type for a selection of built-in curves. The default coordinates used with these curves are ‘affine’.

The following Edwards curves and Weierstrass curves are built-in:

These curves can be used with ‘affine’ (default) and ‘projective’ coordinates. The Edwards curves can also be used with ‘extended’ coordinates, and the Weierstrass curves with ‘jacobian’ coordinates.

mpyc.secgroups.SecGrp(group)

Secure version of given finite group.

mpyc.secgroups.SecQuadraticResidues(p=None, l=None)

Call SecQuadraticResidues(…) is equivalent to SecGrp(QuadraticResidues(…)), returning secure version of QuadraticResidues from mpyc.fingroups.

QuadraticResidues(p=None, l=None):

Create type for quadratic residues group given (bit length l of) odd prime modulus p.

The group of quadratic residues modulo p is of order n=(p-1)/2. Given bit length l>2, p will be chosen such that n is also an odd prime. If l=2, the only possibility is p=3, hence n=1.

mpyc.secgroups.SecSchnorrGroup(p=None, q=None, g=None, l=None, n=None)

Call SecSchnorrGroup(…) is equivalent to SecGrp(SchnorrGroup(…)), returning secure version of SchnorrGroup from mpyc.fingroups.

SchnorrGroup(p=None, q=None, g=None, l=None, n=None):

Create type for Schnorr group of odd prime order q.

If q is not given, q will be the largest n-bit prime, n>=2. If p is not given, p will be the least l-bit prime, l>n, such that q divides p-1.

If l and/or n are not given, default bit lengths will be set (2<=n<l).

mpyc.secgroups.SecSymmetricGroup(n)

Call SecSymmetricGroup(…) is equivalent to SecGrp(SymmetricGroup(…)), returning secure version of SymmetricGroup from mpyc.fingroups.

SymmetricGroup(n):

Create type for symmetric group of degree n, n>=0.

class mpyc.secgroups.SecureClassGroupForm(value=None)

Common base class for secure (secret-shared) class group forms.

classmethod equality(f1, f2, /)

Return a == b.

classmethod inversion(f, /)

Return @-inverse of a (written ~a).

classmethod operation(f1, f2, /)

Return a @ b.

classmethod operation2(f, /)

Return a @ a.

set_share(value)

Set share to the given value.

The share is set directly (or recursively, for a composite SecureObject), using callbacks if value contains Futures that are not yet done.

class mpyc.secgroups.SecureEllipticCurvePoint(value=None)

Common base class for secure (secret-shared) elliptic curve points.

classmethod equality(a, b, /)

Return a == b.

classmethod inversion(a, /)

Return @-inverse of a (written ~a).

classmethod operation(a, b, /)

Return a @ b.

set_share(value)

Set share to the given value.

The share is set directly (or recursively, for a composite SecureObject), using callbacks if value contains Futures that are not yet done.

class mpyc.secgroups.SecureFiniteGroup(value=None)

Abstract base class for secure (secret-shared) finite groups elements.

classmethod equality(a, b, /)

Return a == b.

classmethod if_else(c, a, b)

Secure selection based on binary condition c between group elements a and b.

Condition c must be of a secure number type compatible with the group, and its value should be 0 or 1. Input a must be compatible with the group as well, either of the secure type cls or of type cls.group. Same for input b.

inverse()

For ease of use.

classmethod inversion(a, /)

Return @-inverse of a (written ~a).

classmethod operation(a, b, /)

Return a @ b.

classmethod operation2(a, /)

Return a @ a.

classmethod repeat(a, x)

Return xth @-power of a (written a^x), for any integral number x.

Base a is either a public or a secure group element. Exponent x is either a public or a secure integral number. Possibly a, x are lists (of same length)

class mpyc.secgroups.SecureQuadraticResidue(value=None)

Common base class for secure (secret-shared) quadratic residues.

classmethod equality(a, b, /)

Return a == b.

classmethod inversion(a, /)

Return @-inverse of a (written ~a).

classmethod operation(a, b, /)

Return a @ b.

set_share(value)

Set share to the given value.

The share is set directly (or recursively, for a composite SecureObject), using callbacks if value contains Futures that are not yet done.

class mpyc.secgroups.SecureSchnorrGroupElement(value=None)

Common base class for secure (secret-shared) Schnorr group elements.

classmethod equality(a, b, /)

Return a == b.

classmethod inversion(a, /)

Return @-inverse of a (written ~a).

classmethod operation(a, b, /)

Return a @ b.

set_share(value)

Set share to the given value.

The share is set directly (or recursively, for a composite SecureObject), using callbacks if value contains Futures that are not yet done.

class mpyc.secgroups.SecureSymmetricGroupElement(value=None)

Common base class for secure (secret-shared) symmetric group elements.

classmethod equality(p, q, /)

Return a == b.

classmethod inversion(p, /)

Return @-inverse of a (written ~a).

classmethod operation(p, q, /)

First p then q.

set_share(value)

Set share to the given value.

The share is set directly (or recursively, for a composite SecureObject), using callbacks if value contains Futures that are not yet done.

mpyc.secgroups.repeat_public_base_public_output(a, x) Future

Multi-exponentiation for given base(s) a and exponent(s) x.

mpyc.secgroups.repeat_public_base_secret_output(a, x, secgrp)

Compute a^[x]->[a^x].

mpyc.secgroups.repeat_secret_base_secret_output(a, x, secgrp)

Compute [a]^[x]->[a^x].

mpyc.statistics

This module provides secure versions of common mathematical statistics functions. The module is modeled after the statistics module in the Python standard library, and as such aimed at small scale use (“at the level of graphing and scientific calculators”).

Functions mean, median, median_low, median_high, quantiles, and mode are provided for calculating averages (measures of central location). Functions variance, stdev, pvariance, pstdev are provided for calculating variability (measures of spread). Functions covariance, correlation, linear_regression are provided for calculating statistics regarding relations between two sets of data.

Most of these functions work best with secure fixed-point numbers, but some effort is done to support the use of secure integers as well. For instance, the mean of a sample of integers is rounded to the nearest integer, which may still be useful. The variance of a sample of integers is also rounded to the nearest integer, but this will only be useful if the sample is properly scaled.

A baseline implementation is provided, favoring simplicity over efficiency. Also, the current implementations of mode, median, and quantiles favor a small privacy leak over a strict but less efficient approach.

If these functions are called with plain data, the call is relayed to the corresponding function in Python’s statistics module.

class mpyc.statistics.LinearRegression(slope, intercept)
intercept

Alias for field number 1

slope

Alias for field number 0

mpyc.statistics.correlation(x, y)

Return Pearson’s correlation coefficient for x and y.

Pearson’s correlation coefficient takes values between -1 and +1. It measures the strength and direction of the linear relationship between x and y, where +1 means very strong, positive linear relationship, -1 very strong, negative linear relationship, and 0 no linear relationship.

mpyc.statistics.covariance(x, y)

Return the sample covariance of x and y.

mpyc.statistics.linear_regression(x, y)

Return a (simple) linear regression model for x and y.

The parameters of the model are returned as a named LinearRegression tuple, with two fields called “slope” and “intercept”, respectively.

A linear regression model describes the relationship between independent variable x and dependent variable y in terms of a linear function:

y = slope * x + intercept + noise

Here, slope and intercept are the regression parameters estimated using ordinary least squares, and noise represents the variability of the data not explained by the linear regression (it is equal to the difference between predicted and actual values of the dependent variable).

mpyc.statistics.mean(data)

Return the sample mean (average) of data which can be a sequence or an iterable.

If the data points are secure integers or secure fixed-point numbers, the mean value returned is of the same secure type, rounded to the nearest number.

If data is empty, StatisticsError will be raised.

mpyc.statistics.median(data)

Return the median of numeric data, using the common “mean of middle two” method.

If data is empty, StatisticsError is raised. data can be a sequence or iterable.

When the number of data points is even, the median is interpolated by taking the average of the two middle values.

mpyc.statistics.median_high(data)

Return the high median of numeric data.

If data is empty, StatisticsError is raised. data can be a sequence or iterable.

The high median is always a member of the data set. When the number of data points is odd, the middle value is returned. When it is even, the larger of the two middle values is returned.

mpyc.statistics.median_low(data)

Return the low median of numeric data.

If data is empty, StatisticsError is raised. data can be a sequence or iterable.

The low median is always a member of the data set. When the number of data points is odd, the middle value is returned. When it is even, the smaller of the two middle values is returned.

mpyc.statistics.mode(data)

Return the mode, the most common data point from discrete or nominal data.

If there are multiple modes with the same frequency, the first one encountered in data is returned.

If data is empty, StatisticsError is raised.

To speed up the computation, the bit length of the sample range max(data) - min(data) is revealed, provided this range is not too small.

mpyc.statistics.pstdev(data, mu=None)

Return the population standard deviation (square root of the population variance).

See pvariance() for arguments and other details.

mpyc.statistics.pvariance(data, mu=None)

Return the population variance of data, an iterable of at least two numbers.

If the optional second argument mu is given, it is typically the mean of the data. It can also be used to compute the second moment around a point that is not the mean. If it is missing or None (the default), the arithmetic mean is automatically calculated.

Use this function to calculate the variance from the entire population. To estimate the variance from a sample, the variance() function is usually a better choice.

Raises StatisticsError if data is empty.

mpyc.statistics.quantiles(data, *, n=4, method='exclusive')

Divide data into n continuous intervals with equal probability.

Returns a list of n-1 cut points separating the intervals.

Set n to 4 for quartiles (the default). Set n to 10 for deciles. Set n to 100 for percentiles which gives the 99 cuts points that separate data into 100 equal sized groups.

The data can be any iterable containing samples. The cut points are linearly interpolated between data points.

If method is set to ‘inclusive’, data is treated as population data. The minimum value is treated as the 0th percentile (lowest quantile) and the maximum value is treated as the 100th percentile (highest quantile).

mpyc.statistics.stdev(data, xbar=None)

Return the sample standard deviation (square root of the sample variance).

See variance() for arguments and other details.

mpyc.statistics.variance(data, xbar=None)

Return the sample variance of data, an iterable of at least two numbers.

If the optional second argument xbar is given, it should be the mean of data. If it is missing or None (the default), the mean is automatically calculated.

Use this function when your data is a sample from a population. To calculate the variance from the entire population, see pvariance().

Raises StatisticsError if data has fewer than two values.