4.6.2-multi-variable-operand-polynomial.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. from bls_py import bls12381
  2. from bls_py import pairing
  3. from bls_py import ec
  4. from bls_py.fields import Fq, Fq2, Fq6, Fq12, bls12381_q as Q
  5. from finite_fields.modp import IntegersModP
  6. from finite_fields.polynomial import polynomialsOver
  7. import random
  8. n = bls12381.n
  9. g1 = ec.generator_Fq(bls12381)
  10. g2 = ec.generator_Fq2(bls12381)
  11. mod_field = IntegersModP(n)
  12. poly = polynomialsOver(mod_field).factory
  13. def lagrange(points):
  14. result = poly([0])
  15. for i, (x_i, y_i) in enumerate(points):
  16. p = poly([y_i])
  17. for j, (x_j, y_j) in enumerate(points):
  18. if i == j:
  19. continue
  20. p *= poly([-x_j, 1]) / (x_i - x_j)
  21. #print(poly)
  22. #print(poly(1), poly(2), poly(3))
  23. result += p
  24. return result
  25. l_a_points = [
  26. (1, 1), (2, 1), (3, 0)
  27. ]
  28. l_a = lagrange(l_a_points)
  29. #print(l_a)
  30. l_d_points = [
  31. (1, 0), (2, 0), (3, 1)
  32. ]
  33. l_d = lagrange(l_d_points)
  34. #print(l_d)
  35. # a x b = r_1
  36. # a x c = r_2
  37. # d x c = r_3
  38. # a = 3
  39. # d = 2
  40. L = 3*l_a + 2*l_d
  41. #print(L)
  42. def poly_call(poly, x):
  43. result = mod_field(0)
  44. for degree, coeff in enumerate(poly):
  45. result += coeff * (x**degree)
  46. return result.n
  47. assert poly_call(L, 1) == 3
  48. assert poly_call(L, 2) == 3
  49. assert poly_call(L, 3) == 2
  50. def rand_scalar():
  51. return random.randrange(1, bls12381.q)
  52. #################################
  53. # Verifier (trusted setup)
  54. #################################
  55. # samples a random value (a secret)
  56. toxic_scalar = rand_scalar()
  57. # calculate the shift
  58. alpha_shift = rand_scalar()
  59. l_a_s = poly_call(l_a, toxic_scalar)
  60. l_d_s = poly_call(l_d, toxic_scalar)
  61. enc_a_s = g1 * l_a_s
  62. enc_a_s_alpha = enc_a_s * alpha_shift
  63. enc_d_s = g1 * l_d_s
  64. enc_d_s_alpha = enc_d_s * alpha_shift
  65. # Proving key is enc_* values above
  66. # Actual values of s are toxic waste and discarded
  67. verify_key = g2 * alpha_shift
  68. #################################
  69. # Prover
  70. #################################
  71. a = 3
  72. d = 2
  73. assigned_a = enc_a_s * a
  74. assigned_d = enc_d_s * d
  75. assigned_a_shift = enc_a_s_alpha * a
  76. assigned_d_shift = enc_d_s_alpha * d
  77. operand = assigned_a + assigned_d
  78. operand_shift = assigned_a_shift + assigned_d_shift
  79. # proof = operand, operand_shift
  80. #################################
  81. # Verifier
  82. #################################
  83. e = pairing.ate_pairing
  84. assert e(operand_shift, g2) == e(operand, verify_key)