示例#1
0
    def test_construct_multivariate_dirac_delta(self):
        """Tests the construct of the multivariate dirac delta."""
        modulus = 3
        mod7 = IntegersModP(modulus)
        n = 3
        # Let's make polynomials in (Z/7)[x, y, z]
        multi = multivariates_over(mod7, n).factory
        # Let's generate the dirac delta at x=0, y=0, z=0
        values = [mod7(0), mod7(0), mod7(0)]
        dirac = construct_multivariate_dirac_delta(mod7, values, n)

        # The dirac delta should be 1 at x=0, y=0, z=0
        assert dirac((0, 0, 0)) == 1
        # It should be 0 elsewhere
        assert dirac((1, 0, 0)) == 0
        assert dirac((0, 1, 0)) == 0
        assert dirac((0, 0, 1)) == 0

        # Let's generate the dirac delta at x=1, y=1, z=1
        values = [mod7(1), mod7(1), mod7(1)]
        dirac = construct_multivariate_dirac_delta(mod7, values, n)

        # The dirac delta should be 1 at x=1, y=1, z=1
        assert dirac((1, 1, 1)) == 1
        # It should be 0 elsewehre
        assert dirac((1, 0, 0)) == 0
        assert dirac((0, 1, 0)) == 0
        assert dirac((0, 0, 1)) == 0
示例#2
0
 def test_project_multivar(self):
     """Test the multivariate projection."""
     modulus = 7
     field = IntegersModP(modulus)
     width = 3
     # Let's make polynomials in (Z/7)[x, y, z]
     multi = multivariates_over(field, width).factory
     # This should equal xy
     xy_poly = multi({(1, 1, 0): 1})
     x_poly = project_to_univariate(xy_poly, 0, field, width)
示例#3
0
文件: apr.py 项目: apguerrera/starks
  def __init__(self, air: AIR, zero_knowledge_expansion=5):
    """Initiates the APR object using an AIR object.

    Implements the AIR->APR transform from the STARKs paper.
    """
    self.air = air
    modulus = air.field.p
    self.width = air.width
    # field = (Z/2[g]/h(g))
    self.field = air.field
    # base_field = Z/2
    base_field = self.field.base_field
    self.basePolys = polynomials_over(base_field)
    # h(g)
    h = self.field.ideal_generator
    # g
    g = self.basePolys([0, 1])

    # Some constants
    T = air.steps
    self.t = int(math.log(T, 2))
    # chosen so deg(C) <= 2^d
    # Setting to arbitrary value for now.
    self.d = int(math.log(self.air.CDegree, 2))+1
    # TODO(rbharath): How should this constant be set correctly?
    self.R = 5
    # This is the zero-knowledge expansion
    self.k = zero_knowledge_expansion

    self.polysOver = polynomials_over(self.field).factory
    self.Tau = list(range(self.width))
    # Element of (Z/2[g]/h(g))
    self.zeta = generate_primitive_polynomial(modulus, self.width)
    # Neighbors
    self.Nbrs = self.construct_neighbors(self.Tau, self.zeta, g, self.polysOver)

    # Define the affine spaces
    self.H = AffineSpace(base_field, [g**k for k in range(self.t)])
    self.H0 = AffineSpace(base_field, [g**k for k in range(self.t-1)])
    self.H1 = AffineSpace(base_field, [g**k for k in range(self.t-1)], g**(self.t-1))
    self.L = self.construct_L(g)
    self.Lcmp = self.construct_L_cmp(g)
    self.Z_boundaries = self.construct_Z_boundaries(air.B)
    self.Eps_boundaries = self.construct_Eps_boundaries(air.B)
    self.rho_js = self.compute_rho_js(self.Z_boundaries, self.L)
    self.rho_cmp = self.compute_rho_cmp(self.Lcmp)
    self.comp = air

    # X_loc + {X_N}_{n in Nbrs}
    num_Phi_vars = 1 + len(self.Nbrs)
    PhiPolys = multivariates_over(self.field, num_Phi_vars).factory
    self.Phi = self.construct_Phi_polynomials(air, PhiPolys, g, self.zeta, modulus)

    # Witness reductio
    self.w = self.generate_witness()
