Advertisement
Guest User

Untitled

a guest
Nov 20th, 2019
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 35.90 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Numerics;
  6. using System.Text;
  7. using System.Security.Cryptography;
  8.  
  9. namespace EC2
  10. {
  11. class Program
  12. {
  13. public static BigInteger NR;
  14. public static BigInteger B;
  15. public static BigInteger p;
  16. public static int cnt = 0;
  17. public static List<BigInteger> PNR;
  18. public static Random rand = new Random();
  19. public static List<BigInteger> Q = new List<BigInteger>();
  20. public static BigInteger r;
  21. public static BigInteger l;
  22. public static string m;
  23. public static List<BigInteger> P;
  24. static void Main(string[] args)
  25. {
  26. while (true)
  27. {
  28. Info();
  29. int idx;
  30.  
  31. try
  32. {
  33. idx = int.Parse(Console.ReadLine());
  34. }
  35. catch (FormatException)
  36. {
  37. continue;
  38. }
  39. Console.Clear();
  40. try
  41. {
  42.  
  43.  
  44.  
  45. switch (idx)
  46. {
  47. case 1:
  48. {
  49. GenerateEC();
  50. Console.ReadLine();
  51. Console.Clear();
  52. break;
  53. }
  54.  
  55. case 2:
  56. {
  57. ElGamal();
  58. Console.ReadLine();
  59. Console.Clear();
  60. break;
  61. }
  62. case 0:
  63. {
  64. return;
  65. }
  66. default:
  67. break;
  68. }
  69. }
  70. catch (FileNotFoundException)
  71. {
  72. Console.WriteLine("Не заданы параметры Эллиптической кривой");
  73. Console.ReadLine();
  74. return;
  75. }
  76. }
  77. }
  78.  
  79. public static void ElGamal()
  80. {
  81. try
  82. {
  83. ReadParam();
  84. int counter = 0,
  85. lastStep = 0;
  86. Console.Write("Введите l: ");
  87. l = BigInteger.Parse(Console.ReadLine());
  88. WriteNumber("l.txt", l);
  89. P = QuickSumPoint(Q, l, p);
  90. WritePoint(P, "P.txt");
  91.  
  92. while (true)
  93. {
  94. Console.WriteLine("Введите номер шага, который хотите исполнить: ");
  95. Console.WriteLine("\t1 - Если хотите сгенерировать случайный показатель k'");
  96. Console.WriteLine("\t2 - Если хотите убадиться что R принадлежит E(K)");
  97. Console.WriteLine("\t3 - Если хотите вычислить подпись");
  98. Console.WriteLine("\t4 - Если хотите проверить подпись");
  99. Console.WriteLine("\t5 - Если хотите погасить монету");
  100. Console.WriteLine("\t0 - Если хотите выйти");
  101. int idx;
  102. try
  103. {
  104. idx = int.Parse(Console.ReadLine());
  105.  
  106. m = File.ReadAllText("m.txt");
  107. }
  108. catch (FormatException)
  109. {
  110. continue;
  111. }
  112. catch (FileNotFoundException)
  113. {
  114. Console.WriteLine("Создайте файл m.txt");
  115. Console.ReadLine();
  116. Console.Clear();
  117. return;
  118. }
  119. Console.Clear();
  120.  
  121. try
  122. {
  123. switch (idx)
  124. {
  125. case 1:
  126. {
  127. EStep1();
  128. lastStep = 1;
  129. break;
  130. }
  131. case 2:
  132. {
  133. if (lastStep != 1 || !EStep2())
  134. {
  135. DeleteFiles();
  136. return;
  137. }
  138.  
  139. lastStep = 2;
  140. break;
  141. }
  142. case 3:
  143. {
  144. if (lastStep != 2 || !EStep3())
  145. {
  146. DeleteFiles();
  147. return;
  148. }
  149. lastStep = 3;
  150. break;
  151. }
  152. case 4:
  153. {
  154. if (lastStep != 3)
  155. {
  156. DeleteFiles();
  157. return;
  158. }
  159. counter++;
  160. if (EStep4())
  161. {
  162. Console.WriteLine("Подпись принята");
  163. }
  164. else
  165. {
  166. Console.WriteLine("Подпись не принята");
  167. }
  168. lastStep = 0;
  169. break;
  170. }
  171. case 5:
  172. {
  173. if (EStep5())
  174. Console.WriteLine("Подпись действительна");
  175. else
  176. Console.WriteLine("Подпись не действительна");
  177. DeleteFiles(true);
  178. return;
  179. }
  180. case 0:
  181. {
  182. DeleteFiles();
  183. return;
  184. }
  185. default:
  186. break;
  187. }
  188. Console.WriteLine("Шаг {0} выполнен", idx);
  189. Console.ReadLine();
  190. Console.Clear();
  191. }
  192. catch (FileNotFoundException er)
  193. {
  194. Console.WriteLine(er.Message);
  195. DeleteFiles();
  196. return;
  197. }
  198. }
  199. }
  200. catch (FormatException)
  201. {
  202. Console.Clear();
  203. throw;
  204. }
  205. catch (FileNotFoundException)
  206. {
  207.  
  208. throw;
  209. }
  210. catch (Exception)
  211. {
  212.  
  213. throw;
  214. }
  215. }
  216. public static void EStep1()
  217. {
  218. List<BigInteger> _R;
  219. while (true)
  220. {
  221. BigInteger _k;
  222. do
  223. {
  224. _k = BigInteger.ModPow(new Random().Next(99, 9999), new Random().Next(99, 9999), r);
  225. } while (_k == 0 || _k == r);
  226.  
  227. _R = QuickSumPoint(Q, _k, p);
  228. if (_R[0] != 0)
  229. {
  230. WriteNumber("_k.txt", _k);
  231. break;
  232. }
  233. }
  234. WritePoint(_R, "_R.txt");
  235. }
  236. public static bool EStep2()
  237. {
  238. List<BigInteger> _R = readPoint("_R.txt");
  239. if ((_R[1] * _R[1]) % p != (_R[0] * _R[0] * _R[0] + B) % p) return false;
  240.  
  241. BigInteger alpha;
  242. List<BigInteger> R;
  243. while (true)
  244. {
  245. do
  246. {
  247. alpha = BigInteger.ModPow(new Random().Next(99, 9999), new Random().Next(99, 9999), r);
  248. } while (alpha == 0 || alpha == r);
  249.  
  250. R = QuickSumPoint(_R, alpha, p);
  251.  
  252. if (R[0] != 0)
  253. break;
  254. }
  255. WritePoint(R, "R.txt");
  256.  
  257. var Bb = R[0] * Reverse(_R[0], r) % r;
  258. WriteNumber("B.txt", Bb);
  259.  
  260. var _m = alpha * Reverse(Bb, r) * NumMessage(m) % r;
  261.  
  262. WriteNumber("_m.txt", _m);
  263.  
  264. return true;
  265. }
  266. public static bool EStep3()
  267. {
  268. var l = BigInteger.Parse(File.ReadAllText("l.txt"));
  269. var _m = BigInteger.Parse(File.ReadAllText("_m.txt"));
  270. var _k = BigInteger.Parse(File.ReadAllText("_k.txt"));
  271. var _R = readPoint("_R.txt");
  272. if (_m == 0) return false;
  273.  
  274. var _s = l * _R[0] + _k * _m % r;
  275.  
  276. WriteNumber("_s.txt", _s);
  277.  
  278. return true;
  279. }
  280. public static bool EStep4()
  281. {
  282. var P = readPoint("P.txt");
  283. var _R = readPoint("_R.txt");
  284. var _m = BigInteger.Parse(File.ReadAllText("_m.txt"));
  285. var _s = BigInteger.Parse(File.ReadAllText("_s.txt"));
  286. var Bb = BigInteger.Parse(File.ReadAllText("B.txt"));
  287.  
  288. var mult1 = QuickSumPoint(Q, _s, p);
  289. var mult2 = QuickSumPoint(P, _R[0], p);
  290. var mult3 = QuickSumPoint(_R, _m, p);
  291. var sum1 = SummaTochek(mult2, mult3, p);
  292. if (mult1[0] == sum1[0] && mult1[1] == sum1[1])
  293. {
  294. var s = _s * Bb % r;
  295. WriteNumber("s.txt", s);
  296. foreach (var item in Directory.GetFiles(Environment.CurrentDirectory))
  297. {
  298. if (Path.GetFileNameWithoutExtension(item) == "m" || Path.GetFileNameWithoutExtension(item) == "R" || Path.GetFileNameWithoutExtension(item) == "s")
  299. continue;
  300. if (Path.GetExtension(item) == ".txt")
  301. File.Delete(item);
  302. }
  303. return true;
  304. }
  305. else
  306. return false;
  307. }
  308. public static bool EStep5()
  309. {
  310. var R = readPoint("R.txt");
  311. var s = BigInteger.Parse(File.ReadAllText("s.txt"));
  312. var M = NumMessage(m);
  313. if (M == 0 || R[0] == 0) return false;
  314.  
  315. var mult1 = QuickSumPoint(Q, s, p);
  316. var mult2 = QuickSumPoint(P, R[0], p);
  317. var mult3 = QuickSumPoint(R, M, p);
  318. var sum1 = SummaTochek(mult2, mult3, p);
  319. return (mult1[0] == sum1[0] && mult1[1] == sum1[1]);
  320. }
  321.  
  322.  
  323.  
  324. private static void WritePoint(List<BigInteger> _R, string path)
  325. {
  326. using (var write = new StreamWriter(File.Open(path, FileMode.Create)))
  327. {
  328. write.WriteLine(_R[0]);
  329. write.WriteLine(_R[1]);
  330. }
  331. }
  332. private static List<BigInteger> readPoint(string path)
  333. {
  334. var _R = new List<BigInteger>();
  335. using (var sr = new StreamReader(File.Open(path, FileMode.Open), Encoding.Default))
  336. {
  337. _R.Add(BigInteger.Parse(sr.ReadLine()));
  338. _R.Add(BigInteger.Parse(sr.ReadLine()));
  339. }
  340.  
  341. return _R;
  342. }
  343. private static void WriteNumber(string path, BigInteger num)
  344. {
  345. using (StreamWriter wr = new StreamWriter(File.Create(path), Encoding.Default))
  346. {
  347. wr.Write(num);
  348. }
  349. }
  350. private static BigInteger NumMessage(string m)
  351. {
  352. StringBuilder str = new StringBuilder();
  353. for (int i = 0; i < m.Length; i++)
  354. {
  355. str.Append((int)m[i]);
  356. }
  357. return BigInteger.Parse(str.ToString());
  358. }
  359. public static void DeleteFiles(bool flag = false)
  360. {
  361. foreach (var item in Directory.GetFiles(Environment.CurrentDirectory))
  362. {
  363. if (flag == false && Path.GetFileName(item) == "m.txt") continue;
  364. if (Path.GetExtension(item) == ".txt")
  365. File.Delete(item);
  366. }
  367. }
  368.  
  369. public static void ReadParam()
  370. {
  371. using (var sr = new StreamReader(File.Open("GeneralSettings.txt", FileMode.Open), Encoding.Default))
  372. {
  373. p = BigInteger.Parse(sr.ReadLine());
  374. B = BigInteger.Parse(sr.ReadLine());
  375. r = BigInteger.Parse(sr.ReadLine());
  376. Q.Add(BigInteger.Parse(sr.ReadLine()));
  377. Q.Add(BigInteger.Parse(sr.ReadLine()));
  378. }
  379. }
  380. private static void Info()
  381. {
  382. Console.WriteLine("Введите");
  383. Console.WriteLine("\t1 - Если хотите сгенерировать ЭК ");
  384. Console.WriteLine("\t2 - Если хотите создать электронную монету");
  385. Console.WriteLine("\t0 - Для выхода");
  386. }
  387. public static void GenerateEC()
  388. {
  389. int m = 5;
  390. BigInteger D = 3;
  391. bool flag = true;
  392. Console.Write("l ");
  393. int l = int.Parse(Console.ReadLine());
  394. if (l <= 4)
  395. {
  396. Console.WriteLine("Нет простых чисел, удовлетворяющих условию алгоритма");
  397. return;
  398. }
  399.  
  400. Console.Write("m = ");
  401. cnt = int.Parse(Console.ReadLine());
  402.  
  403. while (true)
  404. {
  405. step1:
  406. while (true)
  407. {
  408. flag = true;
  409. List<BigInteger> razl;
  410. FindPrime(l);
  411. razl = razlP(D, p);
  412.  
  413. // if (razl.Count() == 0)
  414. // goto step1;
  415.  
  416. PNR = pnr(razl[0], razl[1], p);
  417. if (PNR.Count() == 0) goto step1;
  418.  
  419. if (p != PNR[1])
  420. {
  421. for (int i = 1; i <= m; i++)
  422. {
  423. if (BigInteger.ModPow(p, i, PNR[1]) == 0)
  424. {
  425. cnt += 1;
  426. if (cnt > 20)
  427. {
  428. Console.WriteLine("Такого p не существует");
  429. Console.ReadKey();
  430. return;
  431. }
  432. goto step1;
  433. }
  434. }
  435. break;
  436. }
  437. goto step1;
  438. }
  439.  
  440. BigInteger conut = 2, j = 1;
  441. List<BigInteger> tochka = new List<BigInteger>();
  442. int counter = 0;
  443.  
  444. step5:
  445. while (true)
  446. {
  447. if (PNR[0] == PNR[1] * 2)
  448. Proverka(ref flag, ref conut, 2);
  449.  
  450. if (PNR[0] == PNR[1] * 3)
  451. Proverka(ref flag, ref conut, 3);
  452.  
  453. if (PNR[0] == PNR[1] * 1)
  454. Proverka(ref flag, ref conut, 1);
  455.  
  456. if (PNR[0] == PNR[1] * 6)
  457. Proverka(ref flag, ref conut, 6);
  458.  
  459. if (!flag) goto step6;
  460. tochka = new List<BigInteger>();
  461. for (BigInteger i = j; ; i++, j++)
  462. {
  463. BigInteger z = (B + i * i * i) % p;
  464. if (Legandr(z, p) == 1)
  465. {
  466. if (ModSqrt(z, p) == 0) continue;
  467. else
  468. {
  469. tochka.Add(i);
  470. tochka.Add(ModSqrt(z, p));
  471. }
  472. i++; j++;
  473. break;
  474. }
  475. }
  476.  
  477. BigInteger cnt = PNR[0];
  478.  
  479. List<BigInteger> mulp1p2 = QuickSumPoint(tochka, cnt, p);
  480.  
  481. if (mulp1p2.Any())
  482. {
  483. if (counter++ < 100)
  484. goto step5;
  485. else
  486. {
  487. goto step1;
  488. }
  489. }
  490. break;
  491. }
  492.  
  493. step6:
  494. if (!flag)
  495. continue;
  496. NR = PNR[0] / PNR[1];
  497.  
  498. List<BigInteger> Q = QuickSumPoint(tochka, NR, p);
  499.  
  500. if (!Q.Any() || Q[1] == 0)
  501. continue;
  502.  
  503. Console.WriteLine("p = " + p);
  504. Console.WriteLine("r = " + PNR[1]);
  505. Console.WriteLine("B = " + B);
  506. Console.WriteLine("Q = (" + Q[0] + ", " + Q[1] + ")");
  507. WriteToFiles(Q);
  508. break;
  509. }
  510. }
  511. public static string c10to2(BigInteger i)
  512. {
  513. string s = "";
  514. while (i > 0) { s = (i % 2).ToString() + s; i /= 2; }
  515. return s == "" ? "0" : s;
  516. }
  517. private static List<BigInteger> QuickSumPoint(List<BigInteger> P, BigInteger cnt, BigInteger p)
  518. {
  519. BigInteger lengthBase = CountBit(cnt);
  520. string c = c10to2(cnt);
  521. char[] b = c.ToCharArray();
  522. Array.Reverse(b);
  523. c = new string(b);
  524. List<List<BigInteger>> basePoints = new List<List<BigInteger>>();
  525. List<List<BigInteger>> result = new List<List<BigInteger>>();
  526. basePoints.Add(P);
  527. int k = 0;
  528. for (BigInteger i = 1; i <= cnt; i *= 2)
  529. {
  530. if (!basePoints[k].Any())
  531. {
  532. break;
  533. }
  534. else
  535. {
  536. basePoints.Add(SummaTochek(basePoints[k], basePoints[k], p));
  537. }
  538.  
  539. if (c[k] == '1')
  540. {
  541. result.Add(basePoints[k]);
  542. }
  543. k++;
  544. }
  545.  
  546. if (!result.Any())
  547. return new List<BigInteger>();
  548. List<BigInteger> resultPoint = result[0];
  549.  
  550. for (int i = 1; i < result.Count; i++)
  551. {
  552. if (!resultPoint.Any())
  553. resultPoint = result[i];
  554. else
  555. resultPoint = SummaTochek(resultPoint, result[i], p);
  556. }
  557.  
  558. return resultPoint;
  559. }
  560. private static int CountBit(BigInteger P)
  561. {
  562. int count = 0;
  563. while (P > 0)
  564. {
  565. P >>= 1;
  566. count++;
  567. }
  568. return count;
  569. }
  570. private static void WriteToFiles(List<BigInteger> Q)
  571. {
  572. using (StreamWriter wr = new StreamWriter(File.Open("GeneralSettings.txt", FileMode.Create), Encoding.Default))
  573. {
  574. wr.WriteLine(p);
  575. wr.WriteLine(B);
  576. wr.WriteLine(PNR[1]);
  577. wr.WriteLine(Q[0]);
  578. wr.WriteLine(Q[1]);
  579. }
  580. return;
  581. List<BigInteger> mulp1p2_new;
  582. StreamWriter Cout = null, Cout1 = null, Cout2 = null;
  583. try
  584. {
  585. Cout = new StreamWriter(File.Open("x.txt", FileMode.Create));
  586. Cout1 = new StreamWriter(File.Open("y.txt", FileMode.Create));
  587. Cout2 = new StreamWriter(File.Open("ec.txt", FileMode.Create));
  588. }
  589. catch (IOException e)
  590. {
  591. Console.WriteLine(e.Message);
  592. }
  593. BigInteger por = PNR[1];
  594. try
  595. {
  596. Cout.WriteLine(Q[0]);
  597. Cout1.WriteLine(Q[1]);
  598. Cout2.WriteLine(Q[0] + " " + Q[1]);
  599. }
  600. catch (IOException e)
  601. {
  602. Console.WriteLine(e.Message);
  603. }
  604. mulp1p2_new = SummaTochek(Q, Q, p);
  605. try
  606. {
  607. Cout.WriteLine(mulp1p2_new[0]);
  608. Cout1.WriteLine(mulp1p2_new[1]);
  609.  
  610. Cout2.WriteLine(mulp1p2_new[0] + " " + mulp1p2_new[1]);
  611. }
  612. catch (IOException e)
  613. {
  614. Console.WriteLine(e.Message);
  615. }
  616. while (por != 3)
  617. {
  618. if (!mulp1p2_new.Any())
  619. {
  620. mulp1p2_new = Q;
  621. try
  622. {
  623. Cout.WriteLine(mulp1p2_new[0]);
  624. Cout1.WriteLine(mulp1p2_new[1]);
  625.  
  626. Cout2.WriteLine(mulp1p2_new[0] + " " + mulp1p2_new[1]);
  627. }
  628. catch (IOException e)
  629. {
  630. Console.WriteLine(e.Message);
  631. }
  632. }
  633. else
  634. {
  635. mulp1p2_new = SummaTochek(mulp1p2_new, Q, p);
  636. try
  637. {
  638. Cout.WriteLine(mulp1p2_new[0]);
  639. Cout1.WriteLine(mulp1p2_new[1]);
  640. Cout2.WriteLine(mulp1p2_new[0] + " " + mulp1p2_new[1]);
  641. }
  642. catch (IOException e)
  643. {
  644. Console.WriteLine(e.Message);
  645. }
  646. }
  647. por--;
  648. }
  649. Cout.Close();
  650. Cout1.Close();
  651. Cout2.Close();
  652. }
  653.  
  654. public static BigInteger powmod(BigInteger x, BigInteger a, BigInteger m)
  655. {
  656. BigInteger r = 1;
  657. while (a > 0)
  658. {
  659. if (a % 2 != 0)
  660. r = mulmod(r, x, m);
  661. a = a >> 1;
  662. x = mulmod(x, x, m);
  663. }
  664. return r;
  665. }
  666.  
  667. static BigInteger randomBinBigInteger(int l)
  668. {
  669. RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
  670. byte[] Nresult = new byte[BigInteger.Pow(2, l).ToByteArray().LongLength];
  671. BigInteger result;
  672. do
  673. {
  674. rng.GetBytes(Nresult);
  675. result = new BigInteger(Nresult);
  676. } while (result <= BigInteger.Pow(2, (l - 1)) || result >= BigInteger.Pow(2, l));
  677.  
  678. return result;
  679. }
  680.  
  681. static BigInteger GenSimple(int l)
  682. {
  683. BigInteger result;
  684. result = randomBinBigInteger(l);
  685. while (!Isprime(result))
  686. result = randomBinBigInteger(l);
  687. return result;
  688. }
  689.  
  690. static bool Isprime(BigInteger p)
  691. {
  692. if (p == 2 || p == 3)
  693. return true;
  694. if (p < 2 || p % 2 == 0)
  695. return false;
  696. BigInteger t = p - 1;
  697. int s = 0;
  698. while (t % 2 == 0)
  699. {
  700. t /= 2;
  701. s += 1;
  702. }
  703.  
  704. for (int i = 0; i < 20; i++)
  705. {
  706. RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
  707. byte[] tmpa = new byte[p.ToByteArray().LongLength];
  708. rng.GetBytes(tmpa);
  709. BigInteger a;
  710. a = new BigInteger(tmpa);
  711. while (a < 2 || a >= p - 2)
  712. {
  713. rng.GetBytes(tmpa);
  714. a = new BigInteger(tmpa);
  715. }
  716. BigInteger x = BigInteger.ModPow(a, t, p);
  717. if (x == 1 || x == p - 1)
  718. continue;
  719.  
  720. for (int r = 1; r < s; r++)
  721. {
  722. x = BigInteger.ModPow(x, 2, p);
  723. if (x == 1) return false;
  724. if (x == p - 1)
  725. break;
  726. }
  727. if (x != p - 1)
  728. return false;
  729. }
  730. return true;
  731. }
  732.  
  733. private static Boolean isSqrt(BigInteger n, BigInteger sqr)
  734. {
  735. BigInteger lowerBound = sqr * sqr, upperBound = (sqr + 1) * (sqr + 1);
  736. return (n >= lowerBound && n < upperBound);
  737. }
  738.  
  739. public static BigInteger SqrtN(BigInteger N)
  740. {
  741. if (N == 0) return 0;
  742. if (N > 0)
  743. {
  744. int bitLength = Convert.ToInt32(Math.Ceiling(BigInteger.Log(N, 2)));
  745. BigInteger sqr = BigInteger.One << (bitLength / 2);
  746.  
  747. while (!isSqrt(N, sqr))
  748. {
  749. sqr += N / sqr;
  750. sqr /= 2;
  751. }
  752. return sqr;
  753. }
  754. throw new ArithmeticException("NaN");
  755. }
  756.  
  757. public static BigInteger gcd(BigInteger a, BigInteger b)
  758. {
  759. if (b == 0)
  760. return a;
  761. return gcd(b, a % b);
  762. }
  763.  
  764. static Tuple<BigInteger, BigInteger> RashEvkl(BigInteger a, BigInteger b)
  765. {
  766. BigInteger r0 = a, r1 = b, x0 = 1, x1 = 0, y0 = 0, y1 = 1;
  767. BigInteger x, y, d;
  768. while (true)
  769. {
  770. BigInteger q = r0 / r1, r = r0 % r1;
  771. if (r == 0) break;
  772. else
  773. {
  774. r0 = r1; r1 = r;
  775. x = x0 - q * x1;
  776. x0 = x1; x1 = x;
  777. y = y0 - q * y1;
  778. y0 = y1; y1 = y;
  779. }
  780. }
  781. d = r1;
  782. x = x1;
  783. y = y1;
  784. return new Tuple<BigInteger, BigInteger>(x, y);
  785. }
  786.  
  787. static BigInteger Pow(BigInteger a, BigInteger b)
  788. {
  789. BigInteger result = 1;
  790. for (BigInteger i = 0; i < b; i++)
  791. result *= a;
  792. return result;
  793. }
  794.  
  795. static BigInteger Jacobi(BigInteger a, BigInteger n)
  796. {
  797. if (gcd(a, n) != 1)
  798. return 0;
  799. BigInteger r = 1;
  800. if (a < 0)
  801. {
  802. a = -a;
  803. if (n % 4 == 3)
  804. r = -r;
  805. }
  806. while (a != 0)
  807. {
  808. BigInteger k = 0;
  809. while (a % 2 == 0)
  810. {
  811. k++;
  812. a = a / 2;
  813. }
  814. if (k % 2 != 0)
  815. {
  816. if (n % 8 == 3 || n % 8 == 5)
  817. r = -r;
  818. }
  819. if (n % 4 == 3 && a % 4 == 3)
  820. r = -r;
  821. BigInteger temp = a;
  822. a = n % a;
  823. n = temp;
  824. }
  825. return r;
  826. }
  827.  
  828. static BigInteger Reverse(BigInteger a, BigInteger m)
  829. {
  830. BigInteger d = gcd(a, m);
  831. if (d != 1)
  832. return -1;
  833. else
  834. {
  835. Tuple<BigInteger, BigInteger> pair = RashEvkl(a, m);
  836. BigInteger x0 = pair.Item1 % m;
  837. while (x0 < 0) x0 += m;
  838. BigInteger inv = x0 % m;
  839. return inv;
  840. }
  841. }
  842.  
  843. static BigInteger ModSqrt(BigInteger a, BigInteger p)
  844. {
  845. a += p;
  846. BigInteger jacobi = Jacobi(a, p);
  847. if (jacobi == -1)
  848. return 0;
  849.  
  850. int N = 0;
  851. if (jacobi == 1)
  852. {
  853. for (int i = 2; i < p; i++)
  854. {
  855. if (Jacobi(i, p) == -1)
  856. {
  857. N = i;
  858. break;
  859. }
  860. }
  861. }
  862. BigInteger h = p - 1;
  863. int k = 0;
  864. while (h % 2 == 0)
  865. {
  866. k++;
  867. h = h / 2;
  868. }
  869. BigInteger a1 = BigInteger.ModPow(a, (h + 1) / 2, p);
  870. BigInteger a2 = Reverse(a, p);
  871. BigInteger N1 = BigInteger.ModPow(N, h, p);
  872. BigInteger N2 = 1;
  873. BigInteger[] j = new BigInteger[k - 1];
  874. for (int i = 0; i <= k - 2; i++)
  875. {
  876. BigInteger b = (a1 * N2) % p;
  877. BigInteger c = (a2 * b * b) % p;
  878. BigInteger pow = Pow(2, k - 2 - i);
  879. BigInteger d = BigInteger.ModPow(c, pow, p);
  880. if (d == 1)
  881. j[i] = 0;
  882.  
  883. if (d == p - 1 || d - p == -1)
  884. j[i] = 1;
  885. N2 = (N2 * (BigInteger.ModPow(N1, BigInteger.Pow(2, i) * j[i], p))) % p;
  886. }
  887. BigInteger answer = (a1 * N2) % p;
  888. BigInteger answer1 = (-answer + p) % p;
  889. return answer;
  890. }
  891.  
  892. public static List<BigInteger> SummaTochek(List<BigInteger> P1, List<BigInteger> P2, BigInteger p)
  893. {
  894. List<BigInteger> res = new List<BigInteger>();
  895. BigInteger lambda, x1 = P1[0], y1 = P1[1], x2 = P2[0], y2 = P2[1];
  896. if (x1 == x2 && y1 == y2)
  897. {
  898. BigInteger chis = (3 * x1 * x1) % p, znam = (2 * y1) % p;
  899. if (znam == 0)
  900. return res;
  901. lambda = chis * Reverse(znam, p) % p;
  902. }
  903. else
  904. {
  905. BigInteger chis = (y2 - y1) % p, znam = (x2 - x1) % p;
  906. if (!(znam >= 0))
  907. znam += p;
  908. if (znam == 0)
  909. return res;
  910.  
  911. lambda = chis * Reverse(znam, p) % p;
  912. }
  913. BigInteger xr = (lambda * lambda - x1 - x2) % p, yr = (-y1 + lambda * (x1 - xr)) % p;
  914. if (!(xr >= 0))
  915. xr += p;
  916. if (!(yr >= 0))
  917. yr += p;
  918. res.Add(xr);
  919. res.Add(yr);
  920. return res;
  921. }
  922.  
  923. public static bool isKvadrVich(BigInteger B, BigInteger p)
  924. {
  925. if (Legandr(B, p) == 1)
  926. return true;
  927. else return false;
  928. }
  929. public static bool isKubVich(BigInteger B, BigInteger p)
  930. {
  931. if (BigInteger.ModPow(B, (p - 1) / gcd(p - 1, 3), p) == 1)
  932. return true;
  933. else return false;
  934. }
  935.  
  936. private static List<BigInteger> pnr(BigInteger c, BigInteger d, BigInteger p)
  937. {
  938. List<BigInteger> T = new List<BigInteger>();
  939. T.Add(c + 3 * d);
  940. T.Add(c - 3 * d);
  941. T.Add(2 * c);
  942. T.Add(c * (-2));
  943. T.Add(3 * d - c);
  944. T.Add(-c - 3 * d);
  945. for (int i = 0; i < T.Count; i++)
  946. {
  947. T[i] += (1 + p);
  948. if ((T[i] % 2).Equals(0) && Isprime((T[i] / 2)))
  949. return new List<BigInteger>() { T[i], T[i] / 2 };
  950. else if ((T[i] % 3).Equals(0) && Isprime((T[i] / 3)))
  951. return new List<BigInteger>() { T[i], T[i] / 3 };
  952. else if ((T[i] % 6).Equals(0) && Isprime((T[i] / 6)))
  953. return new List<BigInteger>() { T[i], T[i] / 6 };
  954. else if ((T[i] % 1).Equals(0) && Isprime((T[i] / 1)))
  955. return new List<BigInteger>() { T[i], T[i] / 1 };
  956. }
  957. return new List<BigInteger>();
  958. }
  959.  
  960. private static void FindPrime(int l)
  961. {
  962. p = GenSimple(l);
  963. while ((p % 6) != 1)
  964. p = GenSimple(l);
  965. }
  966.  
  967. public static int Legandr(BigInteger a, BigInteger p)
  968. {
  969. if (a == 0) return 0;
  970. if (a == 1) return 1;
  971. int result;
  972. if (a < 0)
  973. {
  974. result = Legandr(-a, p);
  975. if ((((p - 1) / 2) % 2) != 0)
  976. result = -result;
  977. }
  978. if (a % 2 == 0)
  979. {
  980. result = Legandr(a / 2, p);
  981. if (((p * p - 1) & 8) != 0)
  982. result = -result;
  983. }
  984. else
  985. {
  986. result = Legandr(p % a, a);
  987. if (((a - 1) * (p - 1) & 4) != 0)
  988. result = -result;
  989. }
  990. return result;
  991. }
  992.  
  993. private static void Proverka(ref bool t, ref BigInteger conut, int num)
  994. {
  995. if (PNR[0] == PNR[1] * num)
  996. {
  997. for (BigInteger i = conut; ; i++)
  998. {
  999. if (i > 1000000)
  1000. {
  1001. t = false;
  1002. break;
  1003. }
  1004. bool f = isKvadrVich((i + 1) % p, PNR[0]), h = isKubVich((i + 1) % p, PNR[0]);
  1005. if (num == 6 && f && h || num == 1 && !f && !h || num == 2 && !f && h || num == 3 && f && !h)
  1006. {
  1007. B = i;
  1008. conut = B + 1;
  1009. break;
  1010. }
  1011. }
  1012. }
  1013. }
  1014.  
  1015. public static List<BigInteger> razlP(BigInteger D, BigInteger p)
  1016. {
  1017. if (Legandr(-D, p) == -1) return new List<BigInteger>();
  1018. BigInteger R = ModSqrt(-D, p);
  1019. int i = 0;
  1020. List<BigInteger> U = new List<BigInteger>(), M = new List<BigInteger>();
  1021. U.Add(R);
  1022. M.Add(p);
  1023. do
  1024. {
  1025. M.Add((U[i] * U[i] + D) / M[i]);
  1026. U.Add(BigInteger.Min(U[i] % M[i + 1], M[i + 1] - U[i] % M[i + 1]));
  1027. i++;
  1028. } while (M[i] != 1);
  1029. i--;
  1030. List<BigInteger> a = new List<BigInteger>(), b = new List<BigInteger>();
  1031. for (int j = 0; j <= i; j++)
  1032. {
  1033. a.Add(0);
  1034. b.Add(0);
  1035. }
  1036. a[i] = U[i];
  1037. b[i] = 1;
  1038. while (i != 0)
  1039. {
  1040. BigInteger znam = a[i] * a[i] + D * b[i] * b[i];
  1041. if ((U[i - 1] * a[i] + D * b[i]) % znam == 0)
  1042. a[i - 1] = (U[i - 1] * a[i] + D * b[i]) / znam;
  1043. else
  1044. a[i - 1] = (-U[i - 1] * a[i] + D * b[i]) / znam;
  1045.  
  1046. if ((-a[i] + U[i - 1] * b[i]) % znam == 0)
  1047. b[i - 1] = (-a[i] + U[i - 1] * b[i]) / znam;
  1048. else
  1049. b[i - 1] = (-a[i] - U[i - 1] * b[i]) / znam;
  1050. i--;
  1051. }
  1052. List<BigInteger> res = new List<BigInteger>();
  1053. res.Add(a[0]);
  1054. res.Add(b[0]);
  1055. return res;
  1056. }
  1057. public static BigInteger mulmod(BigInteger x, BigInteger y, BigInteger m)
  1058. { return (x * y) % m; }
  1059. }
  1060. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement