diff --git a/demos/cnnmnist.py b/demos/cnnmnist.py index 0d89b722..edc9d513 100644 --- a/demos/cnnmnist.py +++ b/demos/cnnmnist.py @@ -23,7 +23,7 @@ def scale_to_int(f): if secnum.field.frac_length == 0: - scale = lambda a: secnum(round(a * f)) + scale = lambda a: secnum(int(round(a * f))) # force Python integers else: scale = secnum return np.vectorize(scale) diff --git a/docs/index.html b/docs/index.html index 9171664e..de27b5d4 100644 --- a/docs/index.html +++ b/docs/index.html @@ -6,7 +6,7 @@  
mpyc (version 0.6)
 
- 
mpyc (version 0.5)
index
c:\users\berry\documents\github\mympyc\mpyc\__init__.py

MPyC is a Python package for secure multi-party computation (MPC).
@@ -16,9 +16,9 @@ The MPC protocols are based on Shamir's threshold secret sharing scheme
and withstand passive adversaries controlling less than half of the parties.
 
-Secure finite field arithmetic is supported for fields of prime order
-and fields of characteristic two. Secure integer and fixed-point arithmetic
-is supported for parameterized number ranges, also including support
+Secure finite field arithmetic is supported for fields of arbitrary order, as
+long as the order exceeds the number of parties. Secure integer and fixed-point
+arithmetic is supported for parameterized number ranges, also including support
for comparison and bitwise operations.
These operations are all available via Python's operator overloading.
Some operations for container datatypes holding secret-shared data items
@@ -31,20 +31,22 @@        
asyncoro
-bfield
-gf2x
+finfields
+gfpx
gmpy
-pfield
+mpctools
random
runtime
+seclists
sectypes
+
statistics
thresha
-

+

-
 
Data
       __license__ = 'Apache License 2.0'
+__license__ = 'MIT License' \ No newline at end of file diff --git a/docs/mpyc.asyncoro.html b/docs/mpyc.asyncoro.html index 54525549..c31edeb7 100644 --- a/docs/mpyc.asyncoro.html +++ b/docs/mpyc.asyncoro.html @@ -44,7 +44,7 @@ class SharesExchanger(asyncio.protocols.Protocol)     -SharesExchanger(peer_pid=None)
+SharesExchanger(rt, peer_pid=None)
 
Send and receive shares.
 
@@ -58,15 +58,15 @@


Methods defined here:
-
__init__(self, peer_pid=None)
Initialize self.  See help(type(self)) for accurate signature.
+
__init__(self, rt, peer_pid=None)
Initialize self.  See help(type(self)) for accurate signature.
close_connection(self)
Close connection with the peer.
-
connection_lost(self, exc)
Called when the connection is lost or closed.
+
connection_lost(self, exc)
Called when the connection with the peer is lost or closed.
 
-The argument is an exception object or None (the latter
-meaning a regular EOF is received or the connection was
-aborted 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 (but exc is None is still possible).
connection_made(self, transport)
Called when a connection is made.
 
@@ -137,10 +137,10 @@ Functions         -
gather_shares(*obj)
Gather all results for the given futures (shared values).
+
gather_shares(rt, *obj)
Gather all results for the given futures (shared values).
mpc_coro(func, pc=True)
Decorator turning coroutine func into an MPyC coroutine.
 
-An MPyC coroutine is evaluated asychronously, returning empty placeholders.
+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.
@@ -154,6 +154,5 @@ Data         -pc_level = 0
-runtime = None +runtime = None \ No newline at end of file diff --git a/docs/mpyc.bfield.html b/docs/mpyc.bfield.html deleted file mode 100644 index 3caec048..00000000 --- a/docs/mpyc.bfield.html +++ /dev/null @@ -1,147 +0,0 @@ - -Python: module mpyc.bfield - - - - - -
 
- 
mpyc.bfield
index
c:\users\berry\documents\github\mympyc\mpyc\bfield.py
-

This module supports Galois (finite) fields of characteristic 2.

-Function GF creates types implementing binary fields.
-Instantiate an object from a field and subsequently apply overloaded
-operators such as + (addition), - (subtraction), * (multiplication),
-and / (division), etc., to compute with field elements.
-In-place versions of the field operators are also provided.

-

- - - - - -
 
-Modules
       
mpyc.gf2x
-

- - - - - -
 
-Classes
       
-
builtins.object -
-
-
BinaryFieldElement -
-
-
-

- - - - - - - -
 
-class BinaryFieldElement(builtins.object)
   BinaryFieldElement(value)

-Common base class for binary field elements.

-Invariant: attribute 'value' is reduced.
 
 Methods defined here:
-
__add__(self, other)
Addition.
- -
__bool__(self)
Truth value testing.

-Return False if this field element is zero, True otherwise.
-Field elements can thus be used directly in Boolean formulas.
- -
__eq__(self, other)
Equality test.
- -
__iadd__(self, other)
In-place addition.
- -
__ilshift__(self, other)
In-place left shift.
- -
__imul__(self, other)
In-place multiplication.
- -
__init__(self, value)
Initialize self.  See help(type(self)) for accurate signature.
- -
__int__(self)
Extract polynomial field element as an integer.
- -
__irshift__(self, other)
In-place right shift.
- -
__isub__ = __iadd__(self, other)
- -
__itruediv__(self, other)
In-place division.
- -
__lshift__(self, other)
Left shift.
- -
__mul__(self, other)
Multiplication.
- -
__neg__(self)
Negation.
- -
__pow__(self, other)
Exponentiation.
- -
__radd__ = __add__(self, other)
- -
__repr__(self)
Return repr(self).
- -
__rlshift__(self, other)
Left shift (with reflected arguments).
- -
__rmul__ = __mul__(self, other)
- -
__rrshift__(self, other)
Right shift (with reflected arguments).
- -
__rshift__(self, other)
Right shift.
- -
__rsub__ = __add__(self, other)
- -
__rtruediv__(self, other)
Division (with reflected arguments).
- -
__sub__ = __add__(self, other)
- -
__truediv__(self, other)
Division.
- -
reciprocal(self)
Multiplicative inverse.
- -
-Class methods defined here:
-
to_bytes(x) from builtins.type
Return an array of bytes representing the given list of polynomials x.
- -
-Static methods defined here:
-
from_bytes(data)
Return the list of integers represented by the given array of bytes.
- -
-Data descriptors defined here:
-
value
-
-
-Data and other attributes defined here:
-
__hash__ = None
- -
ext_deg = None
- -
frac_length = 0
- -
modulus = None
- -
order = None
- -

- - - - - -
 
-Functions
       
GF(modulus)
Create a Galois (finite) field for given irreducible polynomial.
-
find_irreducible(d)
Find smallest irreducible polynomial of degree d satisfying given constraints.

-Constraints ... primitive, low weight w=3, 5
-
- \ No newline at end of file diff --git a/docs/mpyc.finfields.html b/docs/mpyc.finfields.html new file mode 100644 index 00000000..58e0b6c4 --- /dev/null +++ b/docs/mpyc.finfields.html @@ -0,0 +1,551 @@ + +Python: module mpyc.finfields + + + + + +
 
+ 
mpyc.finfields
index
c:\users\berry\documents\github\mympyc\mpyc\finfields.py
+

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.

+

+ + + + + +
 
+Modules
       
functools
+
mpyc.gfpx
+
mpyc.gmpy
+

+ + + + + +
 
+Classes
       
+
builtins.object +
+
+
FiniteFieldElement +
+
+
ExtensionFieldElement +
+
+
BinaryFieldElement +
+
+
PrimeFieldElement +
+
+
+
+
+

+ + + + + + + +
 
+class BinaryFieldElement(ExtensionFieldElement)
   BinaryFieldElement(value)

+Common base class for binary field elements.
 
 
Method resolution order:
+
BinaryFieldElement
+
ExtensionFieldElement
+
FiniteFieldElement
+
builtins.object
+
+
+Methods defined here:
+
is_sqr(self)
Test for quadratic residuosity (0 is also square).
+ +
sqrt(self, INV=False)
Modular (inverse) square roots.
+ +
+Data and other attributes defined here:
+
characteristic = 2
+ +
mix_types = (<class 'int'>, <class 'mpyc.gfpx.BinaryPolynomial'>)
+ +
+Methods inherited from ExtensionFieldElement:
+
__eq__(self, other)
Equality test.
+ +
__int__(self)
Extract field element as an integer value.
+ +
__irshift__(self, other)
In-place right shift.
+ +
__pow__(self, other)
+ +
__repr__(self)
Return repr(self).
+ +
__rshift__(self, other)
Right shift.
+ +
reciprocal(self)
Multiplicative inverse.
+ +
+Data and other attributes inherited from ExtensionFieldElement:
+
__hash__ = None
+ +
least_qnr = None
+ +
+Methods inherited from FiniteFieldElement:
+
__add__(self, other)
Addition.
+ +
__bool__(self)
Truth value testing.

+Return False if this field element is zero, True otherwise.
+Field elements can thus be used directly in Boolean formulas.
+ +
__iadd__(self, other)
In-place addition.
+ +
__ilshift__(self, other)
In-place left shift.
+ +
__imul__(self, other)
In-place multiplication.
+ +
__init__(self, value)
Initialize self.  See help(type(self)) for accurate signature.
+ +
__isub__(self, other)
In-place subtraction.
+ +
__itruediv__(self, other)
In-place division.
+ +
__lshift__(self, other)
Left shift.
+ +
__mul__(self, other)
Multiplication.
+ +
__neg__(self)
Negation.
+ +
__pos__(self)
Unary +.
+ +
__radd__(self, other)
Addition (with reflected arguments).
+ +
__rlshift__(self, other)
Left shift (with reflected arguments).
+ +
__rmul__(self, other)
Multiplication (with reflected arguments).
+ +
__rrshift__(self, other)
Right shift (with reflected arguments).
+ +
__rsub__(self, other)
Subtraction (with reflected arguments).
+ +
__rtruediv__(self, other)
Division (with reflected arguments).
+ +
__sub__(self, other)
Subtraction.
+ +
__truediv__(self, other)
Division.
+ +
+Class methods inherited from FiniteFieldElement:
+
to_bytes(x) from builtins.type
Return byte string representing the given list of integers x.
+ +
+Static methods inherited from FiniteFieldElement:
+
from_bytes(data)
Return the list of integers represented by the given byte string.
+ +
+Data descriptors inherited from FiniteFieldElement:
+
value
+
+
+Data and other attributes inherited from FiniteFieldElement:
+
byte_length = None
+ +
ext_deg = None
+ +
frac_length = 0
+ +
is_signed = None
+ +
modulus = None
+ +
order = None
+ +

+ + + + + + + +
 
+class ExtensionFieldElement(FiniteFieldElement)
   ExtensionFieldElement(value)

+Common base class for extension field elements.
 
 
Method resolution order:
+
ExtensionFieldElement
+
FiniteFieldElement
+
builtins.object
+
+
+Methods defined here:
+
__eq__(self, other)
Equality test.
+ +
__int__(self)
Extract field element as an integer value.
+ +
__irshift__(self, other)
In-place right shift.
+ +
__pow__(self, other)
+ +
__repr__(self)
Return repr(self).
+ +
__rshift__(self, other)
Right shift.
+ +
is_sqr(self)
Test for quadratic residuosity (0 is also square).
+ +
reciprocal(self)
Multiplicative inverse.
+ +
sqrt(self, INV=False)
Modular (inverse) square roots.
+ +
+Data and other attributes defined here:
+
__hash__ = None
+ +
least_qnr = None
+ +
mix_types = (<class 'int'>, <class 'mpyc.gfpx.Polynomial'>)
+ +
+Methods inherited from FiniteFieldElement:
+
__add__(self, other)
Addition.
+ +
__bool__(self)
Truth value testing.

+Return False if this field element is zero, True otherwise.
+Field elements can thus be used directly in Boolean formulas.
+ +
__iadd__(self, other)
In-place addition.
+ +
__ilshift__(self, other)
In-place left shift.
+ +
__imul__(self, other)
In-place multiplication.
+ +
__init__(self, value)
Initialize self.  See help(type(self)) for accurate signature.
+ +
__isub__(self, other)
In-place subtraction.
+ +
__itruediv__(self, other)
In-place division.
+ +
__lshift__(self, other)
Left shift.
+ +
__mul__(self, other)
Multiplication.
+ +
__neg__(self)
Negation.
+ +
__pos__(self)
Unary +.
+ +
__radd__(self, other)
Addition (with reflected arguments).
+ +
__rlshift__(self, other)
Left shift (with reflected arguments).
+ +
__rmul__(self, other)
Multiplication (with reflected arguments).
+ +
__rrshift__(self, other)
Right shift (with reflected arguments).
+ +
__rsub__(self, other)
Subtraction (with reflected arguments).
+ +
__rtruediv__(self, other)
Division (with reflected arguments).
+ +
__sub__(self, other)
Subtraction.
+ +
__truediv__(self, other)
Division.
+ +
+Class methods inherited from FiniteFieldElement:
+
to_bytes(x) from builtins.type
Return byte string representing the given list of integers x.
+ +
+Static methods inherited from FiniteFieldElement:
+
from_bytes(data)
Return the list of integers represented by the given byte string.
+ +
+Data descriptors inherited from FiniteFieldElement:
+
value
+
+
+Data and other attributes inherited from FiniteFieldElement:
+
byte_length = None
+ +
characteristic = None
+ +
ext_deg = None
+ +
frac_length = 0
+ +
is_signed = None
+ +
modulus = None
+ +
order = None
+ +

+ + + + + + + +
 
+class FiniteFieldElement(builtins.object)
   FiniteFieldElement(value)

+Abstract base class for finite field elements.

+Invariant: attribute 'value' nonnegative and below modulus.
 
 Methods defined here:
+
__add__(self, other)
Addition.
+ +
__bool__(self)
Truth value testing.

+Return False if this field element is zero, True otherwise.
+Field elements can thus be used directly in Boolean formulas.
+ +
__iadd__(self, other)
In-place addition.
+ +
__ilshift__(self, other)
In-place left shift.
+ +
__imul__(self, other)
In-place multiplication.
+ +
__init__(self, value)
Initialize self.  See help(type(self)) for accurate signature.
+ +
__int__(self)
Extract field element as an integer value.
+ +
__irshift__(self, other)
In-place right shift.
+ +
__isub__(self, other)
In-place subtraction.
+ +
__itruediv__(self, other)
In-place division.
+ +
__lshift__(self, other)
Left shift.
+ +
__mul__(self, other)
Multiplication.
+ +
__neg__(self)
Negation.
+ +
__pos__(self)
Unary +.
+ +
__radd__(self, other)
Addition (with reflected arguments).
+ +
__rlshift__(self, other)
Left shift (with reflected arguments).
+ +
__rmul__(self, other)
Multiplication (with reflected arguments).
+ +
__rrshift__(self, other)
Right shift (with reflected arguments).
+ +
__rshift__(self, other)
Right shift.
+ +
__rsub__(self, other)
Subtraction (with reflected arguments).
+ +
__rtruediv__(self, other)
Division (with reflected arguments).
+ +
__sub__(self, other)
Subtraction.
+ +
__truediv__(self, other)
Division.
+ +
is_sqr(self)
Test for quadratic residuosity (0 is also square).
+ +
reciprocal(self)
Multiplicative inverse.
+ +
sqrt(self, INV=False)
Modular (inverse) square roots.
+ +
+Class methods defined here:
+
to_bytes(x) from builtins.type
Return byte string representing the given list of integers x.
+ +
+Static methods defined here:
+
from_bytes(data)
Return the list of integers represented by the given byte string.
+ +
+Data descriptors defined here:
+
value
+
+
+Data and other attributes defined here:
+
byte_length = None
+ +
characteristic = None
+ +
ext_deg = None
+ +
frac_length = 0
+ +
is_signed = None
+ +
mix_types = None
+ +
modulus = None
+ +
order = None
+ +

+ + + + + + + +
 
+class PrimeFieldElement(FiniteFieldElement)
   PrimeFieldElement(value)

+Common base class for prime field elements.
 
 
Method resolution order:
+
PrimeFieldElement
+
FiniteFieldElement
+
builtins.object
+
+
+Methods defined here:
+
__abs__(self)
Absolute value of (signed) value.
+ +
__eq__(self, other)
Equality test.
+ +
__float__(self)
Extract field element as a (signed) float value.
+ +
__int__(self)
Extract field element as a (signed) integer value.
+ +
__irshift__(self, other)
In-place right shift.
+ +
__pow__(self, other)
Exponentiation.
+ +
__repr__(self)
Return repr(self).
+ +
__rshift__(self, other)
Right shift.
+ +
is_sqr(self)
Test for quadratic residuosity (0 is also square).
+ +
reciprocal(self)
Multiplicative inverse.
+ +
signed(self)
Return signed integer representation, symmetric around zero.
+ +
sqrt(self, INV=False)
Modular (inverse) square roots.
+ +
unsigned(self)
Return unsigned integer representation.
+ +
+Data and other attributes defined here:
+
__hash__ = None
+ +
is_signed = None
+ +
mix_types = <class 'int'>
int([x]) -> integer
+int(x, base=10) -> integer

+Convert a number or string to an integer, or return 0 if no arguments
+are given.  If x is a number, return x.__int__().  For floating point
+numbers, this truncates towards zero.

+If x is not a number or if base is given, then x must be a string,
+bytes, or bytearray instance representing an integer literal in the
+given base.  The literal can be preceded by '+' or '-' and be surrounded
+by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
+Base 0 means to interpret the base from the string as an integer literal.
+>>> int('0b100', base=0)
+4
+ +
nth = None
+ +
root = None
+ +
rshift_factor = 1
+ +
+Methods inherited from FiniteFieldElement:
+
__add__(self, other)
Addition.
+ +
__bool__(self)
Truth value testing.

+Return False if this field element is zero, True otherwise.
+Field elements can thus be used directly in Boolean formulas.
+ +
__iadd__(self, other)
In-place addition.
+ +
__ilshift__(self, other)
In-place left shift.
+ +
__imul__(self, other)
In-place multiplication.
+ +
__init__(self, value)
Initialize self.  See help(type(self)) for accurate signature.
+ +
__isub__(self, other)
In-place subtraction.
+ +
__itruediv__(self, other)
In-place division.
+ +
__lshift__(self, other)
Left shift.
+ +
__mul__(self, other)
Multiplication.
+ +
__neg__(self)
Negation.
+ +
__pos__(self)
Unary +.
+ +
__radd__(self, other)
Addition (with reflected arguments).
+ +
__rlshift__(self, other)
Left shift (with reflected arguments).
+ +
__rmul__(self, other)
Multiplication (with reflected arguments).
+ +
__rrshift__(self, other)
Right shift (with reflected arguments).
+ +
__rsub__(self, other)
Subtraction (with reflected arguments).
+ +
__rtruediv__(self, other)
Division (with reflected arguments).
+ +
__sub__(self, other)
Subtraction.
+ +
__truediv__(self, other)
Division.
+ +
+Class methods inherited from FiniteFieldElement:
+
to_bytes(x) from builtins.type
Return byte string representing the given list of integers x.
+ +
+Static methods inherited from FiniteFieldElement:
+
from_bytes(data)
Return the list of integers represented by the given byte string.
+ +
+Data descriptors inherited from FiniteFieldElement:
+
value
+
+
+Data and other attributes inherited from FiniteFieldElement:
+
byte_length = None
+ +
characteristic = None
+ +
ext_deg = None
+ +
frac_length = 0
+ +
modulus = None
+ +
order = None
+ +

+ + + + + +
 
+Functions
       
GF(modulus, f=0)
Create a finite (Galois) field for given modulus (prime number or irreducible polynomial).
+
find_irreducible(p, d)
Find smallest irreducible polynomial of degree d over GF(p).
+
find_prime_root(l, blum=True, n=1)
Find smallest 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.
+
pGF(modulus, f=0)
Create a finite field for given prime modulus.
+
xGF(p, modulus)
Create a finite field for given irreducible polynomial.
+
+ \ No newline at end of file diff --git a/docs/mpyc.gf2x.html b/docs/mpyc.gf2x.html deleted file mode 100644 index 6171d48e..00000000 --- a/docs/mpyc.gf2x.html +++ /dev/null @@ -1,151 +0,0 @@ - -Python: module mpyc.gf2x - - - - - -
 
- 
mpyc.gf2x
index
c:\users\berry\documents\github\mympyc\mpyc\gf2x.py
-

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

-Polynomials over GF(2) are represented as nonnegative integers.
-The polynomial b_n x^n + ... + b_1 x + b_0 corresponds
-to the integer b_n 2^n + ... + b_1 2 + b_0, for bits b_n,...,b_0.

-The operators +, -, *, <<, //, %, and function divmod are overloaded.
-Using the direct correspondence between polynomials and integers,
-the operators <, <=, >, >=, ==, != are overloaded as well, where
-the zero polynomial is the smallest 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.

-

- - - - - -
 
-Classes
       
-
builtins.object -
-
-
Polynomial -
-
-
-

- - - - - - - -
 
-class Polynomial(builtins.object)
   Polynomial(value, x='x')

-Polynomials over GF(2) represented as nonnegative integers.
 
 Methods defined here:
-
__add__(self, other)
- -
__bool__(self)
Truth value testing.

-Return False if this field element is zero, True otherwise.
-Field elements can thus be used directly in Boolean formulas.
- -
__divmod__(self, other)
- -
__eq__(self, other)
Equality test.
- -
__floordiv__(self, other)
- -
__ge__(self, other)
Greater-than or equal comparison.
- -
__gt__(self, other)
Strictly greater-than comparison.
- -
__hash__(self)
Hash value.
- -
__iadd__(self, other)
- -
__ifloordiv__(self, other)
- -
__ilshift__(self, other)
- -
__imod__(self, other)
- -
__imul__(self, other)
- -
__init__(self, value, x='x')
Initialize self.  See help(type(self)) for accurate signature.
- -
__int__(self)
- -
__isub__ = __iadd__(self, other)
- -
__le__(self, other)
Less-than or equal comparison.
- -
__lshift__(self, other)
- -
__lt__(self, other)
Strictly less-than comparison.
- -
__mod__(self, other)
- -
__mul__(self, other)
- -
__ne__(self, other)
Negated equality testing.
- -
__pow__(self, exponent)
- -
__radd__(self, other)
- -
__rdivmod__(self, other)
- -
__repr__(self)
Return repr(self).
- -
__rfloordiv__(self, other)
- -
__rmod__(self, other)
- -
__rmul__(self, other)
- -
__rsub__ = __radd__(self, other)
- -
__sub__ = __add__(self, other)
- -
degree(self)
Degree of polynomial (-1 for zero polynomial).
- -
is_irreducible(self)
Test polynomial for irreducibility.
- -
-Data descriptors defined here:
-
value
-
-

- - - - - -
 
-Functions
       
add(a, b)
Add polynomials a and b.
-
degree(a)
Degree of polynomial a (-1 if a is zero).
-
divmod_(a, b)
Divide polynomial a by polynomial b with remainder, for nonzero b.
-
from_terms(s, x='x')
Convert string s with sum of powers of x to a polynomial.
-
gcd(a, b)
Greatest common divisor of polynomials a and b.
-
gcdext(a, b)
Extended GCD for polynomials a and b.

-Return d, s, t satisfying s a + t b = d = gcd(a,b).
-
invert(a, b)
Inverse of polynomial a modulo polynomial b, for nonzero b.
-
is_irreducible(a)
Test polynomial a for irreducibility.
-
mod(a, b)
Reduce polynomial a modulo polynomial b, for nonzero b.
-
mul(a, b)
Multiply polynomials a and b.
-
next_irreducible(a)
Return next irreducible polynomial > a.

-NB: 'x' < 'x+1' < 'x^2+x+1' < 'x^3+x+1' < 'x^3+x^2+1' < ...
-
powmod(a, n, b)
Polynomial a to the power of n modulo polynomial b, for nonzero b.
-
to_terms(a, x='x')
Convert polynomial a to a string with sum of powers of x.
-
- \ No newline at end of file diff --git a/docs/mpyc.gfpx.html b/docs/mpyc.gfpx.html new file mode 100644 index 00000000..cba11987 --- /dev/null +++ b/docs/mpyc.gfpx.html @@ -0,0 +1,362 @@ + +Python: module mpyc.gfpx + + + + + +
 
+ 
mpyc.gfpx
index
c:\users\berry\documents\github\mympyc\mpyc\gfpx.py
+

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).