示例#4
0
def project_to_univariate(multivar_poly: MultiVarPoly, i: int, field: Field,
                          width: int) -> Poly:
    """Projects a multivariate polynomial to a univariate polynomial over one var."""
    multivars = multivariates_over(field, width - 1)
    multiVarsOver = multivars.factory
    polysOver = polynomials_over(multivars).factory
    X = polysOver([0, 1])
    out = 0
    for (term, coeff) in multivar_poly:
        # Remove i-th variable
        term_minus_i = term[:i] + term[i + 1:]
        coeff = multiVarsOver({term_minus_i: coeff})
        out += polysOver([coeff]) * X**term[i]
    return out
示例#5
0
  def test_cross_mul(self):
    """Test multiplication with different types."""
    modulus = 7
    mod7 = IntegersModP(modulus)
    n = 3
    # Let's make polynomials in (Z/7)[x, y, z]
    multi = multivariates_over(mod7, n).factory

    three = mod7(3)
    # This should equal y
    y_poly = multi({(0, 1, 0): mod7(1)})
    three_y_poly = multi({(0, 1, 0): mod7(3)})

    assert three_y_poly == three * y_poly
示例#6
0
  def test_basic_construction(self):
    """"Test construction."""
    modulus = 7
    mod7 = IntegersModP(modulus)
    n = 3
    # Let's make polynomials in (Z/7)[x, y, z]
    multi = multivariates_over(mod7, n).factory
    # This should equal y
    y_poly = multi({(0, 1, 0): 1})

    # Test construction of a constant polynomial
    zero_poly = multi(0)
    zero_poly_2 = multi({})
    assert zero_poly == zero_poly_2
示例#7
0
  def test_add(self):
    """Test multivariate polynomial addition."""
    modulus = 7
    mod7 = IntegersModP(modulus)
    n = 3
    # Let's make polynomials in (Z/7)[x, y, z]
    multi = multivariates_over(mod7, n).factory

    # This should equal 0
    zero_poly = multi({})
    assert zero_poly == zero_poly + zero_poly

    # This should equal y
    y_poly = multi({(0, 1, 0): 1})
    assert y_poly == y_poly + zero_poly
示例#8
0
  def test_composition(self):
    """Test that multivariate polynomials can compose properly."""
    modulus = 2**256 - 2**32 * 351 + 1
    field = IntegersModP(modulus)
    width = 2
    multi = multivariates_over(field, width).factory
    [X_1, X_2] = generate_Xi_s(field, width)
    step_polys = [X_2, X_1 + 2*X_2**2] 

    # This should equal y + 1
    state_polys = [X_1, X_2]
    for step_poly in step_polys:
      next_step = step_poly(state_polys)
      # Since we start from the original polynomials the "next step" poly is
      # just the transition poly.
      assert next_step == step_poly
示例#9
0
  def test_neg(self):
    """Tests negation of multivariate polynomials."""
    modulus = 7
    mod7 = IntegersModP(modulus)
    n = 3
    # Let's make polynomials in (Z/7)[x, y, z]
    multi = multivariates_over(mod7, n).factory

    # This should equal 0
    zero_poly = multi({})
    assert zero_poly == -zero_poly

    # This should equal y
    y_poly = multi({(0, 1, 0): 1})
    # This should equal -y
    neg_y_poly = multi({(0, 1, 0): -1})
    assert neg_y_poly == - y_poly
示例#10
0
def make_multivar(poly: Poly, i: int, field: Field,
                  width: int) -> MultiVarPoly:
    """Converts a univariate polynomial into multivariate.
 
  Suppose poly = x^2 + 3

  Suppose that width = 5, i = 2. Then returns

  x_2^2 + 3
  """
    polysOver = multivariates_over(field, width).factory
    pre = (0, ) * i
    post = (0, ) * (width - (i + 1))
    index = pre + (1, ) + post
    X_i = polysOver({index: field(1)})
    up_poly = 0
    for degree, coeff in enumerate(poly.coefficients):
        up_poly += coeff * X_i**degree
    return up_poly
