bltprf.sage 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001
  2. K = GF(q)
  3. a = K(0x00)
  4. b = K(0x05)
  5. E = EllipticCurve(K, (a, b))
  6. G = E(0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000, 0x02)
  7. p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
  8. assert E.order() == p
  9. Scalar = GF(p)
  10. k = 3
  11. n = 2^k
  12. a = [Scalar(110), Scalar(56), Scalar(89), Scalar(6543),
  13. Scalar(2), Scalar(110), Scalar(44), Scalar(78)]
  14. x = Scalar.random_element()
  15. b = [x^i for i in range(n)]
  16. G = [E.random_element(), E.random_element(), E.random_element(),
  17. E.random_element(), E.random_element(), E.random_element(),
  18. E.random_element(), E.random_element()]
  19. assert len(a) == len(b) == len(G) == n
  20. # Dot product
  21. def dot(x, y):
  22. result = None
  23. for x_i, y_i in zip(x, y):
  24. if result is None:
  25. result = int(x_i) * y_i
  26. else:
  27. result += int(x_i) * y_i
  28. return result
  29. challenges = []
  30. commits = []
  31. original_a, original_G = a, G
  32. # Iterate k times where n = 2^k
  33. for current_k in range(k, 0, -1):
  34. half = 2^(current_k - 1)
  35. assert half * 2 == len(a)
  36. L = dot(a[half:], G[:half])
  37. R = dot(a[:half], G[half:])
  38. #z_L = dot(a[half:], b[:half])
  39. #z_R = dot(a[:half], b[half:])
  40. commits.append((L, R))
  41. challenge = Scalar.random_element()
  42. challenges.append(challenge)
  43. a = [a[i] + challenge^-1 * a[half + i] for i in range(half)]
  44. G = [G[i] + int(challenge) * G[half + i] for i in range(half)]
  45. assert len(a) == len(G) == half
  46. # Last iteration
  47. if current_k == 1:
  48. assert len(a) == 1
  49. assert len(G) == 1
  50. final_a = a[0]
  51. final_G = G[0]
  52. assert len(challenges) == k
  53. # G_3 = [G1, G2, G3, G4, G5, G6, G7, G8]
  54. # G_2 = [
  55. # G1 + x G5,
  56. # G2 + x G6,
  57. # G3 + x G7,
  58. # G4 + x G8
  59. # ]
  60. # G_1 = [
  61. # G_2_1 + x G_2_3,
  62. # G_2_2 + x G_2_4
  63. # ] = [
  64. # (G1 + x G5) + x (G3 + x G7) = G1 + x G3 + x G5 + x^2 G7,
  65. # (G2 + x G6) + x (G4 + x G8) = G2 + x G4 + x G6 + x^2 G8
  66. # ]
  67. #
  68. # We end up with a single remaining value
  69. #
  70. # G_0 = G_1_1 + x G_1_2
  71. # = G1 + x G2 + x G3 + x^2 G4 + x G5 + x^2 G6 + x^2 G7 + x^3 G8
  72. def get_jth_bit(value, idx):
  73. digits = bin(value)[2:]
  74. # Add zero padding
  75. digits = digits.zfill(k)
  76. return True if digits[idx] == "1" else False
  77. # get scalar values
  78. counters = []
  79. for i in range(1, n + 1):
  80. s = Scalar(1)
  81. for j in range(0, k):
  82. if get_jth_bit(i - 1, j):
  83. b = 1
  84. else:
  85. b = 0
  86. s *= challenges[j]^b
  87. counters.append(s)
  88. assert len(counters) == len(original_G)
  89. assert dot(counters, original_G) == final_G