+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.

+

+ + + + + +
 
+Modules
       
functools
+
mpyc.gmpy
+

+ + + + + +
 
+Classes
       
+
builtins.object +
+
+
Polynomial +
+
+
BinaryPolynomial +
+
+
+
+
+

+ + + + + + + +
 
+class BinaryPolynomial(Polynomial)
   BinaryPolynomial(value)

+Polynomials over GF(2) represented as nonnegative integers.
 
 
Method resolution order:
+
BinaryPolynomial
+
Polynomial
+
builtins.object
+
+
+Methods defined here:
+
__int__(self)
+ +
to_bytes(self, length, byteorder)
Return a bytes object representing a polynomial.
+ +
+Data and other attributes defined here:
+
p = 2
+ +
+Methods inherited from Polynomial:
+
__add__(self, other)
+ +
__bool__(self)
Truth value testing.

+Return False if this polynomial is zero, True otherwise.
+ +
__divmod__(self, other)
+ +
__eq__(self, other)
Equality test.
+ +
__floordiv__(self, other)
+ +
__ge__(self, other)
Greater-than or equal comparison.
+ +
__gt__(self, other)
Strictly greater-than comparison.
+ +
__hash__(self)
Make polynomials hashable (e.g., for LRU caching).
+ +
__iadd__(self, other)
+ +
__ifloordiv__(self, other)
+ +
__ilshift__(self, other)
+ +
__imod__(self, other)
+ +
__imul__(self, other)
+ +
__init__(self, value)
Initialize self.  See help(type(self)) for accurate signature.
+ +
__irshift__(self, other)
+ +
__isub__(self, other)
+ +
__le__(self, other)
Less-than or equal comparison.
+ +
__lshift__(self, other)
+ +
__lt__(self, other)
Strictly less-than comparison.
+ +
__mod__(self, other)
+ +
__mul__(self, other)
+ +
__ne__(self, other)
Negated equality test.
+ +
__neg__(self)
+ +
__pos__(self)
+ +
__pow__(self, other)
+ +
__radd__ = __add__(self, other)
+ +
__rdivmod__(self, other)
+ +
__repr__(self)
Return repr(self).
+ +
__rfloordiv__(self, other)
+ +
__rlshift__(self, other)
+ +
__rmod__(self, other)
+ +
__rmul__ = __mul__(self, other)
+ +
__rrshift__(self, other)
+ +
__rshift__(self, other)
+ +
__rsub__(self, other)
+ +
__sub__(self, other)
+ +
degree(self)
Degree of polynomial (-1 for zero polynomial).
+ +
+Class methods inherited from Polynomial:
+
add(a, b) from builtins.type
Add polynomials a and b.
+ +
deg(a) from builtins.type
Degree of polynomial a (-1 if a is zero polynomial).
+ +
divmod(a, b) from builtins.type
Divide polynomial a by polynomial b with remainder, for nonzero b.
+ +
from_terms(s, x='x') from builtins.type
Convert string s with sum of powers of x to a polynomial.
+ +
gcd(a, b) from builtins.type
Greatest common divisor of polynomials a and b.
+ +
gcdext(a, b) from builtins.type
Extended GCD for polynomials a and b.