示例#11
0
    def test_construct_multivariate_coefficients(self):
        """Tests the "compilation" of a function into a polynomial."""
        modulus = 7
        mod7 = IntegersModP(modulus)
        n = 3
        # Let's make polynomials in (Z/7)[x, y, z]
        multi = multivariates_over(mod7, n).factory

        # Our test function
        def f(x):
            if isinstance(x, tuple) or isinstance(x, list):
                x = x[0]
            return x + 1

        poly = construct_multivariate_coefficients(mod7, f, n)

        # This should equal x + 1
        x_plus_one_poly = multi({(0, 0, 0): mod7(1), (1, 0, 0): mod7(1)})
        assert poly == x_plus_one_poly
示例#12
0
  def test_div(self):
    """Test multiplication of multivariate polynomials."""
    modulus = 7
    mod7 = IntegersModP(modulus)
    n = 3
    # Let's make polynomials in (Z/7)[x, y, z]
    multi = multivariates_over(mod7, n).factory

    # This should equal y
    y_poly = multi({(0, 1, 0): mod7(1)})
    # This is y^2
    y_sq_poly = multi({(0, 2, 0): mod7(1)})
    assert y_sq_poly / y_poly == y_poly

    # This should equal x + y
    x_y_poly = multi({(1, 0, 0): mod7(1), (0, 1, 0): mod7(1)})
    # This should equal x^2 + 2xy + y^2
    sq_x_y_poly = multi({(2, 0, 0): mod7(1), (1, 1, 0): mod7(2), (0, 2, 0): mod7(1)})
    prod = x_y_poly*x_y_poly
    assert sq_x_y_poly / x_y_poly == x_y_poly 
示例#13
0
  def test_call(self):
    """Test calling the multivariate polynomial like a function."""
    modulus = 7
    mod7 = IntegersModP(modulus)
    n = 3
    # Let's make polynomials in (Z/7)[x, y, z]
    multi = multivariates_over(mod7, n).factory
    # This should equal 0
    zero_poly = multi({})
    # Evaluate with x=1, y=1, z=1. This should equal 0
    assert zero_poly((1, 1, 1)) == 0

    # This should equal y
    y_poly = multi({(0, 1, 0): mod7(1)})
    # Evaluate with x=1, y=1, z=1. This should equal 1 
    assert y_poly((1, 1, 1)) == 1

    # This should equal x^2 + 2xy + y^2
    sq_x_y_poly = multi({(2, 0, 0): mod7(1), (1, 1, 0): mod7(2), (0, 2, 0): mod7(1)})
    # Evaluate with x=1, y=1, z=1. This should equal 4 
    assert sq_x_y_poly((1, 1, 1)) == 4
示例#14
0
def construct_multivariate_dirac_delta(field: Field,
                                       values: List[FieldElement],
                                       n: int) -> MultiVarPoly:
    """Constructs the multivariate dirac delta polynomial at 0.

  1_0(x) = \prod_{i=1}^n (1 - x_i^{q-1})

  This can be generalized into the the dirac polynomial at y as follows.

  1_y(x)\prod_{i=1}^n (1 - (x_i - y_i)^{q-1})
  """
    multi = multivariates_over(field, n).factory
    q = field.field_size
    base = field(1)
    for i, val in enumerate(values):
        # x_i_term = (0,...1,...0) with the 1 in the ith-term
        x_i_term = [0] * n
        x_i_term[i] = 1
        term = multi({(0, ) * n: -values[i], tuple(x_i_term): 1})
        term = field(1) - term**(q - 1)
        base = base * term
    return base
