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