You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

327 lines
40 KiB

Implement WB hash2curve for BLS12-377 and BLS12-381 (#138) * include the coefficients of bls12-377 G1 and G2 isogenies for wb hash2curve * replacing the ark-ec dependency to w3f/arkworks-algebra * added parameters for isogenous curve to bls12-377 g1 curve for swu map * fix dependency inconsistency problem * implement WBParams and its isogenous curve for BLS12-377 G1 * implement the SWUParameters for isogenous curve to BLS12-377 g2 curve. * implement WBParams for BLS12-377 G2 curve * replacing const generic arrays with const slice in g1 and g2 iso coefficients * - Implement WB hash to curve for BLS12-381 G1 - Improvement to WB hash to curve code for BLS12-377 - Update sage code for generating isogeny coefficients for arkworks. * Implement WB hash to curve for BLS12-381 G2 * - fix the bug with base order for field_new for Fq2 - fix the polynomial coeffcient order for bls12-381 g1 and g2 isogenies. - fix the polynomial coeffcient order for bls12-377 g1. 377-g2 needs to be fixed still. * fix bls12-377 wb hash to curve isogeny coeffcients * fixed sage code for generating the isogeny coefficients * use patch.crates-io hack to resolve dependancy issues on w3f fork * Rename `Parameters` to `Config` for all fields * Rename `field_new` to `MontFp` * Rename `field_new` to `QuadExt` and `CubicExt` * Refactor bls12_381 crate based on update-ff branch. Close #9 * adapt bls12 wb hashing to new changes in algebra * update bls12-381 dependancies and g1, g2 definition to pass tests * adapt bls12-377 hash to curve to algebar updates * depend on upstream for pull request * cargo fmt * - move the isogeny finder script from sage to script folder - delete auxiliary isogeny coeff file * add unit tests for wb hashing to bls12-377 g1 and g2 * - Use IsogenyMap struct to specify WB Isogeny for bls12-381 and bls12-377 - Do not use auxiliary constants to define generators of g2_swu_iso curve. - Update change log * Bump the Algebra dependencies of bls12_381 and bls12_377 to 0.4.0-alpha.4 so they could use the IsogenyMap struct. * Add h2c tests for BLS12-381 curve * Drop alpha sub-version in dependancies because it takes the lastest sub version * Parameters → Config for bls12-377/381 curves * do cargo fmt * do SwuIsoParameters → SwuIsoConfig for bls12-377/381 * Adapt to new macro * Fix macro invocation should be semicolon not comma * curves master should use algebra/r1cs default branch * Add h2c test invocation for bls12-377 curve no actual test vectors yet * add faster cofactor clearing and tests for g1 * add faster cofactor clearing and tests for g2 parameters of endomorphisms are wrong for now * add test vectors for bls12-377 * add h_eff to g2 tests for correctness test * improve cofactor tests g2 * add a test for psi(psi(P)) == psi2(P) * fix bls12-377 psi & psi2 computation parameters * rename const to DOUBLE_P_POWER_ENDOMORPHISM_COEFF_0 and make private * fix clippy warnings in changed code * use the same zeta as test suites * update code comments, make methods private * update changelog Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu> Co-authored-by: mmagician <marcin.gorny.94@protonmail.com>
1 year ago
  1. # look for isogenous curves having j-invariant not in {0, 1728}
  2. # Caution: this can take a while!
  3. def find_iso(E):
  4. for p_test in primes(30):
  5. print("trying isogenies of degree %d"%p_test)
  6. isos = []
  7. for i in E.isogenies_prime_degree(p_test):
  8. print("checking j-invariant of isogeny ", i)
  9. jinv = i.codomain().j_invariant()
  10. print("j-invariant is ", jinv)
  11. if jinv not in (0, 1728):
  12. isos.append(i)
  13. if len(isos) > 0:
  14. for cur_isos in isos:
  15. print("found isogeny ", cur_isos)
  16. #print("found isogeny ", isos[0])
  17. return isos[0].dual()
  18. return None
  19. def bls12_381_isos():
  20. # BLS12-381 parameters
  21. z = -0xd201000000010000
  22. h = (z - 1) ** 2 // 3
  23. q = z ** 4 - z ** 2 + 1
  24. p = z + h * q
  25. assert is_prime(p)
  26. assert is_prime(q)
  27. # E1
  28. F = GF(p)
  29. Ell = EllipticCurve(F, [0, 4])
  30. assert Ell.order() == h * q
  31. # E2
  32. F2.<X> = GF(p^2, modulus=[1,0,1])
  33. Ell2 = EllipticCurve(F2, [0, 4 * (1 + X)])
  34. assert Ell2.order() % q == 0
  35. iso_G1 = find_iso(Ell)
  36. # an isogeny from E’ to E,
  37. Ell_prime = iso_G1.domain()
  38. # where this is E’
  39. assert iso_G1(Ell_prime.random_point()).curve() == Ell
  40. iso_G2 = find_iso(Ell2)
  41. # an isogeny from E2’ to E2,
  42. Ell2_prime = iso_G2.domain()
  43. # where this is E2’
  44. assert iso_G2(Ell2_prime.random_point()).curve() == Ell2
  45. return (iso_G1, iso_G2)
  46. def bls12_377_isos():
  47. p = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001 # BLS12-377 parameters
  48. q = 0x12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001
  49. z = 0x8508c00000000001
  50. #z = -0xd201000000010000
  51. h = (z - 1) ** 2 // 3
  52. q1 = z ** 4 - z ** 2 + 1
  53. p1 = z + h * q
  54. assert(q1 == q)
  55. assert(p1 == p)
  56. assert is_prime(p)
  57. assert is_prime(q)
  58. # E1
  59. F = GF(p)
  60. Ell = EllipticCurve(F, [0, 1])
  61. assert Ell.order() == h * q
  62. # E2
  63. quad_non_res = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508bffffffffffc
  64. F.<X> = GF(p)[]
  65. F2.<X2> = GF(p^2, modulus=X^2 - quad_non_res)
  66. #F2.<X> = GF(p^2, modulus=[1,0,quad_non_res])
  67. B = 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906 * X2
  68. Ell2 = EllipticCurve(F2, [0, B])
  69. assert Ell2.order() % q == 0
  70. F.<X> = GF(p)[]
  71. F6.<X6> = GF(p^6, modulus=X^6 - quad_non_res)
  72. B = 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906 * X6^3
  73. Ell2_6 = EllipticCurve(F6, [0, B])
  74. Ell2_6.order() % q
  75. G1_X = 0x008848defe740a67c8fc6225bf87ff5485951e2caa9d41bb188282c8bd37cb5cd5481512ffcd394eeab9b16eb21be9ef
  76. G1_Y = 0x01914a69c5102eff1f674f5d30afeec4bd7fb348ca3e52d96d182ad44fb82305c2fe3d3634a9591afd82de55559c8ea6
  77. #make sure the generator is on the curve
  78. X_cx0 = 0x018480be71c785fec89630a2a3841d01c565f071203e50317ea501f557db6b9b71889f52bb53540274e3e48f7c005196
  79. X_cx1 = 0x00ea6040e700403170dc5a51b1b140d5532777ee6651cecbe7223ece0799c9de5cf89984bff76fe6b26bfefa6ea16afe
  80. Y_cy0 = 0x00690d665d446f7bd960736bcbb2efb4de03ed7274b49a58e458c282f832d204f2cf88886d8c7c2ef094094409fd4ddf
  81. Y_cy1 = 0x00f8169fd28355189e549da3151a70aa61ef11ac3d591bf12463b01acee304c24279b83f5e52270bd9a1cdd185eb8f93
  82. iso_G1 = find_iso(Ell)
  83. # an isogeny from E’ to E,
  84. Ell_prime = iso_G1.domain()
  85. # where this is E’
  86. assert iso_G1(Ell_prime.random_point()).curve() == Ell
  87. generate_WBParams_Fq(iso_G1)
  88. # just making sure if there is any isogeny that is defined over F2 up to degree 30
  89. print("searching for isogeny of Ell2 on F2 up to degree 30")
  90. iso_G2 = find_iso(Ell2)
  91. generate_WBParams_Fq2(iso_G2)
  92. print("searching for isogeny of Ell2 on F6 up to degree 30")
  93. iso_G2_F6 = find_iso(Ell2_6)
  94. #iso_G2=iso_G2_F6
  95. # an isogeny from E2’ to E2,
  96. Ell2_prime = iso_G2.domain()
  97. # where this is E2’
  98. assert iso_G2_F6(Ell2_prime.random_point()).curve() == Ell2_6
  99. return (iso_G1, iso_G2)
  100. def trace_endo(P, p2):
  101. ParentCurve = P.curve()
  102. return P + ParentCurve((P[0]^p2, P[1]^p2)) + ParentCurve((P[0]^(p2^2), P[1]^(p2^2)))
  103. def bls12_377_hash_to_G2(e2_p6S_iso, data):
  104. p = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001 # BLS12-377 parameters
  105. Fp = GF(p)
  106. # E2
  107. quad_non_res = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508bffffffffffc
  108. F.<X> = GF(p)[]
  109. F2.<X2> = GF(p^2, modulus=X^2 - quad_non_res)
  110. #F2.<X> = GF(p^2, modulus=[1,0,quad_non_res])
  111. B = 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906 * X2
  112. Ell2 = EllipticCurve(F2, [0, B])
  113. F.<X> = GF(p)[]
  114. F6.<X6> = GF(p^6, modulus=X^6 - quad_non_res)
  115. B = 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906 * X6^3
  116. Ell2_6 = EllipticCurve(F6, [0, B])
  117. Fpelm = Fp(hash(data))
  118. Ep2 = e2_p6S_iso.domain()
  119. a = Ep2.hyperelliptic_polynomials()[0][1]
  120. b = Ep2.hyperelliptic_polynomials()[0][0]
  121. X_0 = - (b/a) * ( 1 + 1/(xsi^2*Fpelm^4 + xsi*Fpelm^2))
  122. if Ep2.is_x_coord(X_0):
  123. P_p = Ep2.lift_x(X_0)
  124. else:
  125. P_p = Ep2.lift_x(xsi*Fpelm^2*X_0)
  126. P_F_6 = e2_p6S_iso(P_p)
  127. P = trace_endo(P_F_6, p^2)
  128. x_p = P[0].polynomial().coefficients()[1]*X2 + P[0].polynomial().coefficients()[0]
  129. y_p = P[1].polynomial().coefficients()[1]*X2 + P[1].polynomial().coefficients()[0]
  130. P_down = Ell2((x_p,y_p))
  131. return P_down
  132. # BLS12-377 curve is fully defined by the following set of parameters (coefficient A=0 for all BLS12 curves):
  133. # Base field modulus = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
  134. # B coefficient = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
  135. # Main subgroup order = 0x12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001
  136. # Extension tower:
  137. # Fp2 construction:
  138. # Fp quadratic non-residue = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508bffffffffffc
  139. # Fp6/Fp12 construction:
  140. # Fp2 cubic non-residue c0 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
  141. # Fp2 cubic non-residue c1 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
  142. # Twist parameters:
  143. # Twist type: D
  144. # B coefficient for twist c0 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
  145. # B coefficient for twist c1 = 0x010222f6db0fd6f343bd03737460c589dc7b4f91cd5fd889129207b63c6bf8000dd39e5c1ccccccd1c9ed9999999999a
  146. # Generators:
  147. # G1:
  148. # X = 0x008848defe740a67c8fc6225bf87ff5485951e2caa9d41bb188282c8bd37cb5cd5481512ffcd394eeab9b16eb21be9ef
  149. # Y = 0x01914a69c5102eff1f674f5d30afeec4bd7fb348ca3e52d96d182ad44fb82305c2fe3d3634a9591afd82de55559c8ea6
  150. # G2:
  151. # X cx0 = 0x018480be71c785fec89630a2a3841d01c565f071203e50317ea501f557db6b9b71889f52bb53540274e3e48f7c005196
  152. # X cx1 = 0x00ea6040e700403170dc5a51b1b140d5532777ee6651cecbe7223ece0799c9de5cf89984bff76fe6b26bfefa6ea16afe
  153. # Y cy0 = 0x00690d665d446f7bd960736bcbb2efb4de03ed7274b49a58e458c282f832d204f2cf88886d8c7c2ef094094409fd4ddf
  154. # Y cy1 = 0x00f8169fd28355189e549da3151a70aa61ef11ac3d591bf12463b01acee304c24279b83f5e52270bd9a1cdd185eb8f93
  155. # Pairing parameters:
  156. # |x| (miller loop scalar) = 0x8508c00000000001
  157. # x is negative = false
  158. # Curve information:
  159. # Base field: q = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
  160. # Scalar field: r = 8444461749428370424248824938781546531375899335154063827935233455917409239041
  161. # valuation(q - 1, 2) = 46
  162. # valuation(r - 1, 2) = 47
  163. # G1 curve equation: y^2 = x^3 + 1
  164. # G2 curve equation: y^2 = x^3 + B, where
  165. # B = Fq2(0, 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906)
  166. # e26_order = Ell2_6.order()
  167. # for i in primes(30):
  168. # if e26_order % i == 0:
  169. # print("order is divisable by ", i)
  170. def find_non_square():
  171. quad_non_res = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508bffffffffffc
  172. F.<X> = GF(p)[]
  173. F6.<X6> = GF(p^6, modulus=X^6 - quad_non_res)
  174. xsi = 0
  175. R.<X> = F6[]
  176. for i in F6:
  177. j = F6.random_element()
  178. if not j.is_square():
  179. xsi = j
  180. break
  181. return xsi
  182. def find_non_square_low_abs(base_field):
  183. for i in base_field:
  184. if not i.is_square():
  185. print(i, "is a nonsquare")
  186. return i
  187. elif not (-i).is_square():
  188. print(-i, "is a nonsquare")
  189. return -i
  190. def find_non_square_low_abs_in_F2(extended_field):
  191. """
  192. Note that everything in Fp is an square in Fp^2
  193. suppose a in F_p^2 and b in F_p are primitive elements
  194. in their respective field.
  195. a and b have multiplicative order (p-1)(p+1) and (p-1)
  196. suppose b = a^c so b^(p-1) = a^(c)(p-1) = 1 so
  197. d(p+1)(p-1) = (c)(p-1) so (p+1)|c => 2|c so then
  198. (a^c/2)^2 = b so b has square.
  199. also all degree 2 extensions of Fp are isomorphic. so
  200. if you add square root of an element you can find it
  201. in the original Fp
  202. """
  203. base_field = extended_field.base()
  204. for i in base_field:
  205. for j in base_field:
  206. for k in [(1,1),(-1,1),(1,-1),(-1,-1)]:
  207. candidate = extended_field([i*k[0],j*k[1]])
  208. if not candidate.is_square():
  209. print(candidate, "is a nonsquare")
  210. return candidate
  211. def generate_WBParams_Fq(Fq_isogeny):
  212. print("\nconst PHI_X_NOM: &'static [<Self::IsogenousCurve as ModelParameters>::BaseField] = &"+convert_g1_coeff_arrays_to_arkworks(Fq_isogeny.rational_maps()[0].numerator()))
  213. print("\nconst PHI_X_DEN: &'static [<Self::IsogenousCurve as ModelParameters>::BaseField] = &"+convert_g1_coeff_arrays_to_arkworks(Fq_isogeny.rational_maps()[0].denominator()))
  214. print("\nconst PHI_Y_NOM: &'static [<Self::IsogenousCurve as ModelParameters>::BaseField] = &"+convert_g1_coeff_arrays_to_arkworks(phi2_num(Fq_isogeny)))
  215. print("\nconst PHI_Y_DEN: &'static [<Self::IsogenousCurve as ModelParameters>::BaseField] = &"+convert_g1_coeff_arrays_to_arkworks(Fq_isogeny.rational_maps()[1].denominator()))
  216. def convert_g1_coeff_arrays_to_arkworks(iso_poly):
  217. """
  218. convert an array of coefficients in Fp2 to arkwork format
  219. """
  220. arkwork_array = '[\n'
  221. for cur_deg in range(0, iso_poly.degree() + 1):
  222. coeff_selector = [cur_deg]
  223. coeff_selector.extend([0]*(len(parent(iso_poly).gens())-1))
  224. arkwork_array += 'field_new!(Fq, \"' + str(iso_poly.coefficient(coeff_selector)) + '\"), \n'
  225. arkwork_array = arkwork_array[: -2] + '\n];'
  226. return arkwork_array
  227. def phi2_num(Fq2_isogeny):
  228. return (Fq2_isogeny.rational_maps()[1].numerator()/Fq2_isogeny.rational_maps()[1].numerator().variables()[1]).numerator()
  229. def generate_WBParams_Fq2(Fq2_isogeny):
  230. print("\nconst PHI_X_NOM: &'static [<Self::IsogenousCurve as ModelParameters>::BaseField] = &"+convert_g2_coeff_arrays_to_arkworks(Fq2_isogeny.rational_maps()[0].numerator()))
  231. print("\nconst PHI_X_DEN: &'static [<Self::IsogenousCurve as ModelParameters>::BaseField] = &"+convert_g2_coeff_arrays_to_arkworks(Fq2_isogeny.rational_maps()[0].denominator()))
  232. print("\nconst PHI_Y_NOM: &'static [<Self::IsogenousCurve as ModelParameters>::BaseField] = &"+convert_g2_coeff_arrays_to_arkworks(phi2_num(Fq2_isogeny)))
  233. print("\nconst PHI_Y_DEN: &'static [<Self::IsogenousCurve as ModelParameters>::BaseField] = &"+convert_g2_coeff_arrays_to_arkworks(Fq2_isogeny.rational_maps()[1].denominator()))
  234. def convert_g2_coeff_arrays_to_arkworks(iso_poly):
  235. """
  236. convert an array of coefficients in Fp2 to arkwork format
  237. """
  238. arkwork_array = '[\n'
  239. for cur_deg in range(0, iso_poly.degree() + 1):
  240. elm_poly = iso_poly.coefficient([cur_deg])
  241. assert(elm_poly.is_constant())
  242. elm_poly = elm_poly.constant_coefficient().polynomial()
  243. x_gen = parent(elm_poly).gen()
  244. arkwork_array += 'field_new!(Fq2, \nfield_new!(Fq, \"' + str(elm_poly.monomial_coefficient(x_gen^0)) + '\"), \nfield_new!(Fq, \"' + str(elm_poly.monomial_coefficient(x_gen^1)) + '\")), \n'
  245. arkwork_array = arkwork_array[: -2] + '\n];'
  246. return arkwork_array
  247. #xsi = find_non_square()
  248. p = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
  249. quad_non_res = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508bffffffffffc
  250. F.<X> = GF(p)[]
  251. F6.<X6> = GF(p^6, modulus=X^6 - quad_non_res)
  252. xsi = 219316876564715501445845678793720069854490678622108189766720284953606550746049804013989455416277727490975087855145*X6^5 + 189466179801738810887203415755624953151244475240588395433085007196132075694018697411282623497091853518199320679360*X6^4 + 108520825812509855860919714742321990242401369063484109910639742940603686352843166577300516208027451357460988981712*X6^3 + 34112775793303707113282524593132637468394825594735587392051797399858875786055772232469914619100641475357422803395*X6^2 + 24571511079604071320024029432159749780558012896103101565537728634741822079830191849836550641682167566004999041634*X6 + 159529377420408936856843219892213059773340895657856533814435812939320020966386099270143668590340681432634121813716
  253. g1_iso, g2_iso = bls12_377_isos()
  254. message = "'I refuse to prove that I exist,' says God, 'for proof denies faith, and without faith I am nothing.'"
  255. print(bls12_377_hash_to_G2(g2_iso, message))
  256. print(bls12_377_hash_to_G2(g2_iso, message))
  257. message = "'if you stick a Babel fish in your ear you can instantly understand anything said to you in any form of language."
  258. print(bls12_377_hash_to_G2(g2_iso, message))
  259. print(bls12_377_hash_to_G2(g2_iso, message))
  260. phi_x_nom = [F2(257686488674545770403807165703608491821700153538449954828958424244540050698630649531963334687249831352703307010320), 111424637101855455933266154646364284011426845669269128135151076357862608862363255550023430066507374024948118755170*X2 + 42757221749971324771094873984161893488770713619971906650868412147150411626107692517374735631529074208182971223761, 225121846650282460844501132545123914298308844633699320249517374760159461135641190512758348530493533776082794775238*X2 + 182397511129719455005407008314265069548677727690813781407770284951663734172103638427690475141072553074575221965383, 207900273391847649346738694548609379565855077833395139615718913929125517933139374225345876078131155102796477330196*X2 + 57815299880375466472857931022912171296473275308202666945592250229771936329503691945881925004852905385160277065937, 126932856673577834557989832150639712812952235385146245135235966945536973066700604316981524138335070494135486842267*X2 + 137461512605659170682300574841422927080299499340556631216517745531687218204749421916211266297116812992348911035943, 239220883081126775212690475926873251881459118214247205003758844846022330659109168499739536107988232402392010148915*X2 + 46999088780962505530452862218145506822520603893157196954987630663398814970386085186714696215299498862118704356116, 134745690770497208213126494241047670387239583870118646766457825646403640347226342104549240830903829682059982326727*X2 + 139197805910452438551419010260519164074855817417063470117576949912038778696248952069759607969690314639425179841530, 13030331252003455924520111292282390143014750833628314421882396445822808054003584720817672388894671968339344750750*X2 + 205538184807792915395400814312734290381492118179294333381188081024280220461983210331268164749465891791515156713363, 140302880976816076816721836344737338071783799730513599397010923016385668972882234545823525686327074617973208860421*X2 + 142477190388553987083175296028785369398580520754966744245694134692905987471896623788336582063245356609279657681007, 139097554917981907719834170888130444861465074977932740823078016609751284491153969166862091045221603146530147099779*X2 + 224387508661509885922784938707800296916307265709615639996851552571542396031861010679067114387017955365668256976459, 168051662766288660516992486993594951443897767271245608184500932350745292043277998040372769419920145370014740823389*X2 + 205121513164720886728676669276499362266139599046368626660027529707299170205603076104821498121463983514654737906998, 75932324143801627944771670190157701465835368459121478812142087933983158148741884038298732552979549182443318608554*X2 + 121805396188033590038927712795579559087103093135515082191363074395734682090746320669474388875423586929711608364404, 71494892585734577638768956295356005795556178117525317604450863442514001295461407965931789120761632296953990284809*X2 + 129405180560592211762572081137246817341681076084973348177153469170177032429929182033872985192027066614650754524309, 7531651998638745138624528632013700806848273210661661935097722938692087106885113623803921367479582718152259987647*X2 + 33702103741469458207888758659069786556456463428431771947788685622778743201883736580054112022350187936628758294279, 233542978062801907184831603532041452683131033894029390005010898310417350737942550513935694209129350870817277172583*X2 + 188864327416940344326229259749844123042825201085435432627935318423081174922012610651352346391417830722940140585036, 55517007457989983858891530398020104232682844055600438506715652841000901588962918721851719951820185832313468320365*X2 + 18662780664429933771192510151421557554668611953190652639195940454142648933454488952361465779870877163142807899993, 97587419381711441517698658129839468394457401157021696651597713140291602428957555768352336399994179660880524139808*X2 + 96957224446676123824350918241672464825735454895610578698586352322390662445273628285471423071856275085141118045105, 141639542381992520856560441410242716791591163086143661904501184306161835850893036003163803884002896297253767009574*X2 + 231615170079008089001496386178968115998492752668752266579314749799030868007672086089822600816657899022828734321418, 116602947282570158568911982642223012726308726836613908383578383334370050655181609483409110122767402070015216413338*X2 + 161628978970526519329329822295337582413127505041035400390544637404697415598883543152357105789965717470570494458589, 134026238756820071135251263743482298414233385640297868129438877114735051445009051866011097877494554014116371908672*X2 + 231856156439094824000656216233999389240375109059054378946071472571709648546048606758615235778059505184730503731408, 124795068789978952575783920730487695370136831800946532752608526840944057283524691812795315973894625798220920082767*X2 + 240831597672798022181780196442988629902557797416422752447288392631352072879531084668083129009311685341499602842359, 26460985441766134300772651139298255538590921173641559533448371120006177647448359485069994828122162245692248966113*X2 + 88440326308038176392218244342168484162310820452393341528824316035047758188693394849605113877264996124652991932266, 133330677606878026253733532636681674371349711466687180056118155523679405609126901243884039337337134962627419965345*X2 + 49078863819486020728803126419770411403544927967564775122533948145670810135602221046611632159195633125363688522753, 172182978063994664796636281648715261218877265445686511820228400278128135165425091257965367402286789184662480399420*X2 + 165752316658948679552567650341600213993620343632797226373648182250196112194084163699689918190990441453209217107673]
  261. phi_x_den = [0, 1, 226808321937551848279625259185874129283473963677740840941191767963773773116795416044456897499248110949601850478751*X2 + 114765242606519624982400506165904237893471895287563151339459173837887003905317760268941880935997925302483810508170, 38216467720351249271557670250657907497353617320059247139049052120842234439257669911851800147147313339669901995490*X2 + 69204740140688189359361744597982172008615446130082862488352885921056331761951244674105352971861180999345144984246, 122245180850560437899129167839042992977076962956306963014567407897293197200681367630073717776421484831646532593850*X2 + 88800087516399959501800534486349824688877578947555023348699585957763763180753947498274724426567091309571649023166, 40524381030862708561992431051313657250449208728762250622105264621614810013551839533882876237430311293361821844681*X2 + 219867891253233227579149075701158020315633373195728794672342716359369374905471205886891783929214978430681990036959, 258564647705165711537697112631909171171984598885182416737094411313452565619624851452883996847677936536536427515609*X2 + 61539107135026562717413992304341045078777699607129438878970720148394005607774781361280841945254066290447512808860, 159070381032762485827712709726121404273458384870681735035622289092845201234785949112608113110663482448286550123895*X2 + 82401683815523491481199527201592079745651015539510634295850130611233688561451492330603949648060220533354045095181, 48223421552324743764826987807666420223567068651197810526658625431719723647078135623842652870214605734395702563953*X2 + 228687493726193558146661770435566220015197012398911029567178581932152080915557441338298274247922585720118620741642, 218641591773893348322227471378547165043111820723080862748702228639502320411481947789769811366015509814793754417785*X2 + 135098057022357227608956235549944366234286127511416070373827898662879730495316177891045223676768538262860577751087, 47600282095791674213992406796226738606147801920837771594412659335039656256887529097801732359033209329929517773020*X2 + 137972103666241533333852948884443545062916813938500094392929132716673981519930321922556812217620174550912349461419, 172261303485740204844677209985093962119870302741179905216184157502752680126595180139007438892219460422745105017475*X2 + 155939253194251956164424003889230633804182501306742152137449150503013281009623802843490858570697615902305132709111, 196336324454181158449524835117699225596467237400207491815838252818724619960701247377784788803043096102210425517795*X2 + 146699001487357489560227247646638441970227213145065178169054120124066032784405371946823057532199624317631250110158, 247894577734607804564008327202067464850944943412136922154651844411293409127507835027401641672218158657943826643185*X2 + 219195224293908756855578672234544437367397890301565855376597788842679778002659222115121213889017072727428356719234, 39000405073743042346296304484168728185850505353133307908773204457381817815206498660334035187329579833299098854925*X2 + 220384543328043309613139993483671702409123249316603413540407457441864555087013622511692877380446192851630287225413, 73874168720549156282270730246833500558176745413797996774310087510749148634278604002052708223696920208907646881989*X2 + 200535851812830711305923885193456283997079838967145939474743725430895019937175928830731575175640901984178880783011, 1943403947563275150997369785095274118967148389261968103605246462390957897712088493386683316483490223770940902453*X2 + 142027935684179419855710336591935481541662612521926997142809731189880364304749483394981554800161483370077741056896, 10757428905957703588038877674336794621171834192483169256644941002565404396356505770991807551250572677872221995215*X2 + 33059404918884325948584592996172619413923041143099424466021368531149134447772287601175965141235934645074697267050, 99720174640078175171062115168656883367851695095484071724968247253018133737453004325770034298778522431209097310502*X2 + 168096269708683796856556357930292925811554548435612382636199127159818409693729567946366892866365435246772528367031, 95980723944521770226526824868742386994509079773043937452565624851192578861364669763702851513923262074687274763858*X2 + 11697862001088266121450094179739500241088837734277696824118211258364151630931186792937914301859707394679202145393, 214943806307523271117409515396321303330984956986022871981067208079182219051826091487389512723678609613943324945884*X2 + 247957910140234524214324761874381439955705875777136703199106095643204254634304448830280410483013931961038942096519, 154931903368935230733381648548242132592387960818255334523314635613616976204585469590179605887364646535250639335453*X2 + 133779461364688439286044255858523747234865723284672664672066362220940987786797573428234566651244275384657571315397, 38999017135204040984255776995893429123212353273299706702441986090800506456890730978953545316903022073202240280957*X2 + 73314120416427646620569455169905724114883313094893949291513517502168861559767103394033744003864213510722887906274, 106967816747202586221026040614608875779671819314280336591550617355334247302203894951925800601923998790402234025494*X2 + 196537929755540830130458921156910352741196129560556501635658595085779576490417628044619830744899117989899096675116]
  262. phi_y_nom = [191144230647045707590184821948778479495825928592047153194222027257046414968351470170933284561757547536684715232224, 187207294428708203829145346569036650547801585764458185253951079008883539428999915118458145884040644479498579194069*X2 + 8411654157888762354868203383638678565276209861191964793314989111047210939710084789719415109438273538021505111510, 38886256490758184304393553179653915986060051480245869194662478974097783410818598716423697164666847852998235320966*X2 + 133980604703672698089766182661998480874540278232523164821108522954758888202993741126021280431373622479768313949356, 221484407095875062109245088271905042727631591858266177514520864715688286361376419124935364810076972840743950061836*X2 + 165653628641840315664303139225783620502451401675361521932235743336920154286645843675719999005591028855021909439672, 138246251209835932037747211155451146889753321830881007441732932302281412878493276648902633332871835811473542877960*X2 + 187289608720372854303118076618428364941868395899689208696722069999084187290922488892094161492110977423619035272649, 92602205576740019970555092291786069878442230185393269119060098961688837594116147683652993589116622567477525635445*X2 + 149340524242957423974772893433814190392014381473852786295383636551096665463613496468840974015807625484823068784839, 14821532235517245029225575994881495294340097494060025842437989195232333244802578196149414170959605497405878582540*X2 + 216436913923048926393371382639334167145590308917722616640273699755872914758105310937706004925121569777096571773501, 214497132288922282410470995366492104127705853917251639956391350188219443322307620708083843529019036699996096662829*X2 + 107794270350250727824303719264349327362253764840855494366195678657690526275364378542854833701549538802096418248084, 219490420378012040044597900078465204875085141304274262719756064241884227366143829466191943246131284770521917871841*X2 + 209865017468509971341642462085093919192185569139223034709204939485243056860760867821924437786503336074163109167043, 214026235442364760645768878901893433888530027239186932434340221483611429797860448445573321733516533800376783586849*X2 + 133226465537371725791207823007732608016851433266603356824246032571600774858733596680855277271698121233692296984412, 225199447663521472758596124691205483139271667363437613911741821442536429098852529066869544898685674003162780468715*X2 + 89345438915485267000169594163110872264018138861479961667441187849751112704236404111089533981719810422892295971197, 93302878136439028547402102681387844515310157832968167882878653011659204369510932686206718073261314562836132094987*X2 + 25945524144868616798377005434321968607597029473408456417628770501736226577600936996306306386148517051252174176056, 76313913933214383311039506294052736258824720597935452573279680967713148986901401959316819572744945391130691484709*X2 + 128014602802339573117431114877417430852771121268703430430938496966993823548956133449208721198231566864014207876438, 236947842470057836630333692287445445381482585314120394670322793497639860754696181540315462907276465780536189751938*X2 + 190392008574458975806418600277835706985376229847531539152452591238358119216217627352637258288556199770365835067627, 120208242722200714489749801697072499732825359039071841003310452443348308205795253556381720202955786470886397257982*X2 + 24894203921911934571199160858232802417038583022586807490232139245280305064770051397858560092019807972764914216208, 153830492090479629579603390014414329445124716355506854714467139884353350218676155251380590350715220577136073627555*X2 + 134073844001083825421215848942909782702386338984309026786345170296027964134133613977422644522116018820345983847098, 9418692556935347898382092734571186686450013671235254851703843297990915553970523788207837029694342875454233715193*X2 + 8193038016485856982946817225511231096542148907426451941320763511467909442967073658628847889502238964737537651732, 38290302770763423573829549940707041833171456153861823771988991461936307395626028842226881832323571911777783325552*X2 + 187038260664272653235271156369560372695631446985830424056061915935191103410794701043280599214000281588074544657045, 41800154023275681622180037448850007404785328883356603798952195956734186941687720006035939799906615555216990599152*X2 + 232464396645736057215489125286424902556417590819993013568149210848680788030572385843387291711255018198764185991688, 67221897212365550931740188657735915316732820967428518278153545138481072202717711417949297443415145931349647354864*X2 + 1902545032251691771730077590223241149624964994150687591044314892275508885163105731414463515832696686914784357054, 61944739699039529393579599024212698483276675572994284564132452254474389809816373777333943401872462638231436446348*X2 + 43364741387169348753014627410136368149262698966106150910900756728904165177527487078077667350512959263803465594111, 48778316120483961415587198479185523835826749642473845435889717611018677968038563827240090688089889339896065735651*X2 + 202678826482051686554967485240375873611017127444692775767942717540980994219310434688309713205309853725035377739266, 41448968894064940344019909320065089603789758666259308674991068396259424208998703895462327945020441899649105710894*X2 + 216229669548325266866202681779047392389311278655704899819569794547799955366773265486059541504823551138048188296915, 3933321808920817665892338621688661599151270488240879901971434149901647580182088988848276352998263499828820719486*X2 + 203453160391122297114764634999687500867096029894782931052056493086745424054313508850135956093450854351511962568248, 123487321384490387195094801639396482206262484603737596281845841408384878196277195829349272799617445074531384638014*X2 + 199891426461397900698689228549412057991574595606781836622700872746783962617889812808189413859146835266670353365164, 188439202506521797668192307957766105517906171778775206324453830870041256388075168650527562921934698697140423464142*X2 + 115853993705912938985758922127173369175321347209545356726288637524744651943071927137158115778405271676616612170666, 142202207982399429498494980946602932891398916434890751210930378360132151108127041093945093575972538591541631204396*X2 + 106675525854808944323662773997719159035717496275254424840883415090817949089664218352587480756720528552217297479523, 256411146327954053251262434650444473133439725697572806395735688747939610541453396276159230618136278790246160635595*X2 + 159262246805999098136860288248138175456624792734939305704793543040582454889431805248352849370505960249829264037333, 135097007131619291616144192105571840182910366835929043414300810591005223344182310684819863256436016908585466099814*X2 + 142632909729670553826438094523500302011158161959746397893981306350515911350319381478896794266740222044724793183031, 251345693404812657374633929641944735274020119374936409701199723189056283828393555325905238148261248120379910778583*X2 + 116623955280658732717402646061913268461869836841204913444259922610012147799771656282704605878638711580234302879520, 220909287290837789818195731110558629271153823543746871132117978761339034747123501189473420274677281822601971748563*X2 + 228308803559737454633222698485074629499383737811342884536963429506633258142551503400414163815852158951494613610809, 226047422399128874433860903177676209375847937545805175562415311468986239012130226120019081492247088609694678876810*X2 + 8414285408102090292522571401032945098403423241877066651551931468973120658567171350501434823318074450118610388181, 30408441237651674477115309504276625429344634933425091999725383701660094027885762738289460271315609173544614563248*X2 + 109149004424675517113489432756837393820953128532207867425106578478986226345054217066591849467433110788215195319750, 154445371651863854130996979206021232172872232688365227537444264835087932826365764405635125797374865965304745730822*X2 + 243169287995837894205750503657473181252400776697661357268613577074201794943537027717771587727860769419520957117060]
  263. phi_y_den = [1, 210880269899843225414111521931364427157014189139153931141845520612300425501022712679200902179085486362182614989038*X2 + 172147863909779437473600759248856356840207842931344727009188760756830505857976640403412821403996887953725715762255, 97451989647642778641795555357790293895920858058713680518946629728091416392679362160653023502048556793761866531581*X2 + 234716866510887739589745422464313597883163631119309437461957606368046054279070563732715561665778636277317684644515, 6765896997590927451499527318422027932088882822980873934837948553969718709492787823596776070132570199077127482065*X2 + 212106075999882114389916784897163150756429321557076536924307653148222968665985018997130331497354557069316538670523, 183808890703436998546164599111050972902808423546263572335175957576564587842514119276068990911067829699066843757937*X2 + 79081485025787885179619178550309706744599846607596447880706626420512740963985633088538634502003788677250834958908, 183219245849642047090141657656072708461001592401873575143115550847958265143529306190408825011434780265059908079650*X2 + 4121090928751590306336774011079865996138664888804166805010515676212588791761189056383637824656513752764121888675, 157598266513011182093451150345114371606842593014102635902061162138398777778450012845089379844999350325670077782200*X2 + 212862020601301354783026588297306531610140885387724836359356800753780855161155144746080869191538655229274242914307, 132695208880203057798268960407754614753345990251279710979596670783892175104478291787481794529190706739877760089560*X2 + 42585898388361518080924198789209195881860509830112816215046001795045034138585747974649960102171072364466234418812, 6046324386958113626500748531301314307229746408846776295678625368971798823548167403538529285882066298168231669149*X2 + 64805743514968884017432304617184871899075979363892814607985017391426869625002757534871594116135107848421987411961, 148745905560783494991892238622790396213255789465409808038709750840775025617296316699696997331989504328034553213894*X2 + 101332532133743769759178027285109552486478973958553103055307446365529747250973790438239230671819476569086244438727, 53390417057360854696711134553867053334956120915983753729596602193155006833056717338565729257476036879055975910097*X2 + 30126025128311053094362231518416999154688680759401769180563223025361877725315179695978985780460875616652938854146, 75265817091612360444217709043194311507703596250641164601263089234422086318666070167810083868284770450890779266774*X2 + 194440756770673250653849096711805826346541581797630354589253365569405779009028682866443842541588052010949210024484, 246226868929550107779875102413192686259972538740042993595504829761267272514998892312681511407413880843390092913913*X2 + 252218794556637183364789705825049189219556217519670190016584589877973440046635828866291293002549365274213665103495, 228823832066259533984346839854456963456061412139464585495219844904598927917971403987214543635705786807302526573779*X2 + 242374981274128257174433646391488180576863913259197526647513270422870835725158808599624055920155693832356361192562, 246735083688655178976599901436968434779493759990448799231310864308891009496294971885106650388027197609829556319894*X2 + 248265339860070148327157063205450906034372346050742532250909040050681913704941472496789561564874787781299103889328, 33695298953151791677564491610276872092952551110021466172491397823758283921068636555353240048692541883780027233962*X2 + 141307886851791570111930048284226290849958071383456038631306928334570275405889250568493573543543795501685612269615, 206045464105062318563700338460670926332476051084269665075012377410704353049241671458557389593362582538704238377616*X2 + 124201488690791095020042847186337439989685011854729481246272047846908500431421470344897520044190299684207452017073, 167478505497067957490757520193067128323382872103395718848436244112857102765738573826312783708349214669979612036158*X2 + 136011650568921952309089811450436645471254909718073766303847394446918967077385999380499048535832357755732371368738, 53213606042373287683153647684084583002441527525177758051678463570615020765660540938870067881706148841340293404257*X2 + 57449149099548285338146473529383255206310079371370663992648410210841833627207062160011080280732475904935527767063, 119396884503349014053839666170414789560955868303656326650021743484252346209353246139311353657707899076368015332219*X2 + 40836628940164991036725499428168139451294386215534361893839871958837737306822281294361671587764896498700322394958, 204809230842263072415312635210643987712012160534293694062738501600937603588267937911969298058204043106501986725326*X2 + 108398849957050915959578499238335172000970311919637037913625633347326921657585237193100994767528244599176367431882, 55976309667093193926953058482403983650044130588205371047077237394269232758375928755579870418413040530924659710422*X2 + 18177910449767953614338723180992575758462819793657888834925741153507922227776503487306285172452430778418239589878, 224037954053161681052577381077631881138732983068288196649494577229506443999757164090758954620762136536790092765707*X2 + 94953611600133917480746113251669332369937157892937924494319507354263981756523698288726321437604686331762128114942, 78363344687446114757879143124020926645520829625790622079288990711202726499291972408305265373741655103522048633806*X2 + 255810123836950778051032251049468471118744836441263107437005316697409810175422976454215094737538073112171964000966, 171430383391121065822039978510482289343958135960126315509375831831735263180943544895493884988847947752888720502133*X2 + 251064692215092635541196206457923985861467397867989080397969990645886126152674833092283559946890888232618697517884, 131736273443849165304852712527070616520885505701320868662058330388440710419459541866884603770735894010610491333882*X2 + 250488593850017034090300371968459931740406675270099747930030660805939980644430804509506597720682995099971419762057, 42967590874964323361920860309631969474991176192252393149421408476343364383848642144439727879920981862569415477634*X2 + 53290030879673160724264978063216325707183784347799183367929912851157629196486013218134779085284663628473135140615, 224732340440722096332247540469311391766792864305974461767563394934556509366444399113606207665094042937608880394380*X2 + 32044478312863504453978511975839237915357713065285858656377527520925624222082496835678894223326750023304346513708, 82194329196840936158921467961561828669469444994699107543787160001285217807552090667641931153824104285439311091477*X2 + 42398151340378868438123040588425908782227436520374323184618125390984068793920538080412999034838310511981244418952, 114397460921328140828185121166450637136573513025702964340164304518654108540682577087979875141067314446917571826582*X2 + 107140053800026140817203074526089346919722280052456645787788712045148531978814339001150298053597504647766497707422, 75310151275642225944994533227518963961512910025529659163648069668626195571780520556481029340507362571133885889206*X2 + 214137118009637944275213937166601531498145257806838837034827533674793291112410824873653425491233537265355337125438, 36167189440196390196320129647971031300455228428629866775570898825049060037811108115927676106354625467897211624573*X2 + 83946178094995839681455048029661822915614318352963730526672352524233381944447759416757234629624830143848209247040, 19068358873460915055376626440913257473060029137260026174266944920186136734103362122730468957229595374427187617425*X2 + 255874157960252694683645508260848371559149621054025374393554376526882940742514793344046680765937904153005134511200, 234106598974619695004693596968258258794247055108931498762994964636371479098512727352039267846913406623802246782945*X2 + 177304823246185962354212404236288831041380791662214394697399928748373114098169675564032904690251242875327747673679]