+Return d, s, t satisfying s a + t b = d = gcd(a,b).
+ +
invert(a, b) from builtins.type
Inverse of polynomial a modulo polynomial b, for nonzero b.
+ +
is_irreducible(a) from builtins.type
Test polynomial a for irreducibility.
+ +
lshift(a, n) from builtins.type
Multiply polynomial a by X^n.
+ +
mod(a, b) from builtins.type
Reduce polynomial a modulo polynomial b, for nonzero b.
+ +
mul(a, b) from builtins.type
Multiply polynomials a and b.
+ +
next_irreducible(a) from builtins.type
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.
+ +
powmod(a, n, b) from builtins.type
Polynomial a to the power of n modulo polynomial b, for nonzero b.
+ +
rshift(a, n) from builtins.type
Quotient for polynomial a divided by X^n, assuming a is multiple of X^n.
+ +
sub(a, b) from builtins.type
Subtract polynomials a and b.
+ +
to_terms(a, x='x') from builtins.type
Convert polynomial a to a string with sum of powers of x.
+ +
+Data descriptors inherited from Polynomial:
+
value
+
+

+ + + + + + + +
 
+class Polynomial(builtins.object)
   Polynomial(value)

+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).
 
 Methods defined here:
+
__add__(self, other)
+ +
__bool__(self)
Truth value testing.

+Return False if this polynomial is zero, True otherwise.
+ +
__divmod__(self, other)
+ +
__eq__(self, other)
Equality test.
+ +
__floordiv__(self, other)
+ +
__ge__(self, other)
Greater-than or equal comparison.
+ +
__gt__(self, other)
Strictly greater-than comparison.
+ +
__hash__(self)
Make polynomials hashable (e.g., for LRU caching).
+ +
__iadd__(self, other)
+ +
__ifloordiv__(self, other)
+ +
__ilshift__(self, other)
+ +
__imod__(self, other)
+ +
__imul__(self, other)
+ +
__init__(self, value)
Initialize self.  See help(type(self)) for accurate signature.
+ +
__int__(self)
+ +
__irshift__(self, other)
+ +
__isub__(self, other)
+ +
__le__(self, other)
Less-than or equal comparison.
+ +
__lshift__(self, other)
+ +
__lt__(self, other)
Strictly less-than comparison.
+ +
__mod__(self, other)
+ +
__mul__(self, other)
+ +
__ne__(self, other)
Negated equality test.
+ +
__neg__(self)
+ +
__pos__(self)
+ +
__pow__(self, other)
+ +
__radd__ = __add__(self, other)
+ +
__rdivmod__(self, other)
+ +
__repr__(self)
Return repr(self).
+ +
__rfloordiv__(self, other)
+ +
__rlshift__(self, other)
+ +
__rmod__(self, other)
+ +
__rmul__ = __mul__(self, other)
+ +
__rrshift__(self, other)
+ +
__rshift__(self, other)
+ +
__rsub__(self, other)
+ +
__sub__(self, other)
+ +
degree(self)
Degree of polynomial (-1 for zero polynomial).
+ +
to_bytes(self, length, byteorder)
Return a bytes object representing a polynomial.
+ +
+Class methods defined here:
+
add(a, b) from builtins.type
Add polynomials a and b.
+ +
deg(a) from builtins.type
Degree of polynomial a (-1 if a is zero polynomial).
+ +
divmod(a, b) from builtins.type
Divide polynomial a by polynomial b with remainder, for nonzero b.
+ +
from_terms(s, x='x') from builtins.type
Convert string s with sum of powers of x to a polynomial.
+ +
gcd(a, b) from builtins.type
Greatest common divisor of polynomials a and b.
+ +
gcdext(a, b) from builtins.type
Extended GCD for polynomials a and b.

+Return d, s, t satisfying s a + t b = d = gcd(a,b).
+ +
invert(a, b) from builtins.type
Inverse of polynomial a modulo polynomial b, for nonzero b.
+ +
is_irreducible(a) from builtins.type
Test polynomial a for irreducibility.
+ +
lshift(a, n) from builtins.type
Multiply polynomial a by X^n.
+ +
mod(a, b) from builtins.type
Reduce polynomial a modulo polynomial b, for nonzero b.
+ +
mul(a, b) from builtins.type
Multiply polynomials a and b.
+ +
next_irreducible(a) from builtins.type
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.
+ +
powmod(a, n, b) from builtins.type
Polynomial a to the power of n modulo polynomial b, for nonzero b.
+ +
rshift(a, n) from builtins.type
Quotient for polynomial a divided by X^n, assuming a is multiple of X^n.
+ +
sub(a, b) from builtins.type
Subtract polynomials a and b.
+ +
to_terms(a, x='x') from builtins.type
Convert polynomial a to a string with sum of powers of x.
+ +
+Data descriptors defined here:
+
value
+
+
+Data and other attributes defined here:
+
p = None
+ +

+ + + + + +
 
+Functions
       
GFpX(p)
Create type for polynomials over GF(p).
+

+ + + + + +
 
+Data
       X = 'x'
+ \ No newline at end of file diff --git a/docs/mpyc.gmpy.html b/docs/mpyc.gmpy.html index b2c30aa8..e0ad01e0 100644 --- a/docs/mpyc.gmpy.html +++ b/docs/mpyc.gmpy.html @@ -11,6 +11,8 @@ >index
c:\users\berry\documents\github\mympyc\mpyc\gmpy.py

This module collects all gmpy2 functions used by MPyC.
 
+Plus a function for factoring prime powers.

Stubs of limited functionality and efficiency are provided
in case the gmpy2 package is not available.

@@ -20,15 +22,26 @@ Functions         -

invert(...)
invert(x, m) -> mpz
+
factor_prime_power(x)
Return p and d for a prime power x = p**d.
+
invert(...)
invert(x, m) -> mpz
 
Return y such that x*y == 1 (mod m). Raises ZeroDivisionError if no
inverse exists.
+
iroot(...)
iroot(x,n) -> (number, boolean)

+Return the integer n-th root of x and boolean value that is True
+iff the root is exact. x >= 0. n > 0.
is_prime(...)
is_prime(x[, n=25]) -> bool
 
Return True if x is _probably_ prime, else False if x is
definitely composite. x is checked for small divisors and up
to n Miller-Rabin tests are performed.
+
is_square(...)
is_square(x) -> bool

