def robust_decode(self, z, encoded): m = {zi: i for i, zi in enumerate(z)} enc_extended = [ self.point.field(encoded[m[i]]) if i in m else None for i in range(self.n) ] try: coeffs = self._dec(enc_extended) except Exception as e: # Welch-Berlekamp doesn't throw any specific exceptions. # Just catch 'em all if str(e) not in ("Wrong degree", "found no divisors!"): raise e coeffs = None if coeffs is not None: coeffs = [c.value for c in coeffs] x = [self.point(i).value for i in range(self.point.n)] poly_eval = vandermonde_batch_evaluate(x, [coeffs], self.modulus)[0] errors = [ i for i in range(self.point.n) if enc_extended[i] is not None and enc_extended[i].value != poly_eval[i] ] return coeffs, errors return None, None
def robust_decode(self, z, encoded): x = [self.point(zi).value for zi in z] args = [x, encoded, self.d + 1, self.modulus] if self.use_omega_powers: args += [z, self.point.omega.value, self.point.order] decoded, error_poly = gao_interpolate( *args, use_omega_powers=self.use_omega_powers) if decoded is None: return None, None errors = [] if len(error_poly) > 1: if self.use_omega_powers: err_eval = fft(error_poly, self.point.omega.value, self.modulus, self.point.order)[:self.point.n] else: x = [self.point(i).value for i in range(self.point.n)] err_eval = vandermonde_batch_evaluate(x, [error_poly], self.modulus)[0] errors = [i for i in range(self.point.n) if err_eval[i] == 0] return decoded, errors
def test_batch_vandermonde_evaluate(galois_field): # Given x = [1, 2] polynomials = [[0, 1], [1, 2]] p = galois_field.modulus # When y = vandermonde_batch_evaluate(x, polynomials, p) # Then assert y == [[1, 2], [3, 5]]
def encode_batch(self, data): return vandermonde_batch_evaluate(self.x, data, self.modulus)
def encode_one(self, data): return vandermonde_batch_evaluate(self.x, [data], self.modulus)[0]
async def refine_triples(context, a_dirty, b_dirty, c_dirty): """This method takes dirty triples and refines them. Arguments: context {Mpc} -- MPC context. a_dirty {list[Share]} -- Shares of first part of the triples. b_dirty {list[Share]} -- Shares of second part of the triples. c_dirty {list[Share]} -- Shares of first*second part of the triples. Returns: list[Share] -- Shares of first part of the refined triples. list[Share] -- Shares of second part of the refined triples. list[Share] -- Shares of first*second part of the refined triples. """ assert len(a_dirty) == len(b_dirty) == len(c_dirty) n, t = context.N, context.t m = len(a_dirty) d = (m - 1) // 2 # d = 2*m + 1 modulus = context.field.modulus assert m >= n - t and m <= n # Use the first `d+1` points to define the d-degree polynomials A() and B() a, b = a_dirty[:d + 1], b_dirty[:d + 1] a_coeffs = vandermonde_batch_interpolate(list(range(d + 1)), [a], modulus)[0] b_coeffs = vandermonde_batch_interpolate(list(range(d + 1)), [b], modulus)[0] assert len(a_coeffs) == len(b_coeffs) == d + 1 # Evaluate A() and B() at `d` more points a_rest = vandermonde_batch_evaluate(list(range(d + 1, 2 * d + 1)), [a_coeffs], modulus)[0] b_rest = vandermonde_batch_evaluate(list(range(d + 1, 2 * d + 1)), [b_coeffs], modulus)[0] assert len(a_rest) == len(b_rest) == d # Multiply these newly evaluated `d` points on A() and B() to # obtain `d` more points on C() using batch beaver multiplication x, y, z = ( a_dirty[d + 1:2 * d + 1], b_dirty[d + 1:2 * d + 1], c_dirty[d + 1:2 * d + 1], ) assert len(x) == len(y) == len(z) c_rest = await batch_beaver(context, a_rest, b_rest, x, y, z) assert len(c_rest) == d # The initial `d+1` points and the `d` points computed in the last step make a # total of `2d+1` points which can now be used to completely define C() which # is a 2d degree polynomial c = c_dirty[:d + 1] c_coeffs = vandermonde_batch_interpolate(list(range(2 * d + 1)), [c + c_rest], modulus)[0] assert len(c_coeffs) == 2 * d + 1 # The total number of triples which can be extracted securely k = d + 1 - t # Evaluate the polynomial at `k` new points p = vandermonde_batch_evaluate(list(range(n + 1, n + 1 + k)), [a_coeffs], modulus)[0] q = vandermonde_batch_evaluate(list(range(n + 1, n + 1 + k)), [b_coeffs], modulus)[0] pq = vandermonde_batch_evaluate(list(range(n + 1, n + 1 + k)), [c_coeffs], modulus)[0] assert len(p) == len(q) == len(pq) == k return p, q, pq