Esempio n. 1
0
def calculate_lagrange_polynomials(x_values):
    """
    Given the x_values for evaluating some polynomials, it computes part of the lagrange polynomials
    required to interpolate a polynomial over this domain.
    """
    lagrange_polynomials = []
    monomials = [
        Polynomial.monomial(1, FieldElement.one()) - Polynomial.monomial(0, x)
        for x in x_values
    ]
    numerator = prod(monomials)
    for j in tqdm(range(len(x_values))):
        # In the denominator, we have:
        # (x_j-x_0)(x_j-x_1)...(x_j-x_{j-1})(x_j-x_{j+1})...(x_j-x_{len(X)-1})
        denominator = prod(
            [x_values[j] - x for i, x in enumerate(x_values) if i != j])
        # Numerator is a bit more complicated, since we need to compute a poly multiplication here.
        # Similarly to the denominator, we have:
        # (x-x_0)(x-x_1)...(x-x_{j-1})(x-x_{j+1})...(x-x_{len(X)-1})
        cur_poly, _ = numerator.qdiv(monomials[j].scalar_mul(denominator))
        lagrange_polynomials.append(cur_poly)
    return lagrange_polynomials
Esempio n. 2
0
def test_field_div():
    for _ in range(100):
        t = FieldElement.random_element(exclude_elements=[FieldElement.zero()])
        t_inv = FieldElement.one() / t
        assert t_inv == t.inverse()
        assert t_inv * t == FieldElement.one()
Esempio n. 3
0
def test_field_operations():
    # Check pow, mul, and the modular operations
    t = FieldElement(2).pow(30) * FieldElement(3) + FieldElement(1)
    assert t == FieldElement(0)
Esempio n. 4
0
 def __init__(self, coefficients, var='x'):
     # Internally storing the coefficients in self.poly, least-significant (i.e. free term)
     # first, so $9 - 3x^2 + 19x^5$ is represented internally by the list  [9, 0, -3, 0, 0, 19].
     # Note that coefficients is copied, so the caller may freely modify the given argument.
     self.poly = remove_trailing_elements(coefficients, FieldElement.zero())
     self.var = var
Esempio n. 5
0
 def X(cls):
     """
     Returns the polynomial x.
     """
     return cls([FieldElement.zero(), FieldElement.one()])
Esempio n. 6
0
def trim_trailing_zeros(p):
    """
    Removes zeros from the end of a list.
    """
    return remove_trailing_elements(p, FieldElement.zero())
Esempio n. 7
0
 def gen_linear_term(point):
     """
     Generates the polynomial (x-p) for a given point p.
     """
     return Polynomial([FieldElement.zero() - point, FieldElement.one()])
Esempio n. 8
0
 def monomial(degree, coefficient):
     """
     Constructs the monomial coefficient * x**degree.
     """
     return Polynomial([FieldElement.zero()] * degree + [coefficient])
Esempio n. 9
0
 def __sub__(self, other):
     other = Polynomial.typecast(other)
     return Polynomial(
         two_lists_tuple_operation(self.poly, other.poly, operator.sub,
                                   FieldElement.zero()))
Esempio n. 10
0
def test_prod():
    g = FieldElement.generator()**((FieldElement.k_modulus - 1) // 1024)
    assert X**1024 - 1 == prod([(X - g**i) for i in range(1024)])

# a STARK proving mechanism 
# from StarkWare101 Workshop
# in San Fransisco, 2/17/20


##########
# PART 1 #
##########

# first step is to create a list of length 1023 
# first two elements are FieldElement objects 
# representing 1 and 3141592 respectively.

a = [FieldElement(1), FieldElement(3141592)]
while len(a) < 1023:
    a.append(a[-2] * a[-2] + a[-1] * a[-1])

# quick unit test to verify a[] constructed properly
assert len(a) == 1023, 'The trace must consist of exactly 1023 elements.'
assert a[0] == FieldElement(1), 'The first element in the trace must be the unit element.'
for i in range(2, 1023):
    assert a[i] == a[i - 1] * a[i - 1] + a[i - 2] * a[i - 2], f'The FibonacciSq recursion rule does not apply for index {i}'
assert a[1022] == FieldElement(2338775057), 'Wrong last element!'
print('Success!')

# need a generator from field element class
# need to generator a group of size 1024

g = FieldElement.generator() ** (3 * 2 ** 20)