+Returns True if x is a perfect square, else return False.
+
isqrt(...)
isqrt(x) -> mpz

+Return the integer square root of an integer x. x >= 0.
legendre(...)
legendre(x, y) -> mpz
 
Return the Legendre symbol (x|y). y is assumed to be an odd prime.
diff --git a/docs/mpyc.html b/docs/mpyc.html index 9171664e..de27b5d4 100644 --- a/docs/mpyc.html +++ b/docs/mpyc.html @@ -6,7 +6,7 @@  
mpyc (version 0.6)
 
- 
mpyc (version 0.5)
index
c:\users\berry\documents\github\mympyc\mpyc\__init__.py

MPyC is a Python package for secure multi-party computation (MPC).
@@ -16,9 +16,9 @@ The MPC protocols are based on Shamir's threshold secret sharing scheme
and withstand passive adversaries controlling less than half of the parties.
 
-Secure finite field arithmetic is supported for fields of prime order
-and fields of characteristic two. Secure integer and fixed-point arithmetic
-is supported for parameterized number ranges, also including support
+Secure finite field arithmetic is supported for fields of arbitrary order, as
+long as the order exceeds the number of parties. Secure integer and fixed-point
+arithmetic is supported for parameterized number ranges, also including support
for comparison and bitwise operations.
These operations are all available via Python's operator overloading.
Some operations for container datatypes holding secret-shared data items
@@ -31,20 +31,22 @@        
asyncoro
-bfield
-gf2x
+finfields
+gfpx
gmpy
-pfield
+mpctools
random
runtime
+seclists
sectypes
+
statistics
thresha
-

+

-
 
Data
       __license__ = 'Apache License 2.0'
+__license__ = 'MIT License' \ No newline at end of file diff --git a/docs/mpyc.mpctools.html b/docs/mpyc.mpctools.html new file mode 100644 index 00000000..ee925a47 --- /dev/null +++ b/docs/mpyc.mpctools.html @@ -0,0 +1,63 @@ + +Python: module mpyc.mpctools + + + + + +
 
+ 
mpyc.mpctools
index
c:\users\berry\documents\github\mympyc\mpyc\mpctools.py
+

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.

+

+ + + + + +
 
+Modules
       
operator
+

+ + + + + +
 
+Functions
       
accumulate(x, f=<built-in function add>, iv=None)
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, 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 iv is provided, 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.
+
reduce(f, x, iv=None)
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 iv is provided, it is placed before the items of x (hence effectively
+serves as a default when x is empty). If iv is not given and x contains
+only one item, that item is returned.
+
+ \ No newline at end of file diff --git a/docs/mpyc.pfield.html b/docs/mpyc.pfield.html deleted file mode 100644 index f42965ab..00000000 --- a/docs/mpyc.pfield.html +++ /dev/null @@ -1,167 +0,0 @@ - -Python: module mpyc.pfield - - - - - -
 
- 
mpyc.pfield
index
c:\users\berry\documents\github\mympyc\mpyc\pfield.py
-

This module supports Galois (finite) fields of prime order.

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

-

- - - - - -
 
-Modules
       
mpyc.gmpy
-

- - - - - -
 
-Classes
       
-
builtins.object -
-
-
PrimeFieldElement -
-
-
-

- - - - - - - -
 
-class PrimeFieldElement(builtins.object)
   PrimeFieldElement(value)

-Common base class for prime field elements.

-Invariant: attribute 'value' nonnegative and below prime modulus.
 
 Methods defined here:
-
__abs__(self)
Absolute value of (signed) value.
- -
__add__(self, other)
Addition.
- -
__bool__(self)
Truth value testing.

-Return False if this field element is zero, True otherwise.
-Field elements can thus be used directly in Boolean formulas.
- -
__eq__(self, other)
Equality test.
- -
__float__(self)
Extract (signed) float value from the field element.
- -
__iadd__(self, other)
In-place addition.
- -
__ilshift__(self, other)
In-place left shift.
- -
__imul__(self, other)
In-place multiplication.
- -
__init__(self, value)
Initialize self.  See help(type(self)) for accurate signature.
- -
__int__(self)
Extract (signed) integer value from the field element.
- -
__irshift__(self, other)
In-place right shift.
- -
__isub__(self, other)
In-place subtraction.
- -
__itruediv__(self, other)
In-place division.
- -
__lshift__(self, other)
Left shift.
- -
__mul__(self, other)
Multiplication.
- -
__neg__(self)
Negation.
- -
__pow__(self, exponent)
Exponentiation.
- -
__radd__ = __add__(self, other)
- -
__repr__(self)
Return repr(self).
- -
__rlshift__(self, other)
Left shift (with reflected arguments).
- -
__rmul__ = __mul__(self, other)
- -
__rrshift__(self, other)
Right shift (with reflected arguments).
- -
__rshift__(self, other)
Right shift.
- -
__rsub__(self, other)
Subtraction (with reflected arguments).
- -
__rtruediv__(self, other)
Division (with reflected arguments).
- -
__sub__(self, other)
Subtraction.
- -
__truediv__(self, other)
Division.
- -
is_sqr(self)
Test for quadratic residuosity (0 is also square).
- -
reciprocal(self)
Multiplicative inverse.
- -
signed(self)
Return signed integer representation, symmetric around zero.
- -
sqrt(self, INV=False)
Modular (inverse) square roots.
- -
unsigned(self)
Return unsigned integer representation.
- -
-Class methods defined here:
-
to_bytes(x) from builtins.type
Return an array of bytes representing the given list of integers x.
- -
-Static methods defined here:
-
from_bytes(data)
Return the list of integers represented by the given array of bytes.
- -
-Data descriptors defined here:
-
value
-
-
-Data and other attributes defined here:
-
__hash__ = None
- -
frac_length = 0
- -
is_signed = None
- -
modulus = None
- -
nth = None
- -
order = None
- -
root = None
- -
rshift_factor = 1
- -

- - - - - -
 
-Functions
       
GF(modulus, f=0)
Create a Galois (finite) field for given prime modulus.
-
find_prime_root(l, blum=True, n=1)
Find smallest 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.
-
- \ No newline at end of file diff --git a/docs/mpyc.random.html b/docs/mpyc.random.html index d1c1765a..d7fc2db1 100644 --- a/docs/mpyc.random.html +++ b/docs/mpyc.random.html @@ -87,7 +87,7 @@ 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).

-
shuffle(sectype, x)
Shuffle list x secretly in place, and return None.
+
shuffle(sectype, x)
Shuffle list x secretly in-place, and return None.
 
Given list x may contain public or secret elements.
uniform(sectype, a, b)
Uniformly random secret fixed-point number N such that
diff --git a/docs/mpyc.runtime.html b/docs/mpyc.runtime.html index 76944fec..dd566c5d 100644 --- a/docs/mpyc.runtime.html +++ b/docs/mpyc.runtime.html @@ -12,8 +12,8 @@

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 fields of prime order and
-fields of characteristic two. MPyC provides secure number types and operations,
+Shamir's threshold secret sharing scheme is used for finite fields of any order
+exceeding the number of parties. MPyC provides secure number types and operations,
many of which are available through Python's mechanism for operator overloading.

@@ -26,17 +26,18 @@ asyncio
mpyc.asyncoro
configparser
+datetime
functools
itertools
logging
math
-
mpyc
-os
+mpyc
+
os
secrets
mpyc.sectypes
-
ssl
+ssl
sys
-mpyc.thresha
+
mpyc.thresha
time

@@ -97,8 +98,14 @@ to enable distributed computation (without secret sharing).
 
  Methods defined here:
+
__aenter__(self)
Start MPyC runtime when entering async with context.
+ +
__aexit__(self, exc_type, exc, tb)
Shutdown MPyC runtime when exiting async with context.
+
__init__(self, pid, parties, options)
Initialize runtime.
+
abs(self, a)
Secure absolute value of a.
+
add(self, a, b)
Secure addition of a and b.
add_bits(self, x, y)
Secure binary addition of bit vectors x and y.
@@ -107,6 +114,11 @@
barrier(self)
Barrier for runtime.
+
convert(self, x, ttype)
Secure conversion of (elements of) x to given ttype.

