From 20460f30aa6b8831b314af5a21ccdcb7ec280f24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=BB=D0=B0=D1=82=D0=B0=20=D0=9F=D0=B5=D1=82=D1=80?=
 =?UTF-8?q?=D0=B0=D0=BA=D0=BE=D0=B2=D0=B0?= <stud126276@vyatsu.ru>
Date: Mon, 24 Jun 2024 21:08:04 +0000
Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=B8?=
 =?UTF-8?q?=D1=82=D1=8C=20=D1=84=D0=B0=D0=B9=D0=BB=D1=8B=20=D0=B2=20=C2=AB?=
 =?UTF-8?q?/=C2=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 tropicZ.ipynb | 632 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 632 insertions(+)
 create mode 100644 tropicZ.ipynb

diff --git a/tropicZ.ipynb b/tropicZ.ipynb
new file mode 100644
index 0000000..9618e4c
--- /dev/null
+++ b/tropicZ.ipynb
@@ -0,0 +1,632 @@
+{
+  "cells": [
+    {
+      "cell_type": "code",
+      "source": [
+        "class TropicZ(object):\n",
+        "    def __init__(self, infty = 1000, add_op = 'max'):\n",
+        "        self.__infty = infty\n",
+        "        self._posinf = infty\n",
+        "        self._neginf = -infty\n",
+        "\n",
+        "        self.add_op = max\n",
+        "        if add_op == 'min':\n",
+        "            self.add_op = min\n",
+        "\n",
+        "    @property\n",
+        "    def neginf(self):\n",
+        "        return TropicZ.TropicElement(self, self._neginf)\n",
+        "\n",
+        "    @property\n",
+        "    def posinf(self):\n",
+        "        return TropicZ.TropicElement(self, self._posinf)\n",
+        "\n",
+        "    def elem(self, val = 0):\n",
+        "        '''\n",
+        "            Формирует тропический элемента из целого числа val\n",
+        "        '''\n",
+        "        return TropicZ.TropicElement(self, val)\n",
+        "\n",
+        "    class TropicElement(object):\n",
+        "        def __init__(self, outer_instance, val = 0):\n",
+        "            self.__outer_instance = outer_instance\n",
+        "            self._val = self.bound(val)\n",
+        "\n",
+        "        def bound(self, val = 0):\n",
+        "            neginf = self.__outer_instance._neginf\n",
+        "            posinf = self.__outer_instance._posinf\n",
+        "            return min(max(int(val), neginf), posinf)\n",
+        "\n",
+        "        def __repr__(self):\n",
+        "            return str(self)\n",
+        "        def __str__(self):\n",
+        "            return str(self._val)\n",
+        "        def __iter__(self):\n",
+        "            return self.entries.__iter__()\n",
+        "\n",
+        "        def add(self, val):\n",
+        "            '''\n",
+        "                Тропическое сложение текущего элемента с значением val\n",
+        "            '''\n",
+        "            if isinstance(val, TropicZ.TropicElement):\n",
+        "                result = val._val\n",
+        "            else:\n",
+        "                result = int(val)\n",
+        "\n",
+        "            op = self.__outer_instance.add_op\n",
+        "            result = op(self._val, result)\n",
+        "            return TropicZ.TropicElement(self.__outer_instance, result)\n",
+        "\n",
+        "        def __add__(self, val):\n",
+        "            return self.add(val)\n",
+        "\n",
+        "        def __iadd__(self, val):\n",
+        "            self._val = self.add(val)._val\n",
+        "            return self\n",
+        "\n",
+        "        def  __neg__(self):\n",
+        "            result = self.bound(-self._val)\n",
+        "            return TropicZ.TropicElement(self.__outer_instance, result)\n",
+        "\n",
+        "        def mult(self, val):\n",
+        "            '''\n",
+        "                Тропическое умножение текущего элемента на val\n",
+        "            '''\n",
+        "            if isinstance(val, TropicZ.TropicElement):\n",
+        "                result = val._val\n",
+        "            else:\n",
+        "               result = int(val)\n",
+        "            result = self._val + result\n",
+        "            return TropicZ.TropicElement(self.__outer_instance, result)\n",
+        "\n",
+        "        def __mul__(self, val):\n",
+        "            return self.mult(val)\n",
+        "\n",
+        "        def __imul__(self, val):\n",
+        "            self._val = self.mult(val)._val\n",
+        "            return self\n",
+        "\n",
+        "        def div(self, val):\n",
+        "            '''\n",
+        "                Тропическое деление текущего элемента на val\n",
+        "            '''\n",
+        "            if isinstance(val, TropicZ.TropicElement):\n",
+        "                result = val._val\n",
+        "            else:\n",
+        "               result = int(val)\n",
+        "            result = self._val - result\n",
+        "            return TropicZ.TropicElement(self.__outer_instance, result)\n",
+        "\n",
+        "        def __truediv__(self, val):\n",
+        "            return self.div(val)\n",
+        "\n",
+        "        def __floordiv__(self, val):\n",
+        "            return self.div(val)"
+      ],
+      "metadata": {
+        "id": "SRpscGXghDbV"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "id": "xRDb1Z0NhCap"
+      },
+      "outputs": [],
+      "source": [
+        "TZ = TropicZ(1000, 'max')\n",
+        "TZmin = TropicZ(1000, 'min')\n",
+        "TZmax = TropicZ(1000, 'max')"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "a = TZ.elem(5)\n",
+        "b = TZ.elem(6)\n",
+        "stroka = TropicZ.TropicElement.__repr__(a)\n",
+        "print(stroka)\n",
+        "print(int(stroka)+5)\n",
+        "print(-a)\n",
+        "print(a * b)\n",
+        "print(a + b)\n",
+        "L = [TZ.elem(i) for i in range(7)]\n",
+        "print(L)\n",
+        "print(sum(L, TZ.neginf))\n",
+        "print(a * TZ.neginf)"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "4lgRHM3BPbzR",
+        "outputId": "a1d40437-5c55-47c9-b167-d894d1be9967"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "5\n",
+            "10\n",
+            "-5\n",
+            "11\n",
+            "6\n",
+            "[0, 1, 2, 3, 4, 5, 6]\n",
+            "6\n",
+            "-995\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "import math\n",
+        "\n",
+        "class TropicalMatrix:\n",
+        "    def __init__(self, entries):\n",
+        "        self.entries = entries\n",
+        "\n",
+        "    def __str__(self):\n",
+        "        return str(self.entries)\n",
+        "\n",
+        "    def get_entry(self, i, j):\n",
+        "        return self.entries[i][j]\n",
+        "\n",
+        "    def dual(self, dual):\n",
+        "        n = 2\n",
+        "        new_matrix = [[0, 0], [0, 0]]\n",
+        "        for i in range(n):\n",
+        "            for j in range(n):\n",
+        "                new_matrix[i][j] = dual.elem(self[i][j])\n",
+        "        return TropicalMatrix(new_matrix)\n",
+        "\n",
+        "    def add_tropical_matrix(self, matrix, dual):\n",
+        "        n = 2\n",
+        "        new_matrix = [[0, 0], [0, 0]]\n",
+        "        self = TropicalMatrix.dual(self, dual)\n",
+        "        matrix = TropicalMatrix.dual(matrix, dual)\n",
+        "        for i in range(n):\n",
+        "            for j in range(n):\n",
+        "                new_matrix[i][j] = self.get_entry(i, j) + matrix.get_entry(i, j)\n",
+        "        return TropicalMatrix(new_matrix)\n",
+        "\n",
+        "    def mult_scalar(self, scalar, dual):\n",
+        "        n = 2\n",
+        "        new_matrix = [[0, 0], [0, 0]]\n",
+        "        self = TropicalMatrix.dual(self, dual)\n",
+        "        for i in range(n):\n",
+        "            for j in range(n):\n",
+        "                new_matrix[i][j] = self.get_entry(i, j) * scalar\n",
+        "        return TropicalMatrix(new_matrix)\n",
+        "\n",
+        "    def mult_tropical_matrix(self, matrix, dual):\n",
+        "        n = 2\n",
+        "        new_matrix = [[0, 0], [0, 0]]\n",
+        "        self = TropicalMatrix.dual(self, dual)\n",
+        "        matrix = TropicalMatrix.dual(matrix, dual)\n",
+        "        for i in range(n):\n",
+        "            for j in range(n):\n",
+        "                sum_list = []\n",
+        "                for k in range(n):\n",
+        "                    sum_list.append(self.get_entry(i, k) * matrix.get_entry(k, j))\n",
+        "                new_matrix[i][j] = sum_list[0] + sum_list[1]\n",
+        "        return TropicalMatrix(new_matrix)\n",
+        "\n",
+        "    def get_dimension(self):\n",
+        "        return len(self.entries)\n",
+        "\n",
+        "    def __iter__(self): # метод для превращения тропической матрицы в список\n",
+        "        return self.entries.__iter__()\n",
+        "\n",
+        "if __name__ == \"__main__\":\n",
+        "    M = [[-1000, 10], [5, 3]]\n",
+        "    N = [[3, 6], [15, 1000]]\n",
+        "    A = [[5, -1000], [-1000, 5]]\n",
+        "    B = [[2, -1000], [-1000, 2]]\n",
+        "\n",
+        "    p = TropicalMatrix.add_tropical_matrix(M, A, TZmax)\n",
+        "    t = TropicalMatrix.mult_tropical_matrix(N, N, TZmin)\n",
+        "    q = TropicalMatrix.add_tropical_matrix(M, B, TZmax)\n",
+        "    r = TropicalMatrix.mult_scalar(N, 3, TZmin)\n",
+        "\n",
+        "    print('p(x) =', p)\n",
+        "    print('t(x) =', t)\n",
+        "    print('q(x) =', q)\n",
+        "    print('r(x) =', r)"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "jsQa8vr6NTcr",
+        "outputId": "88a5c0bf-19c6-47c1-b4bc-1ab8411f287c"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "p(x) = [[5, 10], [5, 5]]\n",
+            "t(x) = [[6, 9], [18, 21]]\n",
+            "q(x) = [[2, 10], [5, 3]]\n",
+            "r(x) = [[6, 9], [18, 1000]]\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "import math\n",
+        "import random\n",
+        "import numpy as np"
+      ],
+      "metadata": {
+        "id": "2_UE8hylV8BD"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "class TropicalMatrix_without_dual:\n",
+        "    def __init__(self, entries):\n",
+        "        self.entries = entries\n",
+        "\n",
+        "    def __str__(self):\n",
+        "        return str(self.entries)\n",
+        "\n",
+        "    def add_tropical_matrix_without_dual(self, matrix):\n",
+        "        n = 2\n",
+        "        new_matrix = [[0, 0], [0, 0]]\n",
+        "        for i in range(n):\n",
+        "            for j in range(n):\n",
+        "                new_matrix[i][j] = self.get_entry(i, j) + matrix.get_entry(i, j)\n",
+        "        return TropicalMatrix_without_dual(new_matrix)\n",
+        "\n",
+        "    def mult_tropical_matrix_without_dual(self, matrix):\n",
+        "        n = 2\n",
+        "        new_matrix = [[0, 0], [0, 0]]\n",
+        "        for i in range(n):\n",
+        "            for j in range(n):\n",
+        "                sum_list = []\n",
+        "                for k in range(n):\n",
+        "                    sum_list.append(self.get_entry(i, k) * matrix.get_entry(k, j))\n",
+        "                new_matrix[i][j] = sum_list[0] + sum_list[1]\n",
+        "        return TropicalMatrix(new_matrix)\n",
+        "\n",
+        "    def get_entry(self, i, j):\n",
+        "        return self.entries[i][j]\n",
+        "\n",
+        "    def __iter__(self): # метод для превращения тропической матрицы в список\n",
+        "        return self.entries.__iter__()\n",
+        "\n",
+        "if __name__ == \"__main__\":\n",
+        "    M = TropicalMatrix.dual([[-1000, 10], [5, 3]], TZmax)\n",
+        "    N = TropicalMatrix.dual([[3, 6], [15, 1000]], TZmin)\n",
+        "    l = TropicalMatrix_without_dual.add_tropical_matrix_without_dual(M, N)\n",
+        "    m = TropicalMatrix_without_dual.mult_tropical_matrix_without_dual(M, N)\n",
+        "    print(m)"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "DufYsl2a9lrz",
+        "outputId": "2de93bd5-4f48-4fdd-d530-f7c5e07f19f2"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "[[25, 1000], [18, 1000]]\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "def convert(matrix):\n",
+        "    s = list(matrix)\n",
+        "    for i in range(2):\n",
+        "      for j in range(2):\n",
+        "        s[i][j] = int(TropicZ.TropicElement.__repr__(s[i][j]))\n",
+        "    return s\n",
+        "\n",
+        "def generate_random_matrix(n, min_elem, max_elem):\n",
+        "    new_matrix = [[0, 0], [0, 0]]\n",
+        "    for i in range(n):\n",
+        "        for j in range(n):\n",
+        "            new_matrix[i][j] = random.randint(min_elem, max_elem)\n",
+        "    return new_matrix\n",
+        "\n",
+        "def generate_random_tropical_poly(max_degree, min_coefficient, max_coefficient):\n",
+        "    \"\"\"\n",
+        "    Генерирует случайный (не константу) тропический многочлен с точностью до заданной степени.\n",
+        "    \"\"\"\n",
+        "    coefficients = []\n",
+        "    for d in range(0, random.randint(1, max_degree) + 1):\n",
+        "        coefficients.append(random.randint(min_coefficient, max_coefficient))\n",
+        "    return coefficients\n",
+        "\n",
+        "def MatrixMul(a, n):\n",
+        "    if (n <= 1):\n",
+        "        return a\n",
+        "    else:\n",
+        "        return TropicalMatrix_without_dual.mult_tropical_matrix_without_dual(MatrixMul(a, n-1), a)\n",
+        "\n",
+        "def evaluate_polynomial(tropical_matrix, coefficient_list, dual):\n",
+        "    \"\"\"\n",
+        "    Вычисляет многочлен (списком), заданный тропической матрицей.\n",
+        "    \"\"\"\n",
+        "    identity_matrix_Zmax = [[0, -1000], [-1000, 0]]\n",
+        "    identity_matrix_Zmin = [[0, 1000], [1000, 0]]\n",
+        "    null_matrix_Zmax = [[-1000, -1000], [-1000, -1000]]\n",
+        "    null_matrix_Zmin = [[1000, 1000], [1000, 1000]]\n",
+        "    sum_list = []\n",
+        "\n",
+        "    # свободный член\n",
+        "    if coefficient_list[0] != 0:\n",
+        "        if dual == TZmin:\n",
+        "            sum_list.append(TropicalMatrix.mult_scalar(identity_matrix_Zmin, coefficient_list[0], dual))\n",
+        "        else:\n",
+        "            sum_list.append(TropicalMatrix.mult_scalar(identity_matrix_Zmax, coefficient_list[0], dual))\n",
+        "    if coefficient_list[0] == 0:\n",
+        "        if dual == TZmin:\n",
+        "            sum_list.append(TropicalMatrix.dual(null_matrix_Zmin, dual))\n",
+        "        else:\n",
+        "            sum_list.append(TropicalMatrix.dual(null_matrix_Zmax, dual))\n",
+        "\n",
+        "    # для многочлена первой степени\n",
+        "    if (coefficient_list[1] != 0) and (coefficient_list[1] != 1):\n",
+        "        sum_list.append(TropicalMatrix.mult_scalar(tropical_matrix, coefficient_list[1], dual))\n",
+        "    if coefficient_list[1] == 1:\n",
+        "        sum_list.append(TropicalMatrix.dual(tropical_matrix, dual))\n",
+        "    if coefficient_list[1] == 0:\n",
+        "        if dual == TZmin:\n",
+        "            sum_list.append(TropicalMatrix.dual(null_matrix_Zmin, dual))\n",
+        "        else:\n",
+        "            sum_list.append(TropicalMatrix.dual(null_matrix_Zmax, dual))\n",
+        "\n",
+        "    # для многочлена второй степени и выше\n",
+        "\n",
+        "    for i in range(2, len(coefficient_list)):\n",
+        "        sum_list.append(TropicalMatrix.dual(tropical_matrix, dual))\n",
+        "        sum_list[i] = MatrixMul(sum_list[i], i)\n",
+        "        if (coefficient_list[i] != 1) and (coefficient_list[i] != 0):\n",
+        "            sum_list[i] = TropicalMatrix.mult_scalar(convert(sum_list[i]), coefficient_list[i], dual)\n",
+        "        if coefficient_list[i] == 0:\n",
+        "            if dual == TZmin:\n",
+        "                sum_list.append(TropicalMatrix.dual(null_matrix_Zmin, dual))\n",
+        "            else:\n",
+        "                sum_list.append(TropicalMatrix.dual(null_matrix_Zmax, dual))\n",
+        "\n",
+        "    new_matrix = sum_list[0] # складываем все матрицы в sum_list\n",
+        "    for matrix in sum_list:\n",
+        "        new_matrix = TropicalMatrix_without_dual.add_tropical_matrix_without_dual(new_matrix, matrix)\n",
+        "    return TropicalMatrix(new_matrix)\n",
+        "\n",
+        "def get_polynomial_representation(coefficient_list):\n",
+        "    term_list = [str(coefficient_list[0])]\n",
+        "    for i in range(1, len(coefficient_list)):\n",
+        "        term_list.append(str(coefficient_list[i]) + \"x^\" + str(i))\n",
+        "    return \" + \".join(term_list)\n",
+        "\n",
+        "def generate_key(public_term, public_matrix_a, public_matrix_b):\n",
+        "    left_term = TropicalMatrix.mult_tropical_matrix(public_matrix_a, public_term, TZmax)\n",
+        "    right_term = TropicalMatrix.mult_tropical_matrix(convert(left_term), public_matrix_b, TZmin)\n",
+        "    return right_term\n",
+        "\n",
+        "if __name__ == \"__main__\":\n",
+        "    p_x = [5, 1]\n",
+        "    t_x = [0, 0, 1]\n",
+        "    q_x = [2, 1]\n",
+        "    r_x = [0, 3]\n",
+        "\n",
+        "    X = [[1, 2], [6, 10]]\n",
+        "    M = [[-1000, 10], [5, 3]]\n",
+        "    N = [[3, 6], [15, 1000]]\n",
+        "    p_M = convert(evaluate_polynomial(M, p_x, TZmax))\n",
+        "    t_N = convert(evaluate_polynomial(N, t_x, TZmin))\n",
+        "    q_M = convert(evaluate_polynomial(M, q_x, TZmax))\n",
+        "    r_N = convert(evaluate_polynomial(N, r_x, TZmin))\n",
+        "\n",
+        "    print('p(x) =', p_M)\n",
+        "    print('t(x) =', t_N)\n",
+        "    print('q(x) =', q_M)\n",
+        "    print('r(x) =', r_N)\n",
+        "\n",
+        "    Alica = TropicalMatrix.mult_tropical_matrix(p_M, X, TZmax)\n",
+        "    alice_public_key = TropicalMatrix.mult_tropical_matrix(convert(Alica), t_N, TZmin)\n",
+        "    print('Открытый ключ Алисы: ', alice_public_key)\n",
+        "\n",
+        "    Bob = TropicalMatrix.mult_tropical_matrix(q_M, X, TZmax)\n",
+        "    bob_public_key = TropicalMatrix.mult_tropical_matrix(convert(Bob), r_N, TZmin)\n",
+        "    print('Открытый ключ Боба: ', bob_public_key)\n",
+        "\n",
+        "    print('Секретный ключ Алисы: ', generate_key(convert(bob_public_key), p_M, t_N))\n",
+        "    print('Секретный ключ Боба: ', generate_key(convert(alice_public_key), q_M, r_N))"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "m-6cYpv2V3T1",
+        "outputId": "1082faa4-b53b-447e-ff8d-9388dbd0da88"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "p(x) = [[5, 10], [5, 5]]\n",
+            "t(x) = [[6, 9], [18, 21]]\n",
+            "q(x) = [[2, 10], [5, 3]]\n",
+            "r(x) = [[6, 9], [18, 1000]]\n",
+            "Открытый ключ Алисы:  [[22, 25], [17, 20]]\n",
+            "Открытый ключ Боба:  [[22, 25], [15, 18]]\n",
+            "Секретный ключ Алисы:  [[33, 36], [33, 36]]\n",
+            "Секретный ключ Боба:  [[33, 36], [33, 36]]\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "import random\n",
+        "\n",
+        "def pprint_matrix(matrix):\n",
+        "   print('\\n'.join(['  '.join([str(cell) for cell in row]) for row in matrix.entries]))\n",
+        "\n",
+        "if __name__ == \"__main__\":\n",
+        "   matrix_size = 2\n",
+        "   min_matrix_term = -15\n",
+        "   max_matrix_term = 15\n",
+        "   min_polynomial_coefficient = -10\n",
+        "   max_polynomial_coefficient = 10\n",
+        "   max_polynomial_degree = 5\n",
+        "\n",
+        "   print('Генерация многочленов')\n",
+        "\n",
+        "   print(\"Секретные многочлены Алисы: \")\n",
+        "   p_x = generate_random_tropical_poly(max_polynomial_degree, min_polynomial_coefficient, max_polynomial_coefficient)\n",
+        "   t_x = generate_random_tropical_poly(max_polynomial_degree, min_polynomial_coefficient, max_polynomial_coefficient)\n",
+        "   print('p(x) =', get_polynomial_representation(p_x))\n",
+        "   print('t(x) =', get_polynomial_representation(t_x))\n",
+        "\n",
+        "   print('Секретные многочлены Боба: ')\n",
+        "   q_x = generate_random_tropical_poly(max_polynomial_degree, min_polynomial_coefficient, max_polynomial_coefficient)\n",
+        "   r_x = generate_random_tropical_poly(max_polynomial_degree, min_polynomial_coefficient, max_polynomial_coefficient)\n",
+        "   print('q(x) =', get_polynomial_representation(q_x))\n",
+        "   print('r(x) =', get_polynomial_representation(r_x))\n",
+        "\n",
+        "   print('Открытая матрица Алисы: ')\n",
+        "   #M = generate_random_matrix(matrix_size, min_matrix_term, max_matrix_term)\n",
+        "   M = [[68, 1000],[-1000, 11]]\n",
+        "   print('M = ', M)\n",
+        "\n",
+        "   print('Открытая матрица Боба: ')\n",
+        "   #N = generate_random_matrix(matrix_size, min_matrix_term, max_matrix_term)\n",
+        "   N = [[15, 122],[78, 12]]\n",
+        "   print('N = ', N)\n",
+        "\n",
+        "   X_matrix = generate_random_matrix(matrix_size, min_matrix_term, max_matrix_term)\n",
+        "   print('Матрица X: ', X_matrix)\n",
+        "\n",
+        "   print('Алиса отправляет Бобу следующую матрицу')\n",
+        "   p_M = convert(evaluate_polynomial(M, p_x, TZmax))\n",
+        "   t_N = convert(evaluate_polynomial(N, t_x, TZmin))\n",
+        "   Alica = TropicalMatrix.mult_tropical_matrix(p_M, X, TZmax)\n",
+        "   alice_public_key = TropicalMatrix.mult_tropical_matrix(convert(Alica), t_N, TZmin)\n",
+        "   print('Открытый ключ Алисы: ')\n",
+        "   pprint_matrix(alice_public_key)\n",
+        "\n",
+        "   print('Боб отправляет Алисе следующую матрицу')\n",
+        "   q_M = convert(evaluate_polynomial(M, q_x, TZmax))\n",
+        "   r_N = convert(evaluate_polynomial(N, r_x, TZmin))\n",
+        "   Bob = TropicalMatrix.mult_tropical_matrix(q_M, X, TZmax)\n",
+        "   bob_public_key = TropicalMatrix.mult_tropical_matrix(convert(Bob), r_N, TZmin)\n",
+        "   print('Открытый ключ Боба: ')\n",
+        "   pprint_matrix(bob_public_key)\n",
+        "\n",
+        "   print('Алиса и Боб вычисляют секретные ключи')\n",
+        "   print('Секретный ключ Алисы: ')\n",
+        "   alice_key = generate_key(convert(bob_public_key), p_M, t_N)\n",
+        "   pprint_matrix(alice_key)\n",
+        "\n",
+        "   print('Секретный ключ Боба: ')\n",
+        "   bob_key = generate_key(convert(alice_public_key), q_M, r_N)\n",
+        "   pprint_matrix(bob_key)"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "lJW_ff1sek6r",
+        "outputId": "acfe9f61-eafc-49a3-8e9a-42a3a2b0808c"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Генерация многочленов\n",
+            "Секретные многочлены Алисы: \n",
+            "p(x) = 9 + -4x^1 + 9x^2 + 7x^3\n",
+            "t(x) = 10 + -8x^1 + -5x^2 + -7x^3\n",
+            "Секретные многочлены Боба: \n",
+            "q(x) = 2 + 9x^1 + -4x^2 + 8x^3\n",
+            "r(x) = 5 + 6x^1 + 8x^2 + 3x^3\n",
+            "Открытая матрица Алисы: \n",
+            "M =  [[68, 1000], [-1000, 11]]\n",
+            "Открытая матрица Боба: \n",
+            "N =  [[15, 122], [78, 12]]\n",
+            "Матрица X:  [[14, 5], [14, 1]]\n",
+            "Алиса отправляет Бобу следующую матрицу\n",
+            "Открытый ключ Алисы: \n",
+            "1000  1000\n",
+            "88  89\n",
+            "Боб отправляет Алисе следующую матрицу\n",
+            "Открытый ключ Боба: \n",
+            "1000  1000\n",
+            "87  91\n",
+            "Алиса и Боб вычисляют секретные ключи\n",
+            "Секретный ключ Алисы: \n",
+            "1000  1000\n",
+            "169  170\n",
+            "Секретный ключ Боба: \n",
+            "1000  1000\n",
+            "169  170\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [],
+      "metadata": {
+        "id": "vZge8KIiMEql"
+      },
+      "execution_count": null,
+      "outputs": []
+    }
+  ],
+  "metadata": {
+    "kernelspec": {
+      "display_name": "ml",
+      "language": "python",
+      "name": "python3"
+    },
+    "language_info": {
+      "codemirror_mode": {
+        "name": "ipython",
+        "version": 3
+      },
+      "file_extension": ".py",
+      "mimetype": "text/x-python",
+      "name": "python",
+      "nbconvert_exporter": "python",
+      "pygments_lexer": "ipython3",
+      "version": "3.10.9"
+    },
+    "colab": {
+      "provenance": []
+    }
+  },
+  "nbformat": 4,
+  "nbformat_minor": 0
+}
\ No newline at end of file