示例#15
0
 def test_finitefield(self):
   """Test multivariates over finite fields."""
   # This finite field is of size 2^17
   p = 2
   m = 17
   Zp = IntegersModP(p)
   polysOver = polynomials_over(Zp)
   #field = FiniteField(p, m)
   #x^17 + x^3 + 1 is primitive 
   coefficients = [Zp(0)] * 18
   coefficients[0] = Zp(1)
   coefficients[3] = Zp(1)
   coefficients[17] = Zp(1)
   poly = polysOver(coefficients)
   field = FiniteField(p, m, polynomialModulus=poly)
   width = 2
   inp = [field(0), field(1)]
   polysOver = multivariates_over(field, width).factory
   [X_1, X_2] = generate_Xi_s(field, width)
   step_poly = X_2
   poly = step_poly([X_1, X_2])
   assert poly == X_2
示例#16
0
  def test_degree(self):
    """Test computation of multivariate degree"""
    modulus = 7
    mod7 = IntegersModP(modulus)
    n = 3
    # Let's make polynomials in (Z/7)[x, y, z]
    multi = multivariates_over(mod7, n).factory
    # This should equal y
    y_poly = multi({(0, 1, 0): 1})
    assert y_poly.degree() == 1

    # This should equal x + y + z
    sum_poly = multi({(1, 0, 0): 1, (0, 1, 0): 1, (0, 0, 1): 1})
    assert sum_poly.degree() == 1

    # This should equal x^2 + y^2 + z^2
    sq_sum_poly = multi({(2, 0, 0): 1, (0, 2, 0): 1, (0, 0, 2): 1})
    assert sq_sum_poly.degree() == 2

    # This should equal xy + yz + zx
    multi_poly = multi({(1, 1, 0): 1, (0, 1, 1): 1, (1, 0, 1): 1})
    assert multi_poly.degree() == 2
示例#17
0
def construct_multivariate_coefficients(
        field: Field, step_fn: Callable,
        n: int) -> Dict[Tuple[int, ...], FieldElement]:
    """Transforms a function over vector of finite fields into a polynomial.

  Every function f: F_q^n -> F_q is a polynomial if F is a finite field of size
  q. (See Lemma 7 of http://math.uga.edu/~pete/4400ChevalleyWarning.pdf). The
  key trick used in this transformation is the creation of a "dirac-delta"
  multivariate polynomial which is 1 iff all n of its inputs are 0.

  1_0(x) = \prod_{i=1}^n (1 - x_i^{q-1})

  Why does this make sense? For any non-zero element x in F_q, x^{q-1} = 1. How
  can we convert an aribtrary function using these dirac-delta polynomials?

  P_f(x) = \sum_{y \in F_q^n} f(y) \prod_{i=1}^n (1 - (x_i - y_i)^{q-1})

  The idea is that we construct the polynomial term-wise.
  """
    multi = multivariates_over(field, n).factory
    poly = multi(0)
    field_size = field.field_size
    # Finite field case
    if field.__name__[:2] == "F_":
        p = field.p
        m = field.m
    elif field.__name__[:2] == "Z/":
        p = field.p
        m = 1
    else:
        raise ValueError
    # Iterate over field indices
    field_indices = itertools.product(*[range(p) for _ in range(m)])
    for index in field_indices:
        index = [field(ind) for ind in list(index)]
        term = construct_multivariate_dirac_delta(field, index, n)
        poly += step_fn(index) * term
    return poly
示例#18
0
  def test_exponentiation(self):
    """Tests exponentiation of multivariate polynomials."""
    modulus = 7
    mod7 = IntegersModP(modulus)
    n = 3
    # Let's make polynomials in (Z/7)[x, y, z]
    multi = multivariates_over(mod7, n).factory

    # This should equal 0
    zero_poly = multi({})
    assert zero_poly == zero_poly**2

    # This should equal y
    y_poly = multi({(0, 1, 0): mod7(1)})
    # This is y^2
    y_sq_poly = multi({(0, 2, 0): mod7(1)})
    assert y_sq_poly == y_poly**2

    # This should equal x + y
    x_y_poly = multi({(1, 0, 0): mod7(1), (0, 1, 0): mod7(1)})
    # This should equal x^2 + 2xy + y^2
    sq_x_y_poly = multi({(2, 0, 0): mod7(1), (1, 1, 0): mod7(2), (0, 2, 0): mod7(1)})
    assert sq_x_y_poly == x_y_poly**2