+Value x is a secure number, or a list of secure numbers.
+Converted values assumed to fit in target type.
+
div(self, a, b)
Secure division of a by b, for nonzero b.
eq(self, a, b)
Secure comparison a == b.
@@ -115,6 +127,8 @@
from_bits(self, x)
Recover secure number from its binary representation x.
+
gather(self, *obj)
+
gauss(self, A, d, b, c)
Secure Gaussian elimination A d - b c.
ge(self, a, b)
Secure comparison a >= b.
@@ -135,8 +149,6 @@
is_zero_public(self, a) -> _asyncio.Future
Secure public zero test of a.
-
lin_comb(self, a, x)
Secure linear combination: dot product of public a and secret x.
-
logging(self, enable=None)
Toggle/enable/disable logging.
lsb(self, a)
Secure least significant bit of a.
@@ -151,6 +163,12 @@
min(self, *x)
Secure minimum of all given elements in x.
+
min_max(self, *x)
Secure minimum and maximum of all given elements in x.

+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(self, a, b)
Secure modulo reduction.
mul(self, a, b)
Secure multiplication of a and b.
@@ -165,7 +183,9 @@ The receivers are the parties that will obtain the output.
The default is to let every party be a receiver. -
pow(self, a, b)
Secure exponentation a raised to the power of b, for public integer b.
+
pos(self, a)
Secure unary + applied to a.
+ +
pow(self, a, b)
Secure exponentiation a raised to the power of b, for public integer b.
prfs(self, bound)
PRFs with codomain range(bound) for pseudorandom secret sharing.
 
@@ -185,9 +205,9 @@
schur_prod(self, x, y)
Secure entrywise multiplication of vectors x and y.
-
sgn(self, a, EQ=False, GE=False)
Secure sign(um) of a, -1 if a < 0 else 0 if a == 0 else 1.
+
sgn(self, a, EQ=False, GE=False, l=None)
Secure sign(um) of a, -1 if a < 0 else 0 if a == 0 else 1.
-
shutdown(self)
Shutdown the MPC runtime.
+
shutdown(self)
Shutdown the MPyC runtime.
 
