def test_prss(self): field = self.f256 key = int('0x00112233445566778899aabbccddeeff', 16).to_bytes(16, byteorder='little') bound = 256 # field.modulus F = thresha.PRF(key, bound) m = 1 pid = 0 prfs = {(0, ): F} uci = 'test uci'.encode() n = 8 a = F(uci, n) shares = thresha.pseudorandom_share(field, m, pid, prfs, uci, n) b = thresha.recombine(field, [(1, shares)]) self.assertEqual(a, [s.value for s in b]) a = [0] * n shares = thresha.pseudorandom_share_zero(field, m, pid, prfs, uci, n) b = thresha.recombine(field, [(1, shares)]) self.assertEqual(a, b) m = 3 pid = 0 prfs = {(0, 1): F, (0, 2): F} # reuse dummy PRF shares0 = thresha.pseudorandom_share_zero(field, m, pid, prfs, uci, n) pid = 1 prfs = {(0, 1): F, (1, 2): F} # reuse dummy PRF shares1 = thresha.pseudorandom_share_zero(field, m, pid, prfs, uci, n) pid = 2 prfs = {(0, 2): F, (1, 2): F} # reuse dummy PRF shares2 = thresha.pseudorandom_share_zero(field, m, pid, prfs, uci, n) b = thresha.recombine(field, [(1, shares0), (2, shares1), (3, shares2)]) self.assertEqual(a, b)
def test_secretsharing(self): for field in (self.f2, self.f256): t = 0 m = 1 a = [field(0), field(1)] shares = thresha.random_split(a, t, m) b = thresha.recombine(field, [(j + 1, shares[j]) for j in range(len(shares))]) self.assertEqual(a, b) b = thresha.recombine(field, [(j + 1, shares[j]) for j in range(len(shares))], [0])[0] self.assertEqual(a, b) for field in (self.f19, self.f27, self.f256): for t in range(8): m = 2 * t + 1 for i in range(t): a = [field(i), field(i+1), field(i**2), field((i+1)**2)] shares = thresha.random_split(a, t, m) b = thresha.recombine(field, [(j + 1, shares[j]) for j in range(len(shares))]) self.assertEqual(a, b) m = 17 for t in range((m + 1) // 2): for i in range(t): a = [field(i), field(i+1), field(i**2), field((i+1)**2)] shares = thresha.random_split(a, t, m) b = thresha.recombine(field, [(j + 1, shares[j]) for j in range(len(shares))]) self.assertEqual(a, b)
def test_secretsharing(self): field = self.f2 t = 0 n = 1 a = [field(0), field(1)] shares = thresha.random_split(a, t, n) b = thresha.recombine(field, [(j + 1, shares[j]) for j in range(len(shares))]) self.assertEqual(a, b) field = self.f19 for t in range(8): n = 2 * t + 1 for i in range(t): a = [field(i), field(-i), field(i**2), field(-i**2)] shares = thresha.random_split(a, t, n) b = thresha.recombine(field, [(j + 1, shares[j]) for j in range(len(shares))]) self.assertEqual(a, b) n = 17 for t in range((n + 1) // 2): for i in range(t): a = [field(i), field(-i), field(i**2), field(-i**2)] shares = thresha.random_split(a, t, n) b = thresha.recombine(field, [(j + 1, shares[j]) for j in range(len(shares))]) self.assertEqual(a, b)
async def _reshare(self, x): x_is_list = isinstance(x, list) if not x_is_list: x = [x] sftype = type(x[0]) # all elts assumed of same type if issubclass(sftype, Share): field = sftype.field if not field.frac_length: await returnType(sftype, len(x)) else: await returnType((sftype, x[0].integral), len(x)) x = await gather_shares(x) else: field = sftype await returnType(Future) m = len(self.parties) t = self.threshold in_shares = thresha.random_split(x, t, m) in_shares = [field.to_bytes(elts) for elts in in_shares] # Recombine the first 2t+1 output_shares. out_shares = await gather_shares(self._exchange_shares(in_shares)[:2 * t + 1]) points = [(j + 1, field.from_bytes(out_shares[j])) for j in range(len(out_shares))] y = thresha.recombine(field, points) if issubclass(sftype, Share): y = [sftype(s) for s in y] if not x_is_list: y = y[0] return y
async def _recombine(self, x, receivers, t): """Recombine shares of elements of x.""" sftype = type(x[0]) # all elts assumed of same type if issubclass(sftype, Share): field = sftype.field if not field.frac_length: await returnType(sftype, len(x)) else: await returnType((sftype, x[0].integral), len(x)) x = await gather_shares(x) else: field = sftype await returnType(Future, len(x)) m = len(self.parties) x = [a.value for a in x] # Send share to all successors in receivers. for peer_pid in receivers: if 0 < (peer_pid - self.pid) % m <= t: self._send_shares(peer_pid, field.to_bytes(x)) # Receive and recombine shares if this party is a receiver. if self.pid in receivers: shares = [None] * t for i in range(t): shares[i] = self._receive_shares((self.pid - t + i) % m) shares = await gather_shares(shares) points = [((self.pid - t + j) % m + 1, field.from_bytes(shares[j])) for j in range(t)] points.append((self.pid + 1, x)) return thresha.recombine(field, points) return [None] * len(x)
async def _reshare(self, a): if not isinstance(a, list): a = tuple([a]) sftype = type(a[0]) # all elts assumed of same type if issubclass(sftype, Share): if sftype.field.frac_length == 0: await returnType(sftype, len(a)) else: await returnType((sftype, a[0].integral), len(a)) a = await mpc.gather(a) field = sftype.field else: await returnType(Share) field = sftype in_shares = thresha.random_split(a, self.threshold, len(self.parties)) in_shares = [field.to_bytes(elts) for elts in in_shares] # Recombine the first 2t+1 output_shares. out_shares = await gather_shares( self._exchange_shares(in_shares)[:2 * self.threshold + 1]) b = thresha.recombine(field, [(j + 1, field.from_bytes(out_shares[j])) for j in range(len(out_shares))]) if issubclass(sftype, Share): b = [sftype(s) for s in b] if isinstance(a, tuple): return b[0] else: return b
def test_prss(self): field = self.f19 key = b'00112233445566778899aabbccddeeff' max = field.modulus F = thresha.PRF(key, max) n = 1 id = 0 prfs = {frozenset([0]): F} uci = 'test uci' m = 8 a = F(uci, m) shares = thresha.pseudorandom_share(field, n, id, prfs, uci, m) b = thresha.recombine(field, [(1, shares)]) self.assertEqual(a, b) a = [0] * m shares = thresha.pseudorandom_share_zero(field, n, id, prfs, uci, m) b = thresha.recombine(field, [(1, shares)]) self.assertEqual(a, b)
async def _recombine(self, a, receivers=None, threshold=None): """Recombine shares of a. The receivers are the parties that will obtain the result. The default is to let everybody know the result. """ # all parties receive result by default if receivers is None: receivers = list(range(len(self.parties))) if threshold is None: threshold = self.threshold if not isinstance(a, list): a = tuple([a]) sftype = type(a[0]) # all elts assumed of same type if issubclass(sftype, Share): if sftype.field.frac_length == 0: await returnType(sftype) else: await returnType((sftype, a[0].integral)) a = await gather_shares(a) field = type(a[0]) else: await returnType(Share) field = sftype # Send share to all successors in receivers. for peer_id in receivers: if 0 < (peer_id - self.id) % len(self.parties) <= threshold: self._send_share(peer_id, field.to_bytes(list(a))) # Receive and recombine shares if this party is a receiver. if self.id in receivers: shares = [None] * threshold for i in range(threshold): shares[i] = self._expect_share( (self.id - threshold + i) % len(self.parties)) shares = await gather_shares(shares) shares = [((self.id - threshold + j) % len(self.parties) + 1, field.from_bytes(shares[j])) for j in range(threshold)] shares.append((self.id + 1, list(a))) b = thresha.recombine(field, shares) if isinstance(a, tuple): return b[0] else: return b else: return