diff options
| author | Andrew Guschin <guschin.drew@gmail.com> | 2023-12-19 01:03:29 +0400 |
|---|---|---|
| committer | Andrew Guschin <guschin.drew@gmail.com> | 2023-12-19 01:03:29 +0400 |
| commit | 6c2e055e0497b0f5b3a396fc7e058a563ac9735b (patch) | |
| tree | 95cde562b9a9d5bc33509427f2335a4abb202046 | |
| parent | c65cfb6f89be4751451327ff67454c6290c99632 (diff) | |
задание 6
| -rw-r--r-- | t4mk.ipynb | 658 |
1 files changed, 657 insertions, 1 deletions
@@ -596,7 +596,663 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Задание 6" + "# Задание 6\n", + "\n", + "Ввести параметры кривой $a$, $b$, размер поля `field` и индекс точки в полученном отсортированном списке точек `pt_idx`." + ] + }, + { + "cell_type": "code", + "execution_count": 157, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a: 1\n", + "b: 1\n" + ] + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\begin{array}{|c|c|c|c|}\n", + "x & x^2 & x^3 + 1 \\cdot x + 1 & y \\\\\n", + "0 & 0 & 1 & \\\\\n", + "1 & 1 & 3 & \\\\\n", + "2 & 4 & 0 & \\\\\n", + "3 & -2 & -2 & \\\\\n", + "4 & 5 & 3 & \\\\\n", + "5 & 3 & -1 & \\\\\n", + "-5 & 3 & 3 & \\\\\n", + "-4 & 5 & -1 & \\\\\n", + "-3 & -2 & 4 & \\\\\n", + "-2 & 4 & 2 & \\\\\n", + "-1 & 1 & -1 & \\\\\n", + "\\end{array}$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Порядок: 14\n", + "Точки:\n", + "(0, 1)\n", + "(0, -1)\n", + "(1, 5)\n", + "(1, -5)\n", + "(2, 0)\n", + "(3, 3)\n", + "(3, -3)\n", + "(4, 5)\n", + "(4, -5)\n", + "(-3, 2)\n", + "(-3, -2)\n", + "(-5, 5)\n", + "(-5, -5)\n", + "None\n", + "Проверяем точку (0, -1)\n" + ] + }, + { + "data": { + "text/latex": [ + "$\\displaystyle $" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\lambda = \\frac{3 \\cdot x_1^2 + a}{2 \\cdot y_1} = \\frac{3 \\cdot 0^2 + 1}{2 \\cdot 10} = \\frac{3 \\cdot 0 + 1}{20} = \\frac{1}{20}$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\lambda = 1 \\cdot 20^{-1} = 1 \\cdot 5 = 5 \\pmod{11} = 5$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle x_3 = \\lambda^2 - x_1 - x_2 = 5^2 - 0 - 0 = 25 - 0 - 0 = 25 \\pmod{11} = 3 = 3$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle y_3 = \\lambda \\cdot (x_1 - x_3) - y_1 = 5 \\cdot (0 - 3) - 10 = 5 \\cdot -3 - 10 = -15 - 10 = -25 \\pmod{11} = 8 = -3$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle 2P = P + P = (0, -1) + (0, -1) = (3, -3)$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle $" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\lambda = \\frac{y_2 - y_1}{x_2 - x_1} = \\frac{10 - 8}{0 - 3} = \\frac{2}{-3}$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\lambda = 2 \\cdot -3^{-1} = 2 \\cdot 7 = 14 \\pmod{11} = 3$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle x_3 = \\lambda^2 - x_1 - x_2 = 3^2 - 3 - 0 = 9 - 3 - 0 = 6 \\pmod{11} = 6 = -5$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle y_3 = \\lambda \\cdot (x_1 - x_3) - y_1 = 3 \\cdot (3 - 6) - 8 = 3 \\cdot -3 - 8 = -9 - 8 = -17 \\pmod{11} = 5 = 5$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle 3P = 2P + P = (3, -3) + (0, -1) = (-5, 5)$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle $" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\lambda = \\frac{y_2 - y_1}{x_2 - x_1} = \\frac{10 - 5}{0 - 6} = \\frac{5}{-6}$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\lambda = 5 \\cdot -6^{-1} = 5 \\cdot 9 = 45 \\pmod{11} = 1$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle x_3 = \\lambda^2 - x_1 - x_2 = 1^2 - 6 - 0 = 1 - 6 - 0 = -5 \\pmod{11} = 6 = -5$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle y_3 = \\lambda \\cdot (x_1 - x_3) - y_1 = 1 \\cdot (6 - 6) - 5 = 1 \\cdot 0 - 5 = 0 - 5 = -5 \\pmod{11} = 6 = -5$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle 4P = 3P + P = (-5, 5) + (0, -1) = (-5, -5)$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle $" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\lambda = \\frac{y_2 - y_1}{x_2 - x_1} = \\frac{10 - 6}{0 - 6} = \\frac{4}{-6}$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\lambda = 4 \\cdot -6^{-1} = 4 \\cdot 9 = 36 \\pmod{11} = 3$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle x_3 = \\lambda^2 - x_1 - x_2 = 3^2 - 6 - 0 = 9 - 6 - 0 = 3 \\pmod{11} = 3 = 3$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle y_3 = \\lambda \\cdot (x_1 - x_3) - y_1 = 3 \\cdot (6 - 3) - 6 = 3 \\cdot 3 - 6 = 9 - 6 = 3 \\pmod{11} = 3 = 3$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle 5P = 4P + P = (-5, -5) + (0, -1) = (3, 3)$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle $" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\lambda = \\frac{y_2 - y_1}{x_2 - x_1} = \\frac{10 - 3}{0 - 3} = \\frac{7}{-3}$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\lambda = 7 \\cdot -3^{-1} = 7 \\cdot 7 = 49 \\pmod{11} = 5$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle x_3 = \\lambda^2 - x_1 - x_2 = 5^2 - 3 - 0 = 25 - 3 - 0 = 22 \\pmod{11} = 0 = 0$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle y_3 = \\lambda \\cdot (x_1 - x_3) - y_1 = 5 \\cdot (3 - 0) - 3 = 5 \\cdot 3 - 3 = 15 - 3 = 12 \\pmod{11} = 1 = 1$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle 6P = 5P + P = (3, 3) + (0, -1) = (0, 1)$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle $" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\text{Координаты } x \\text{ данных точек одинаковы} \\implies \\text{ сумма равна } \\mathcal{O}$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle 7P = 6P + P = (0, 1) + (0, -1) = \\mathcal{O}$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\displaystyle \\text{Порядок точки } (0, -1) \\text{ равен } 7$" + ], + "text/plain": [ + "<IPython.core.display.Math object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "a, b, field, pt_idx = 1, 1, 11, 1\n", + "\n", + "from math import gcd\n", + "\n", + "def point_neg(point, A, B, p):\n", + " if not is_on_curve(point, A, B, p):\n", + " raise RuntimeError\n", + " if point is None:\n", + " return point\n", + " \n", + " x, y = point\n", + "\n", + " result = x, -y % p\n", + " if not is_on_curve(result, A, B, p):\n", + " raise RuntimeError\n", + " return result\n", + "\n", + "def extended_gcd(a, b):\n", + " if a == 0:\n", + " return b, 0, 1\n", + " else:\n", + " gcd, x, y = extended_gcd(b % a, a)\n", + " return gcd, y - (b // a) * x, x\n", + "\n", + "def inverse_mod(k, p):\n", + " if k < 0:\n", + " return p - inverse_mod(-k, p)\n", + " gcd, x, _ = extended_gcd(k, p)\n", + " if gcd == 1:\n", + " if x < 0:\n", + " x += p\n", + " return x\n", + " else:\n", + " raise RuntimeError\n", + "\n", + "def is_on_curve(point, A, B, p):\n", + " if point is None:\n", + " return True\n", + "\n", + " x, y = point\n", + " return (y ** 2 - x ** 3 - A * x - B) % p == 0\n", + "\n", + "\n", + "def point_addition(point1, point2, A, B, p):\n", + " display(Math(''))\n", + " if not is_on_curve(point1, A, B, p) or not is_on_curve(point2, A, B, p):\n", + " raise RuntimeError\n", + "\n", + " if point1 is None:\n", + " return point2\n", + " elif point2 is None:\n", + " return point1\n", + "\n", + " x1, y1 = point1\n", + " x2, y2 = point2\n", + "\n", + " if x1 - x2 == 0 and y1 != y2:\n", + " display(Math(r'\\text{Координаты } x \\text{ данных точек одинаковы} \\implies \\text{ сумма равна } \\mathcal{O}'))\n", + " return None\n", + "\n", + " if x1 == x2:\n", + " display(Math(fr\"\\lambda = \\frac{{3 \\cdot x_1^2 + a}}{{2 \\cdot y_1}} = \\frac{{3 \\cdot {x1}^2 + {A}}}{{2 \\cdot {y1}}} = \\frac{{3 \\cdot {x1 * x1} + {A}}}{{{2 * y1}}} = \\frac{{{3 * x1 * x1 + A}}}{{{2 * y1}}}\"))\n", + " # print(f\"\\talpha = (3 * x1^2 + a) / (2 * y1) = (3 * {x1}^2 + {A}) / (2 * {y1}) = (3 * {x1 * x1} + {A}) / {2 * y1} = {3 * x1 * x1 + A} / {2 * y1}\")\n", + " num = (3 * x1 ** 2 + A)\n", + " den = 2 * y1\n", + " else:\n", + " display(Math(fr\"\\lambda = \\frac{{y_2 - y_1}}{{x_2 - x_1}} = \\frac{{{y2} - {y1}}}{{{x2} - {x1}}} = \\frac{{{y2 - y1}}}{{{x2 - x1}}}\"))\n", + " # print(f\"\\talpha = (y2 - y1) / (x2 - x1) = ({y2} - {y1}) / ({x2} - {x1}) = {y2 - y1} / {x2 - x1}\")\n", + " num = y2 - y1\n", + " den = x2 - x1\n", + "\n", + " if gcd(den, p) != 1:\n", + " return None\n", + "\n", + " m = num * inverse_mod(den, p)\n", + " display(Math(fr\"\\lambda = {num} \\cdot {den}^{{-1}} = {num} \\cdot {inverse_mod(den, p)} = {m} \\pmod{{{p}}} = {m % p}\"))\n", + " # print(f\"\\talpha = {num} * {inverse_mod(den, p)} = {m} (mod {p}) = {m % p}\")\n", + " m = m % p\n", + "\n", + " x3 = m * m - x1 - x2\n", + " display(Math(fr\"x_3 = \\lambda^2 - x_1 - x_2 = {m}^2 - {x1} - {x2} = {m * m} - {x1} - {x2} = {x3} \\pmod{{{p}}} = {x3 % p} = {mm(x3 % p)}\"))\n", + " # print(f\"\\tx3 = alpha^2 - x1 - x2 = {m}^2 - {x1} - {x2} = {m * m} - {x1} - {x2} = {x3} (mod {p}) = {x3 % p}\")\n", + " x3 = x3 % p\n", + "\n", + " y3 = m * (x1 - x3) - y1\n", + " display(Math(fr\"y_3 = \\lambda \\cdot (x_1 - x_3) - y_1 = {m} \\cdot ({x1} - {x3}) - {y1} = {m} \\cdot {x1 - x3} - {y1} = {m * (x1 - x3)} - {y1} = {y3} \\pmod{{{p}}} = {y3 % p} = {mm(y3 % p)}\"))\n", + " # print(f\"\\ty3 = alpha * (x1 - x3) - y1 = {m} * ({x1} - {x3}) - {y1} = {m} * {x1 - x3} - {y1} = {m * (x1 - x3)} - {y1} = {y3} (mod {p}) = {y3 % p}\")\n", + " y3 = y3 % p\n", + " result = (x3 % p, y3 % p)\n", + " if not is_on_curve(result, A, B, p):\n", + " raise RuntimeError\n", + " return result\n", + "\n", + "\n", + "def mm(x):\n", + " if x <= 5:\n", + " return x\n", + " else:\n", + " return x - field\n", + "\n", + "def mmm(p):\n", + " return (mm(p[0]), mm(p[1]))\n", + "\n", + "N = 1\n", + "\n", + "print(\"a: \", a)\n", + "print(\"b: \", b)\n", + "\n", + "\n", + "points = []\n", + "\n", + "tmp = []\n", + "for x in range(field):\n", + " ys = (x * x) % field\n", + " xs = (x * x * x + a * x + b) % field\n", + " tmp.append((mm(x), mm(ys), mm(xs)))\n", + " # print(f\"x = {mm(x)}; x^2 = {mm(ys)}; x^3 + ax + b = {mm(xs)}\")\n", + "\n", + "ltx = [r\"\\begin{array}{|c|c|c|c|}\", fr\"x & x^2 & x^3 + {a} \\cdot x + {b} & y \\\\\"]\n", + "for (x, x2, x3) in tmp:\n", + " ltx.append(fr\"{x} & {x2} & {x3} & \\\\\")\n", + "ltx.append(r\"\\end{array}\")\n", + "display(Math('\\n'.join(ltx)))\n", + "\n", + "for x in range(field):\n", + " sqrt_y = x * x * x + a * x + b\n", + " for y in range(field):\n", + " if (y * y) % field == sqrt_y % field:\n", + " N += 1\n", + " points.append((x, y))\n", + "\n", + "def sort_key(a):\n", + " m = list(mmm(a))\n", + " if m[0] < 0:\n", + " m[0] = abs(m[0]) + 1e9\n", + " if m[1] < 0:\n", + " m[1] = abs(m[1]) + 1e9\n", + " return tuple(m)\n", + "\n", + "points.sort(key=sort_key)\n", + "points = points + [None]\n", + "\n", + "print(\"Порядок:\", N)\n", + "print(\"Точки:\")\n", + "pts_print = []\n", + "for pt in points:\n", + " if pt is not None:\n", + " pt = mmm(pt)\n", + " print(pt)\n", + "\n", + "\n", + "pt = points[pt_idx]\n", + "print(f\"Проверяем точку {mmm(pt)}\")\n", + "\n", + "kpts = set([pt])\n", + "last = pt\n", + "for k in range(2, N + 1):\n", + " try:\n", + " kpt = point_addition(last, pt, a, b, field)\n", + "\n", + " last1 = mm(last[0]), mm(last[1])\n", + " if kpt is not None:\n", + " kpt1 = mm(kpt[0]), mm(kpt[1])\n", + " else:\n", + " kpt1 = r'\\mathcal{O}'\n", + " pt1 = mm(pt[0]), mm(pt[1])\n", + " \n", + " if k != 2:\n", + " display(Math(f\"{k}P = {k - 1}P + P = {last1} + {pt1} = {kpt1}\"))\n", + " else:\n", + " display(Math(f\"{k}P = P + P = {last1} + {pt1} = {kpt1}\"))\n", + " last = kpt\n", + " if kpt is not None:\n", + " kpts.add(kpt)\n", + " else:\n", + " break\n", + " except RuntimeError:\n", + " break\n", + "\n", + "pt1 = mm(pt[0]), mm(pt[1])\n", + "display(Math(fr\"\\text{{Порядок точки }} {pt1} \\text{{ равен }} {k}\"))\n" ] } ], |