4.5.2-multi-operation-polynomials.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. from bls_py import bls12381
  2. from finite_fields.modp import IntegersModP
  3. from finite_fields.polynomial import polynomialsOver
  4. n = bls12381.n
  5. mod_field = IntegersModP(n)
  6. poly = polynomialsOver(mod_field).factory
  7. def lagrange(points):
  8. result = poly([0])
  9. for i, (x_i, y_i) in enumerate(points):
  10. p = poly([y_i])
  11. for j, (x_j, y_j) in enumerate(points):
  12. if i == j:
  13. continue
  14. p *= poly([-x_j, 1]) / (x_i - x_j)
  15. #print(poly)
  16. #print(poly(1), poly(2), poly(3))
  17. result += p
  18. return result
  19. def poly_call(poly, x):
  20. result = mod_field(0)
  21. for degree, coeff in enumerate(poly):
  22. result += coeff * (x**degree)
  23. return result.n
  24. left_points = [
  25. (1, 2), (2, 2), (3, 6)
  26. ]
  27. left_poly = lagrange(left_points)
  28. #l = poly([2]) * poly([1, -1])
  29. print("Left:")
  30. print(left_poly)
  31. for x, y in left_points:
  32. assert poly_call(left_poly, x) == y
  33. right_points = [
  34. (1, 1), (2, 3), (3, 2)
  35. ]
  36. right_poly = lagrange(right_points)
  37. print("Right:")
  38. print(right_poly)
  39. for x, y in right_points:
  40. assert poly_call(right_poly, x) == y
  41. out_points = [
  42. (1, 2), (2, 6), (3, 12)
  43. ]
  44. out_poly = lagrange(out_points)
  45. print("Out:")
  46. print(out_poly)
  47. for x, y in out_points:
  48. assert poly_call(out_poly, x) == y
  49. target_poly = poly([-1, 1]) * poly([-2, 1]) * poly([-3, 1])
  50. assert poly_call(target_poly, 1) == 0
  51. assert poly_call(target_poly, 2) == 0
  52. assert poly_call(target_poly, 3) == 0
  53. main_poly = left_poly * right_poly - out_poly
  54. cofactor_poly = main_poly / target_poly
  55. assert left_poly * right_poly - out_poly == target_poly * cofactor_poly