@@ -77,7 +77,8 @@ def _div_gf2(a, b):
7777class _Element (object ):
7878 """Element of GF(2^128) field"""
7979
80- # The irreducible polynomial defining this field is 1+x+x^2+x^7+x^128
80+ # The irreducible polynomial defining
81+ # this field is 1 + x + x^2 + x^7 + x^128
8182 irr_poly = 1 + 2 + 4 + 128 + 2 ** 128
8283
8384 def __init__ (self , encoded_value ):
@@ -178,43 +179,53 @@ def split(k, n, secret, ssss=False):
178179
179180 Args:
180181 k (integer):
181- The sufficient number of shares to reconstruct the secret (``k < n``) .
182+ The number of shares needed to reconstruct the secret.
182183 n (integer):
183- The number of shares that this method will create .
184+ The number of shares to create (at least ``k``) .
184185 secret (byte string):
185- A byte string of 16 bytes (e.g. the AES 128 key).
186+ A byte string of 16 bytes (e.g. an AES 128 key).
186187 ssss (bool):
187- If ``True``, the shares can be used with the ``ssss`` utility.
188+ If ``True``, the shares can be used with the ``ssss`` utility
189+ (without using the "diffusion layer").
188190 Default: ``False``.
189191
190192 Return (tuples):
191- ``n`` tuples. A tuple is meant for each participant and it contains two items:
193+ ``n`` tuples, one per participant.
194+ A tuple contains two items:
192195
193196 1. the unique index (an integer)
194- 2. the share (a byte string, 16 bytes)
197+ 2. the share (16 bytes)
195198 """
196199
197200 #
198201 # We create a polynomial with random coefficients in GF(2^128):
199202 #
200- # p(x) = \sum_{i=0 }^{k-1} c_i * x^i
203+ # p(x) = c_0 + \sum_{i=1 }^{k-1} c_i * x^i
201204 #
202- # c_0 is the encoded secret
205+ # c_0 is the secret.
203206 #
204207
205208 coeffs = [_Element (rng (16 )) for i in range (k - 1 )]
206209 coeffs .append (_Element (secret ))
207210
208- # Each share is y_i = p(x_i) where x_i is the public index
209- # associated to each of the n users .
211+ # Each share is y_i = p(x_i) where x_i
212+ # is the index assigned to the share .
210213
211214 def make_share (user , coeffs , ssss ):
212215 idx = _Element (user )
216+
217+ # Horner's method
213218 share = _Element (0 )
214219 for coeff in coeffs :
215220 share = idx * share + coeff
221+
222+ # The ssss utility actually uses:
223+ #
224+ # p(x) = c_0 + \sum_{i=1}^{k-1} c_i * x^i + x^k
225+ #
216226 if ssss :
217227 share += _Element (user ) ** len (coeffs )
228+
218229 return share .encode ()
219230
220231 return [(i , make_share (i , coeffs , ssss )) for i in range (1 , n + 1 )]
@@ -225,11 +236,18 @@ def combine(shares, ssss=False):
225236
226237 Args:
227238 shares (tuples):
228- The *k* tuples, each containin the index (an integer) and
239+ The *k* tuples, each containing the index (an integer) and
229240 the share (a byte string, 16 bytes long) that were assigned to
230241 a participant.
242+
243+ .. note::
244+
245+ Pass exactly as many share as they are required,
246+ and no more.
247+
231248 ssss (bool):
232- If ``True``, the shares were produced by the ``ssss`` utility.
249+ If ``True``, the shares were produced by the ``ssss`` utility
250+ (without using the "diffusion layer").
233251 Default: ``False``.
234252
235253 Return:
@@ -275,4 +293,5 @@ def combine(shares, ssss=False):
275293 numerator *= x_m
276294 denominator *= x_j + x_m
277295 result += y_j * numerator * denominator .inverse ()
296+
278297 return result .encode ()
0 commit comments