@@ -1710,7 +1710,12 @@ def reveal_to(self, player):
1710
1710
res = Array .create_from (res )
1711
1711
return personal (player , res )
1712
1712
1713
- def bit_decompose (self , length ):
1713
+ def bit_decompose (self , length = None ):
1714
+ """ Bit decomposition.
1715
+
1716
+ :param length: number of bits
1717
+
1718
+ """
1714
1719
return [personal (self .player , x ) for x in self ._v .bit_decompose (length )]
1715
1720
1716
1721
def _san (self , other ):
@@ -2144,14 +2149,17 @@ class sint(_secret, _int):
2144
2149
the bit length.
2145
2150
2146
2151
:param val: initialization (sint/cint/regint/int/cgf2n or list
2147
- thereof or sbits/sbitvec/sfix)
2152
+ thereof, sbits/sbitvec/sfix, or :py:class:`personal` )
2148
2153
:param size: vector size (int), defaults to 1 or size of list
2149
2154
2150
2155
When converting :py:class:`~Compiler.GC.types.sbits`, the result is a
2151
2156
vector of bits, and when converting
2152
2157
:py:class:`~Compiler.GC.types.sbitvec`, the result is a vector of values
2153
2158
with bit length equal the length of the input.
2154
2159
2160
+ Initializing from a :py:class:`personal` value implies the
2161
+ relevant party inputting their value securely.
2162
+
2155
2163
"""
2156
2164
__slots__ = []
2157
2165
instruction_type = 'modp'
@@ -4285,6 +4293,7 @@ class sfix(_fix):
4285
4293
""" Secret fixed-point number represented as secret integer, by
4286
4294
multiplying with ``2^f`` and then rounding. See :py:class:`sint`
4287
4295
for security considerations of the underlying integer operations.
4296
+ The secret integer is stored as the :py:obj:`v` member.
4288
4297
4289
4298
It supports basic arithmetic (``+, -, *, /``), returning
4290
4299
:py:class:`sfix`, and comparisons (``==, !=, <, <=, >, >=``),
@@ -5121,7 +5130,8 @@ class Array(_vectorizable):
5121
5130
array ``a`` and ``i`` being a :py:class:`regint`,
5122
5131
:py:class:`cint`, or a Python integer.
5123
5132
5124
- :param length: compile-time integer (int) or :py:obj:`None` for unknown length
5133
+ :param length: compile-time integer (int) or :py:obj:`None`
5134
+ for unknown length (need to specify :py:obj:`address`)
5125
5135
:param value_type: basic type
5126
5136
:param address: if given (regint/int), the array will not be allocated
5127
5137
@@ -5178,6 +5188,8 @@ def delete(self):
5178
5188
self .address = None
5179
5189
5180
5190
def get_address (self , index ):
5191
+ if isinstance (index , (_secret , _single )):
5192
+ raise CompilerError ('need cleartext index' )
5181
5193
key = str (index )
5182
5194
if self .length is not None :
5183
5195
from .GC .types import cbits
@@ -5211,6 +5223,7 @@ def get_slice(self, index):
5211
5223
if index .step == 0 :
5212
5224
raise CompilerError ('slice step cannot be zero' )
5213
5225
return index .start or 0 , \
5226
+ index .stop if self .length is None else \
5214
5227
min (index .stop or self .length , self .length ), index .step or 1
5215
5228
5216
5229
def __getitem__ (self , index ):
@@ -5517,7 +5530,15 @@ def print_reveal_nested(self, end='\n'):
5517
5530
5518
5531
:param end: string to print after (default: line break)
5519
5532
"""
5520
- library .print_str ('%s' + end , self .get_vector ().reveal ())
5533
+ if util .is_constant (self .length ):
5534
+ library .print_str ('%s' + end , self .get_vector ().reveal ())
5535
+ else :
5536
+ library .print_str ('[' )
5537
+ @library .for_range (self .length - 1 )
5538
+ def _ (i ):
5539
+ library .print_str ('%s, ' , self [i ].reveal ())
5540
+ library .print_str ('%s' , self [self .length - 1 ].reveal ())
5541
+ library .print_str (']' + end )
5521
5542
5522
5543
def reveal_to_binary_output (self , player = None ):
5523
5544
""" Reveal to binary output if supported by type.
@@ -5893,7 +5914,8 @@ def dot(self, other, res_params=None, n_threads=None):
5893
5914
""" Matrix-matrix and matrix-vector multiplication.
5894
5915
5895
5916
:param self: two-dimensional
5896
- :param other: Matrix or Array of matching size and type """
5917
+ :param other: Matrix or Array of matching size and type
5918
+ :param n_threads: number of threads (default: all in same thread) """
5897
5919
assert len (self .sizes ) == 2
5898
5920
if isinstance (other , Array ):
5899
5921
assert len (other ) == self .sizes [1 ]
@@ -5928,6 +5950,7 @@ def _(base, size):
5928
5950
res_matrix .assign_part_vector (
5929
5951
self .get_part (base , size ).direct_mul (other ), base )
5930
5952
except AttributeError :
5953
+ assert n_threads is None
5931
5954
if max (res_matrix .sizes ) > 1000 :
5932
5955
raise AttributeError ()
5933
5956
A = self .get_vector ()
@@ -5937,7 +5960,7 @@ def _(base, size):
5937
5960
res_params ))
5938
5961
except (AttributeError , AssertionError ):
5939
5962
# fallback for sfloat etc.
5940
- @library .for_range_opt ( self .sizes [0 ])
5963
+ @library .for_range_opt_multithread ( n_threads , self .sizes [0 ])
5941
5964
def _ (i ):
5942
5965
try :
5943
5966
res_matrix [i ] = self .value_type .row_matrix_mul (
0 commit comments