Close all connections, if any.
@@ -199,12 +219,18 @@
sum(self, x)
Secure sum of all elements in x.
+
throttler(self, load_percentage=1.0)
Throttle runtime by given percentage (default 1.0).
+
to_bits(self, a, l=None)
Secure extraction of l (or all) least significant bits of a.
trunc(self, 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(self, 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(self, x, y)
Secure addition of vectors x and y.
vector_sub(self, x, y)
Secure subtraction of vectors x and y.
@@ -213,11 +239,13 @@
Static methods defined here:
-
SecFld(order=None, modulus=None, char2=None, l=None)
Secure prime or binary field of (l+1)-bit order.
+
SecFld(order=None, modulus=None, char=None, ext_deg=None, min_order=None, signed=False)
Secure finite field of order q = p**d.
 
-Field is prime by default, and if order (or modulus) is prime.
-Field is binary if order is a power of 2, if modulus is a
-polynomial, or if char2 is True.
+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.
SecFxp(l=None, f=None, p=None, n=2)
Secure l-bit fixed-point numbers with f-bit fractional part.
 
@@ -227,13 +255,11 @@
coroutine = mpc_coro(func, pc=True)
Decorator turning coroutine func into an MPyC coroutine.
 
-An MPyC coroutine is evaluated asychronously, returning empty placeholders.
+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.
-
gather = gather_shares(*obj)
Gather all results for the given futures (shared values).
-
returnType(*args, wrap=True)
Define return type for MPyC coroutines.
 
Used in first await expression in an MPyC coroutine.
@@ -253,7 +279,9 @@ Data and other attributes defined here:
random = <module 'mpyc.random' from 'C:\\Users\\Berry\\Documents\\GitHub\\mympyc\\mpyc\\random.py'>
-
version = '0.5'
+
statistics = <module 'mpyc.statistics' from 'C:\\Users\\Berry\\Documents\\GitHub\\mympyc\\mpyc\\statistics.py'>
+ +
version = '0.6'

diff --git a/docs/mpyc.seclists.html b/docs/mpyc.seclists.html new file mode 100644 index 00000000..f30b4efa --- /dev/null +++ b/docs/mpyc.seclists.html @@ -0,0 +1,315 @@ + +Python: module mpyc.seclists + + + +
+ +
 
+ 
mpyc.seclists
index
c:\users\berry\documents\github\mympyc\mpyc\seclists.py
+

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

+A secure list contains secret-shared values. 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 functions such as count()
+and index(), or can be coded easily. For example, the frequency of values in a list x
+of secure integers (which 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.

+

+ + + + + +
 
+Modules
       
mpyc.asyncoro
+

+ + + + + +
 
+Classes
       
+
builtins.list(builtins.object) +
+
+
secindex +
seclist +
+
+
+

+ + + + + + + +
 
+class secindex(builtins.list)
   secindex(*args, offset=0, sectype=None)

+Provisional class to facilitate more efficient manipulation of secure indices.
 
 
Method resolution order:
+
secindex
+
builtins.list
+
builtins.object
+
+
+Methods defined here:
+
__add__(self, other)
Return self+value.
+ +
__await__(self)
+ +
__index__(self)
+ +
__init__(self, *args, offset=0, sectype=None)
Initialize self.  See help(type(self)) for accurate signature.
+ +
+Static methods defined here:
+
random(sectype, length, offset=0)
+ +
+Data descriptors defined here:
+
__dict__
+
dictionary for instance variables (if defined)
+
+
__weakref__
+
list of weak references to the object (if defined)
+
+
+Methods inherited from builtins.list:
+
__contains__(self, key, /)
Return key in self.
+ +
__delitem__(self, key, /)
Delete self[key].
+ +
__eq__(self, value, /)
Return self==value.
+ +
__ge__(self, value, /)
Return self>=value.
+ +
__getattribute__(self, name, /)
Return getattr(self, name).
+ +
__getitem__(...)
x.__getitem__(y) <==> x[y]
+ +
__gt__(self, value, /)
Return self>value.
+ +
__iadd__(self, value, /)
Implement self+=value.
+ +
__imul__(self, value, /)
Implement self*=value.
+ +
__iter__(self, /)
Implement iter(self).
+ +
__le__(self, value, /)
Return self<=value.
+ +
__len__(self, /)
Return len(self).
+ +
__lt__(self, value, /)
Return self<value.
+ +
__mul__(self, value, /)
Return self*value.
+ +
__ne__(self, value, /)
Return self!=value.
+ +
__repr__(self, /)
Return repr(self).
+ +
__reversed__(self, /)
Return a reverse iterator over the list.
+ +
__rmul__(self, value, /)
Return value*self.
+ +
__setitem__(self, key, value, /)
Set self[key] to value.
+ +
__sizeof__(self, /)
Return the size of the list in memory, in bytes.
+ +
append(self, object, /)
Append object to the end of the list.
+ +
clear(self, /)
Remove all items from list.
+ +
copy(self, /)
Return a shallow copy of the list.
+ +
count(self, value, /)
Return number of occurrences of value.
+ +
extend(self, iterable, /)
Extend list by appending elements from the iterable.
+ +
index(self, value, start=0, stop=9223372036854775807, /)
Return first index of value.

+Raises ValueError if the value is not present.
+ +
insert(self, index, object, /)
Insert object before index.
+ +
pop(self, index=-1, /)
Remove and return item at index (default last).

+Raises IndexError if list is empty or index is out of range.
+ +
remove(self, value, /)
Remove first occurrence of value.

+Raises ValueError if the value is not present.
+ +
reverse(self, /)
Reverse *IN PLACE*.
+ +
sort(self, /, *, key=None, reverse=False)
Stable sort *IN PLACE*.
+ +
+Static methods inherited from builtins.list:
+
__new__(*args, **kwargs) from builtins.type
Create and return a new object.  See help(type) for accurate signature.
+ +
+Data and other attributes inherited from builtins.list:
+
__hash__ = None
+ +

+ + + + + + + +
 
+class seclist(builtins.list)
   seclist(x=(), sectype=None)

+Built-in mutable sequence.

+If no argument is given, the constructor creates a new empty list.
+The argument must be an iterable if specified.
 
 
Method resolution order:
+
seclist
+
builtins.list
+
builtins.object
+
+
+Methods defined here:
+
__add__(self, other)
Return self+value.
+ +
__contains__(self, item)
Check if item occurs in self.
+ +
__getitem__(self, key)
Called to evaluate self[key], where key is either public or secret.

+If key is a public integer (or a slice), the behavior is the same as for ordinary lists.
+If key is a secure number or index, the value at the secret position is returned.
+ +
__iadd__(self, other)
Implement self+=value.
+ +
__init__(self, x=(), sectype=None)
Build a secure list from the items in iterable x using the given secure type.

+If no secure type is given, it is inferred from the items in x.

+Invariant: all items in x are of the same secure type.
+ +
__radd__(self, other)
+ +
__setitem__(self, key, value)
Called to set self[key] = value, where key is either public or secret.
+The type of value should fit with the type of the list.

+If key is a public integer (or a slice), the behavior is the same as for ordinary lists.
+If key is a secure number or index, the list is updated at the secret position.
+ +
append(self, other)
Append object to the end of the list.
+ +
copy(self)
Return a shallow copy of the list.
+ +
count(self, value)
Return the number of occurrences of value.
+ +
extend(self, other)
Extend list by appending elements from the iterable.
+ +
find(self, value)
Return index of the first occurrence of value.

+If value is not present, then index is equal to len(self).
+ +
index(self, value)
Return index of the first occurrence of value.

+Raise ValueError if value is not present.
+ +
+Data descriptors defined here:
+
__dict__
+
dictionary for instance variables (if defined)
+
+
__weakref__
+
list of weak references to the object (if defined)
+
+
+Methods inherited from builtins.list:
+
__delitem__(self, key, /)
Delete self[key].
+ +
__eq__(self, value, /)
Return self==value.
+ +
__ge__(self, value, /)
Return self>=value.
+ +
__getattribute__(self, name, /)
Return getattr(self, name).
+ +
__gt__(self, value, /)
Return self>value.
+ +
__imul__(self, value, /)
Implement self*=value.
+ +
__iter__(self, /)
Implement iter(self).
+ +
__le__(self, value, /)
Return self<=value.
+ +
__len__(self, /)
Return len(self).
+ +
__lt__(self, value, /)
Return self<value.
+ +
__mul__(self, value, /)
Return self*value.
+ +
__ne__(self, value, /)
Return self!=value.
+ +
__repr__(self, /)
Return repr(self).
+ +
__reversed__(self, /)
Return a reverse iterator over the list.
+ +
__rmul__(self, value, /)
Return value*self.
+ +
__sizeof__(self, /)
Return the size of the list in memory, in bytes.
+ +
clear(self, /)
Remove all items from list.
+ +
insert(self, index, object, /)
Insert object before index.
+ +
pop(self, index=-1, /)
Remove and return item at index (default last).

+Raises IndexError if list is empty or index is out of range.
+ +
remove(self, value, /)
Remove first occurrence of value.

+Raises ValueError if the value is not present.
+ +
reverse(self, /)
Reverse *IN PLACE*.
+ +
sort(self, /, *, key=None, reverse=False)
Stable sort *IN PLACE*.
+ +
+Static methods inherited from builtins.list:
+
__new__(*args, **kwargs) from builtins.type
Create and return a new object.  See help(type) for accurate signature.
+ +
+Data and other attributes inherited from builtins.list:
+
__hash__ = None
+ +

+ + + + + +
 
+Data
       runtime = None
+ \ No newline at end of file diff --git a/docs/mpyc.sectypes.html b/docs/mpyc.sectypes.html index 4deb679f..e1841f56 100644 --- a/docs/mpyc.sectypes.html +++ b/docs/mpyc.sectypes.html @@ -21,11 +21,11 @@        
asyncio
-mpyc.bfield
+mpyc.finfields
functools
-mpyc.gf2x
+mpyc.gfpx
mpyc.gmpy
-mpyc.pfield
+math

@@ -68,6 +68,8 @@
Methods defined here:
+
__abs__(self)
Currently no support at all.
+
__and__(self, other)
Bitwise and for binary fields (otherwise 1-bit only).
__divmod__(self, other)
Currently no support at all.
@@ -124,6 +126,8 @@
__neg__(self)
Negation.
+
__pos__(self)
Unary +.
+
__pow__(self, other)
Exponentation for public integral exponent.
__radd__ = __add__(self, other)
@@ -170,6 +174,8 @@
Methods inherited from Share:
+
__abs__(self)
Absolute value.
+
__add__(self, other)
Addition.
__and__(self, other)
Bitwise and, for now 1-bit only.
@@ -206,6 +212,8 @@
__or__(self, other)
Bitwise or, for now 1-bit only.
+
__pos__(self)
Unary +.
+
__pow__(self, other)
Exponentation for public integral exponent.
__radd__ = __add__(self, other)
@@ -266,6 +274,8 @@
Methods inherited from Share:
+
__abs__(self)
Absolute value.
+
__add__(self, other)
Addition.
__and__(self, other)
Bitwise and, for now 1-bit only.
@@ -302,6 +312,8 @@
__or__(self, other)
Bitwise or, for now 1-bit only.
+
__pos__(self)
Unary +.
+
__pow__(self, other)
Exponentation for public integral exponent.
__radd__ = __add__(self, other)
@@ -362,6 +374,8 @@ asynchronously, using an instance of a specific cryptographic protocol.
  -
  Methods defined here:
+
__abs__(self)
Absolute value.
+
__add__(self, other)
Addition.
__and__(self, other)
Bitwise and, for now 1-bit only.
@@ -398,6 +412,8 @@
__or__(self, other)
Bitwise or, for now 1-bit only.
+
__pos__(self)
Unary +.
+
__pow__(self, other)
Exponentation for public integral exponent.
__radd__ = __add__(self, other)
@@ -447,11 +463,13 @@ Functions
       
SecFld(order=None, modulus=None, char2=None, l=None)
Secure prime or binary field of (l+1)-bit order.
+
SecFld(order=None, modulus=None, char=None, ext_deg=None, min_order=None, signed=False)
Secure finite field of order q = p**d.
 
-Field is prime by default, and if order (or modulus) is prime.
-Field is binary if order is a power of 2, if modulus is a
-polynomial, or if char2 is True.
+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.
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.
diff --git a/docs/mpyc.statistics.html b/docs/mpyc.statistics.html new file mode 100644 index 00000000..4976bd95 --- /dev/null +++ b/docs/mpyc.statistics.html @@ -0,0 +1,116 @@ + +Python: module mpyc.statistics + + + + + +
 
+ 
mpyc.statistics
index
c:\users\berry\documents\github\mympyc\mpyc\statistics.py
+

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, and mode are provided for calculating
+averages (measures of central location). Functions variance, stdev, pvariance, pstdev
+are provided for calculating variability (measures of spread).

+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 and median 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.

+

+ + + + + +
 
+Modules
       
mpyc.asyncoro
+
mpyc.random
+
mpyc.sectypes
+
statistics
+

+ + + + + +
 
+Functions
       
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.
+
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.
+
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.
+
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.
+
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.
+
pstdev(data, mu=None)
Return the population standard deviation (square root of the population variance).

+See pvariance() for arguments and other details.
+
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.
+
stdev(data, xbar=None)
Return the sample standard deviation (square root of the sample variance).

+See variance() for arguments and other details.
+
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.
+

+ + + + + +
 
+Data
       runtime = None
+ \ No newline at end of file diff --git a/mpyc/__init__.py b/mpyc/__init__.py index 9784a70d..3aa5aa2e 100644 --- a/mpyc/__init__.py +++ b/mpyc/__init__.py @@ -14,5 +14,5 @@ are provided as well (e.g., some matrix-vector operations). """ -__version__ = '0.5.13' +__version__ = '0.6' __license__ = 'MIT License' diff --git a/mpyc/asyncoro.py b/mpyc/asyncoro.py index 977eae27..c858ac9f 100644 --- a/mpyc/asyncoro.py +++ b/mpyc/asyncoro.py @@ -295,6 +295,12 @@ def _reconcile(decl, givn): if decl is None: return + try: + givn = givn.result() + except Exception: + runtime._loop.stop() # TODO: stop loop for other exceptions in callbacks + raise + __reconcile(decl, givn) @@ -357,18 +363,28 @@ def typed_asyncoro(*args, **kwargs): runtime._pc_level -= 1 return exc.value + except Exception: + runtime._pc_level -= 1 + raise + if runtime.options.no_async: while True: try: coro.send(None) except StopIteration as exc: - _reconcile(decl, exc.value) + runtime._pc_level -= 1 + if decl is not None: + __reconcile(decl, exc.value) return decl + except Exception: + runtime._pc_level -= 1 + raise + if pc: coro = _wrap(_ProgramCounterWrapper(runtime, coro)) d = runtime._loop.create_task(coro) # ensure_future - d.add_done_callback(lambda v: _reconcile(decl, v.result())) + d.add_done_callback(lambda v: _reconcile(decl, v)) return _ncopy(decl) return typed_asyncoro diff --git a/mpyc/runtime.py b/mpyc/runtime.py index c4c3ec56..d9706b86 100644 --- a/mpyc/runtime.py +++ b/mpyc/runtime.py @@ -24,6 +24,7 @@ from mpyc import asyncoro import mpyc.random import mpyc.statistics +import mpyc.seclists Future = asyncio.Future Share = sectypes.Share @@ -1617,6 +1618,7 @@ def setup(): asyncoro.runtime = rt mpyc.random.runtime = rt mpyc.statistics.runtime = rt + mpyc.seclists.runtime = rt return rt diff --git a/mpyc/seclists.py b/mpyc/seclists.py new file mode 100644 index 00000000..8edc7081 --- /dev/null +++ b/mpyc/seclists.py @@ -0,0 +1,244 @@ +"""This module provides a secure (oblivious) alternative to Python lists. + +A secure list contains secret-shared values. 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 functions such as count() +and index(), or can be coded easily. For example, the frequency of values in a list x +of secure integers (which 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. +""" + +from mpyc.sectypes import Share +from mpyc.random import random_unit_vector +from mpyc import asyncoro + +runtime = None + + +class seclist(list): + + def __init__(self, x=(), sectype=None): + """Build a secure list from the items in iterable x using the given secure type. + + If no secure type is given, it is inferred from the items in x. + + Invariant: all items in x are of the same secure type. + """ + super().__init__(x) + t = len(self) + for a in self: + if isinstance(a, Share): + t -= 1 + if sectype is None: + sectype = type(a) + elif sectype != type(a): + raise TypeError('inconsistent sectypes') + + if sectype is None: + raise TypeError('sectype missing') + + i = 0 + while t: + while isinstance(self[i], Share): + i += 1 + super().__setitem__(i, sectype(self[i])) + t -= 1 + self.sectype = sectype + + def __getitem__(self, key): + """Called to evaluate self[key], where key is either public or secret. + + If key is a public integer (or a slice), the behavior is the same as for ordinary lists. + If key is a secure number or index, the value at the secret position is returned. + """ + if isinstance(key, (int, slice)): + value = super().__getitem__(key) + if isinstance(key, slice): + value = seclist(value, self.sectype) + return value + + if isinstance(key, self.sectype): + i = runtime.unit_vector(key, len(self)) + elif isinstance(key, secindex): + i = [self.sectype(0)] * key.offset + list(key) + else: + i = key + if len(self) != len(i): + raise IndexError('inconsistent index length') + + # unary index i of right length + return runtime.in_prod(list(self), i) + + def __setitem__(self, key, value): + """Called to set self[key] = value, where key is either public or secret. + The type of value should fit with the type of the list. + + If key is a public integer (or a slice), the behavior is the same as for ordinary lists. + If key is a secure number or index, the list is updated at the secret position. + """ + if isinstance(key, int): + if not isinstance(value, self.sectype): + value = self.sectype(value) + super().__setitem__(key, value) + return + + if isinstance(key, slice): + if not isinstance(value, seclist): + value = seclist(value, self.sectype) + if not issubclass(value.sectype, self.sectype): + raise TypeError('inconsistent sectypes') + + super().__setitem__(key, value) + return + + if not isinstance(value, self.sectype): + value = self.sectype(value) + + if isinstance(key, self.sectype): + i = runtime.unit_vector(key, len(self)) + elif isinstance(key, secindex): + i = [self.sectype(0)] * key.offset + list(key) + else: + i = key + if len(self) != len(i): + raise IndexError('inconsistent index length') + + # unary index i of right length + s_i = runtime.in_prod(list(self), i) + res = runtime.vector_add(list(self), runtime.scalar_mul(value - s_i, i)) + parent = super() + for j in range(len(self)): + parent.__setitem__(j, res[j]) + + def append(self, other): + if not isinstance(other, self.sectype): + other = self.sectype(other) + super().append(other) + + def extend(self, other): + if not isinstance(other, seclist): + other = seclist(other, self.sectype) + super().extend(other) + + def __add__(self, other): + sectype = self.sectype + if not isinstance(other, seclist): + other = seclist(other, sectype) + elif sectype != other.sectype: + raise TypeError('inconsistent sectypes') + + return seclist(super().__add__(other), sectype) + + def __radd__(self, other): + return seclist(other + list(self), self.sectype) + + def __iadd__(self, other): + self.extend(other) + return self + + def copy(self): + return seclist(super().copy(), self.sectype) + +# def random_index(self): +# return secindex(random_unit_vector(self.sectype, len(self))) + + def __contains__(self, item): # NB: item in self does not work in CPython + """Check if item occurs in self.""" + return self.count(item) != 0 + + def count(self, value): + """Return the number of occurrences of value.""" + return runtime.sum([a == value for a in list(self)]) + + @staticmethod + def _find_one(x): + """Return (ix, nz), where ix is the index of first 1 in bit list x (ix=len(x) if no 1 in x) + and nz indicates if x contains a 1. + """ + n = len(x) + if n == 1: + return 1-x[0], x[0] + + ix0, nz0 = seclist._find_one(x[:n//2]) # low bits + ix1, nz1 = seclist._find_one(x[n//2:]) # high bits + return runtime.if_else(nz0, [ix0, nz0], [n//2 + ix1, nz1]) + + def find(self, value): # TODO: add optional i and j to indicate slice + """Return index of the first occurrence of value. + + If value is not present, then index is equal to len(self). + """ + if not self: + ix = self.sectype(0) + else: + ix = seclist._find_one([a == value for a in list(self)])[0] + return ix + + @asyncoro.mpc_coro + async def index(self, value): # TODO: add optional i and j to indicate slice + """Return index of the first occurrence of value. + + Raise ValueError if value is not present. + """ + await runtime.returnType((self.sectype, True)) + + ix = self.find(value) + if await runtime.eq_public(ix, len(self)): + raise ValueError(f'value is not in list') + + return ix + + +class secindex(list): + """Provisional class to facilitate more efficient manipulation of secure indices.""" + + def __init__(self, *args, offset=0, sectype=None): + if sectype is not None: + super().__init__(*args) + else: + x = seclist(*args) + sectype = x.sectype # infer sectype from elements of x + super().__init__(x) + self.offset = offset + self.sectype = sectype + + def __add__(self, other): + sectype = type(self[0]) + i = runtime.in_prod(list(self), [sectype(_) for _ in range(len(self))]) + j = runtime.in_prod(list(other), [sectype(_) for _ in range(len(other))]) + k = runtime.unit_vector(i + j, len(self) + len(other) - 1) + offset = self.offset + other.offset + return secindex(k, offset=offset) + + async def __index__(self): + sectype = type(self[0]) + f = sectype.field.frac_length + i = await runtime.output(runtime.in_prod(list(self), list(map(sectype, range(len(self)))))) + return self.offset + i.value >> f + + def __await__(self): + return self.__index__().__await__() + + @staticmethod + def random(sectype, length, offset=0): + n = length + return secindex(random_unit_vector(sectype, n), offset=offset) diff --git a/mpyc/sectypes.py b/mpyc/sectypes.py index a3b08ed1..d1e7c22d 100644 --- a/mpyc/sectypes.py +++ b/mpyc/sectypes.py @@ -419,6 +419,12 @@ def init(self, value=None): if value is not None: if isinstance(value, int): value = sectype.field(value) + elif not isinstance(value, sectype.field): + if isinstance(value, finfields.FiniteFieldElement): + raise TypeError(f'incompatible finite field {type(value).__name__}' + f' for {type(self).__name__}') + + raise TypeError('None, int, or finite field required') super(sectype, self).__init__(value) sectype = type(f'SecFld{l}({field.__name__})', (SecureFiniteField,), {'__slots__': (), '__init__': init}) @@ -452,12 +458,19 @@ def _SecInt(l, p, n): name = f'SecInt{l}({p})' def init(self, value=None): + """Value must be None, int, or correct field type.""" if value is not None: if isinstance(value, int): value = sectype.field(value) + elif not isinstance(value, sectype.field): + if isinstance(value, finfields.FiniteFieldElement): + raise TypeError(f'incompatible finite field {type(value).__name__}' + f' for {type(self).__name__}') + + raise TypeError('None, int, or finite field required') + super(sectype, self).__init__(value) - sectype = type(name, (SecureInteger,), - {'__slots__': (), '__init__': init}) + sectype = type(name, (SecureInteger,), {'__slots__': (), '__init__': init}) sectype.field = _pfield(l, 0, p, n) sectype.bit_length = l return sectype @@ -491,7 +504,7 @@ def init(self, value=None, integral=False): elif isinstance(value, float): self.integral = value.is_integer() value = sectype.field(round(value * (1<