Advertisement
Guest User

Untitled

a guest
Oct 15th, 2019
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.68 KB | None | 0 0
  1. field_modulus = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
  2. desired_curve_order = 52435875175126190479447740508185965837690552500527637822603658699938581184513
  3.  
  4. Fp = GF(field_modulus)
  5.  
  6. PARAM_A4 = 0
  7. PARAM_A6 = 4
  8.  
  9. E = EllipticCurve(Fp, [PARAM_A4, PARAM_A6])
  10. E_order = E.order()
  11. assert E_order % desired_curve_order == 0
  12. assert desired_curve_order.is_prime() is True
  13. E_cofactor = E_order // desired_curve_order
  14. Fr = GF(desired_curve_order)
  15.  
  16. R.<T> = PolynomialRing(Fp)
  17.  
  18. # Starting at -1 is an arbitrary choice, could start at 1, where 2 will be the first non-residue
  19. if not Fp(-1).is_square():
  20. print("# -1 is non-residue")
  21. non_residue = -1
  22. F2.<u> = Fp.extension(T^2-non_residue, 'u')
  23. for j in range(1,4):
  24. if not (u+j).is_square():
  25. quadratic_non_residue = u+j
  26. F12_equation = (T^6 - j)^2 - non_residue
  27. u_to_w = T^6 - j
  28. w_to_u = T + j
  29. break
  30. else:
  31. print("Unknown")
  32.  
  33.  
  34. F12.<w> = Fp.extension(F12_equation)
  35. E12 = EllipticCurve(F12, [0, PARAM_A6])
  36.  
  37. E2 = EllipticCurve(F2, [0, PARAM_A6*quadratic_non_residue])
  38. is_D_type = False
  39. A_twist = 0
  40. if not (E2.order()/desired_curve_order).is_integer():
  41. B_twist = PARAM_A6/quadratic_non_residue
  42. E2 = EllipticCurve(F2, [0, B_twist])
  43. if not (E2.order()/desired_curve_order).is_integer():
  44. raise Exception('no twist had appropriate order')
  45. is_D_type = True
  46. print("# D type twist")
  47. F2_PARAM_A4 = PARAM_A4 / quadratic_non_residue
  48. F2_PARAM_A6 = PARAM_A6 / quadratic_non_residue
  49. else:
  50. # E2 order is divisible by curve order
  51. # TODO: get cofactor
  52. B_twist = PARAM_A6*quadratic_non_residue
  53. F2_PARAM_A6 = PARAM_A6 * quadratic_non_residue
  54. F2_PARAM_A4 = PARAM_A4 * quadratic_non_residue
  55. print('# M type twist')
  56.  
  57.  
  58. E2_order = E2.order()
  59. assert E2_order % desired_curve_order == 0
  60. E2_cofactor = E2_order // desired_curve_order
  61.  
  62.  
  63.  
  64. def frobenius_coeffs_powers(modulus, degree, num=None, divisor=None):
  65. divisor = divisor or degree
  66. num = num or 1
  67. tower_modulus = modulus ** degree
  68. for i in range(num):
  69. a = i + 1
  70. q_power = 1
  71. powers = []
  72. for j in range(degree):
  73. powers.append((((a*q_power)-a) // divisor) % tower_modulus)
  74. q_power *= modulus
  75. yield powers
  76.  
  77.  
  78. def frobenius_coeffs(non_residue, *args, **kwa):
  79. coeffs = list()
  80. for i, powers in enumerate(frobenius_coeffs_powers(*args, **kwa)):
  81. coeffs.append(list())
  82. for p_i in powers:
  83. coeffs[i].append( non_residue ** p_i )
  84. return coeffs
  85.  
  86.  
  87. def find_generator(E, F, a6, cofactor, order):
  88. for x in range(1, 10**3):
  89. x = F(x)
  90. y2 = x**3 + a6
  91. if not y2.is_square():
  92. continue
  93. y = y2.sqrt()
  94. p = cofactor*E(x, y)
  95. if not p.is_zero() and (order*p).is_zero():
  96. negy = -p[1]
  97. if negy < p[1]:
  98. return -p
  99. return p
  100.  
  101.  
  102. def find_s_t(name, n):
  103. for s in range(1, 50):
  104. if n % (2**s) == 0:
  105. t = n / 2**s
  106. assert t.is_integer()
  107. if not ((t-1)/2).is_integer():
  108. continue
  109. print name, "s", s
  110. print name, "t", t
  111. print name, "t_minus_1_over_2", (t-1)/2
  112. return s, t
  113.  
  114.  
  115. # Finds an R such that R = 2^k, R > N, for the smallest k.
  116. def mont_findR(N, limb_size=64):
  117. g = 0
  118. b = 2 ** limb_size
  119. R = b
  120. while g != 1:
  121. R *= b
  122. if R > N:
  123. g = gcd(R, N)
  124. return R
  125.  
  126.  
  127. def print_field(name, q, F):
  128. print name, 'modulus', q
  129. print name, 'num_bits', ceil(log(q,2))
  130. print name, 'euler', (q-1)//2
  131. s, t = find_s_t(name, q-1)
  132. print name, 'multiplicative_generator', F.vector_space()(F.multiplicative_generator())
  133. gen = F.gen()
  134. for i in range(0, 100): #for i in range(-1, -100, -1):
  135. i = gen+i
  136. if not i.is_square():
  137. i_to_t = i**t
  138. print name, 'nqr', F.vector_space()(i)
  139. print name, 'nqr_to_t', F.vector_space()(i_to_t)
  140. break
  141. print ""
  142.  
  143.  
  144. def print_R(name, q, nbits):
  145. R = mont_findR(q, nbits)
  146. print name, "R (%d-bit)" % (nbits,), R
  147. print name, "Rcubed (%d-bit)" % (nbits,), (R**2) % q
  148. print name, "Rsquared (%d-bit)" % (nbits,), (R**3) % q
  149. print name, "inv (%d-bit)" % (nbits,), hex((-q^-1) % 2**nbits)
  150.  
  151.  
  152. G1 = find_generator(E, Fp, PARAM_A6, E_cofactor, desired_curve_order)
  153. print 'bls12_381 G1_zero', E(0)
  154. print 'bls12_381 G1_one', [Fp.vector_space()(_) for _ in G1]
  155. print ""
  156.  
  157. G2 = find_generator(E2, F2, F2_PARAM_A6, E2_cofactor, desired_curve_order)
  158. print 'bls12_381_G2_zero', E2(0)
  159. print 'bls12_381 G2_one', [F2.vector_space()(_) for _ in G2]
  160. print ""
  161.  
  162. print_field('bls12_381_Fq2', field_modulus**2, F2)
  163. fp2_coeffs = frobenius_coeffs(non_residue, field_modulus, 2)
  164. for i, c in enumerate(fp2_coeffs):
  165. print 'bls12_381_Fq2', 'Frobenius_coeffs_c1[%d]' % (i,), '=', c
  166. print ''
  167.  
  168.  
  169. fp6_coeffs = frobenius_coeffs(quadratic_non_residue, field_modulus, 6, 2, 3)
  170. for i, _ in enumerate(fp6_coeffs):
  171. for j, c in enumerate(_):
  172. print 'bls12_381_Fq6', 'Frobenius_coeffs_c%d[%d]' % (i + 1, j), '=', F2.vector_space()(c)
  173. print ''
  174.  
  175. # Fq12 is two 6th degree towers
  176. fp12_coeffs = frobenius_coeffs(quadratic_non_residue, field_modulus, 12, 1, 6)
  177. for i, _ in enumerate(fp12_coeffs):
  178. for j, c in enumerate(_):
  179. print 'bls12_381_Fq12', 'Frobenius_coeffs_c%d[%d]' % (i + 1, j), '=', F2.vector_space()(c)
  180. print ''
  181.  
  182. print_R("bls12_381 Fr", desired_curve_order, 64)
  183. print_R("bls12_381 Fr", desired_curve_order, 32)
  184. print_field('bls12_381_Fr', desired_curve_order, Fr)
  185.  
  186. print_R("bls12_381 Fq", field_modulus, 64)
  187. print_R("bls12_381 Fq", field_modulus, 32)
  188. print_field('bls12_381_Fq', field_modulus, Fp)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement