{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Calcul de la loi de groupe sur une courbe elliptique\n",
    "\n",
    "La fonction $\\wp$ de Weierstrass vérifie l'équation différentielle\n",
    "\n",
    "$$ [\\wp '(z)]^{2}=4[\\wp (z)]^{3}-g_{2}\\wp (z)-g_{3}$$\n",
    "\n",
    "de sorte que $(x,y)=(\\wp(t),\\wp'(t))$ fournit un paramétrage de la courbe elliptique d'équation\n",
    "$$y^2=4x^3-g_2x-g_3$$.\n",
    "\n",
    "Par ailleurs, elle vérifie la formule d'addition\n",
    "    \n",
    "$$ \\wp (z+y)={\\frac {1}{4}}\\left\\{{\\frac {\\wp '(z)-\\wp '(y)}{\\wp (z)-\\wp (y)}}\\right\\}^{2}-\\wp (z)-\\wp (y) $$\n",
    "\n",
    "et la formula de duplication\n",
    "\n",
    "$${\\displaystyle \\wp (2z)={\\frac {1}{4}}\\left\\{{\\frac {\\wp ''(z)}{\\wp '(z)}}\\right\\}^{2}-2\\wp (z),}$$\n",
    "\n",
    "valable si $2z$ n'est pas une période.\n",
    "\n",
    "\n",
    "Ces formules proviennent des faits suivants : (1) toute  droite coupe la courbe en 3 points (si on  compte les points de tangence avec multiplicité 2), et (2) la somme des zéros d'une fonction elliptique quelconque dans un parallélograme fondamental est congrue à la somme des pôles modulo le réseau des périodes.\n",
    "\n",
    "Ainsi, si $y=px+q$ est l'équation de la droite passant par $P_1$ et $P_2$ de paramètres $t_1$ et $t_2$, et si $t_3$ est\n",
    "le paramètre du troisième point d'intersection $P_3$, alors $t_1+t_2+t_3\\equiv 0 \\mod (\\omega_1,\\omega_2)$. En effet,\n",
    "la seule singularité de la fonction $\\wp'(z)-p\\wp(z)-q$ est un pôle triple en 0, la somme des trois zéros est donc\n",
    "un élément du réseau.\n",
    "\n",
    "\n",
    "Donc, dans le groupe ${\\mathbb C}/({\\mathbb Z}\\omega_1\\oplus{\\mathbb Z}\\omega_2)$, on a $t_3 = -(t_1+t_2)$.\n",
    "Comme $\\wp$ est paire, et sa dérivée $\\wp'$ impaire, le point de paramètre $-t_3$ est $(x_3,-y_3)$, donc, le\n",
    "symétrique de $P_3$ par rapport à l'axe des abscisses.\n",
    "\n",
    "C'est ce point que nous allons maintenant calculer pour la courbe\n",
    "$$y^2 = x^3+ax+b.$$\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sympy import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(x, y, x1, y1, x2, y2, s, a, b)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var('x y x1 y1 x2 y2 s a b')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\frac{- y_{1} + y_{2}}{- x_{1} + x_{2}}$"
      ],
      "text/plain": [
       "(-y1 + y2)/(-x1 + x2)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = (y2-y1)/(x2-x1); s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "E = y**2-x**3-a*x-b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "L'équation de la droite $P_1P_2$ est\n",
    "$$\\left|\\begin{matrix}x-x_1& x_2-x_1\\\\ y-y_1&y_2-y1\\end{matrix}\\right|=0$$\n",
    "ou encore\n",
    "$$y = s(x-x_1)+y_1.$$\n",
    "On substitue cette valeur de $y$ dans l'équation de la courbe :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle - a x - b - x^{3} + \\left(y_{1} + \\frac{\\left(x - x_{1}\\right) \\left(- y_{1} + y_{2}\\right)}{- x_{1} + x_{2}}\\right)^{2}$"
      ],
      "text/plain": [
       "-a*x - b - x**3 + (y1 + (x - x1)*(-y1 + y2)/(-x1 + x2))**2"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "E.subs({y:(x-x1)*s+y1})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle - \\left(x_{1} - x_{2}\\right)^{2} \\left(a x + b + x^{3}\\right) + \\left(y_{1} \\left(x_{1} - x_{2}\\right) + \\left(x - x_{1}\\right) \\left(y_{1} - y_{2}\\right)\\right)^{2}$"
      ],
      "text/plain": [
       "-(x1 - x2)**2*(a*x + b + x**3) + (y1*(x1 - x2) + (x - x1)*(y1 - y2))**2"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "simplify(_*(x2-x1)**2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle - a x x_{1}^{2} + 2 a x x_{1} x_{2} - a x x_{2}^{2} - b x_{1}^{2} + 2 b x_{1} x_{2} - b x_{2}^{2} - x^{3} x_{1}^{2} + 2 x^{3} x_{1} x_{2} - x^{3} x_{2}^{2} + x^{2} y_{1}^{2} - 2 x^{2} y_{1} y_{2} + x^{2} y_{2}^{2} + 2 x x_{1} y_{1} y_{2} - 2 x x_{1} y_{2}^{2} - 2 x x_{2} y_{1}^{2} + 2 x x_{2} y_{1} y_{2} + x_{1}^{2} y_{2}^{2} - 2 x_{1} x_{2} y_{1} y_{2} + x_{2}^{2} y_{1}^{2}$"
      ],
      "text/plain": [
       "-a*x*x1**2 + 2*a*x*x1*x2 - a*x*x2**2 - b*x1**2 + 2*b*x1*x2 - b*x2**2 - x**3*x1**2 + 2*x**3*x1*x2 - x**3*x2**2 + x**2*y1**2 - 2*x**2*y1*y2 + x**2*y2**2 + 2*x*x1*y1*y2 - 2*x*x1*y2**2 - 2*x*x2*y1**2 + 2*x*x2*y1*y2 + x1**2*y2**2 - 2*x1*x2*y1*y2 + x2**2*y1**2"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expand(_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On utilise ensuite le fait que $(x_1,y_1)$ vérifie l'équation de la courbe :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle - a x x_{1}^{2} + 2 a x x_{1} x_{2} - a x x_{2}^{2} - b x_{1}^{2} + 2 b x_{1} x_{2} - b x_{2}^{2} - x^{3} x_{1}^{2} + 2 x^{3} x_{1} x_{2} - x^{3} x_{2}^{2} - 2 x^{2} y_{1} y_{2} + x^{2} y_{2}^{2} + x^{2} \\left(a x_{1} + b + x_{1}^{3}\\right) + 2 x x_{1} y_{1} y_{2} - 2 x x_{1} y_{2}^{2} + 2 x x_{2} y_{1} y_{2} - 2 x x_{2} \\left(a x_{1} + b + x_{1}^{3}\\right) + x_{1}^{2} y_{2}^{2} - 2 x_{1} x_{2} y_{1} y_{2} + x_{2}^{2} \\left(a x_{1} + b + x_{1}^{3}\\right)$"
      ],
      "text/plain": [
       "-a*x*x1**2 + 2*a*x*x1*x2 - a*x*x2**2 - b*x1**2 + 2*b*x1*x2 - b*x2**2 - x**3*x1**2 + 2*x**3*x1*x2 - x**3*x2**2 - 2*x**2*y1*y2 + x**2*y2**2 + x**2*(a*x1 + b + x1**3) + 2*x*x1*y1*y2 - 2*x*x1*y2**2 + 2*x*x2*y1*y2 - 2*x*x2*(a*x1 + b + x1**3) + x1**2*y2**2 - 2*x1*x2*y1*y2 + x2**2*(a*x1 + b + x1**3)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "_.subs({y1**2:x1**3+a*x1+b})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle a x^{2} x_{1} - a x x_{1}^{2} - a x x_{2}^{2} + a x_{1} x_{2}^{2} + b x^{2} - 2 b x x_{2} - b x_{1}^{2} + 2 b x_{1} x_{2} - x^{3} x_{1}^{2} + 2 x^{3} x_{1} x_{2} - x^{3} x_{2}^{2} + x^{2} x_{1}^{3} - 2 x^{2} y_{1} y_{2} + x^{2} y_{2}^{2} - 2 x x_{1}^{3} x_{2} + 2 x x_{1} y_{1} y_{2} - 2 x x_{1} y_{2}^{2} + 2 x x_{2} y_{1} y_{2} + x_{1}^{3} x_{2}^{2} + x_{1}^{2} y_{2}^{2} - 2 x_{1} x_{2} y_{1} y_{2}$"
      ],
      "text/plain": [
       "a*x**2*x1 - a*x*x1**2 - a*x*x2**2 + a*x1*x2**2 + b*x**2 - 2*b*x*x2 - b*x1**2 + 2*b*x1*x2 - x**3*x1**2 + 2*x**3*x1*x2 - x**3*x2**2 + x**2*x1**3 - 2*x**2*y1*y2 + x**2*y2**2 - 2*x*x1**3*x2 + 2*x*x1*y1*y2 - 2*x*x1*y2**2 + 2*x*x2*y1*y2 + x1**3*x2**2 + x1**2*y2**2 - 2*x1*x2*y1*y2"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expand(_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle - \\left(x - x_{1}\\right) \\left(- a x x_{1} + a x_{2}^{2} - b x - b x_{1} + 2 b x_{2} + x^{2} x_{1}^{2} - 2 x^{2} x_{1} x_{2} + x^{2} x_{2}^{2} - 2 x x_{1}^{2} x_{2} + x x_{1} x_{2}^{2} + 2 x y_{1} y_{2} - x y_{2}^{2} + x_{1}^{2} x_{2}^{2} + x_{1} y_{2}^{2} - 2 x_{2} y_{1} y_{2}\\right)$"
      ],
      "text/plain": [
       "-(x - x1)*(-a*x*x1 + a*x2**2 - b*x - b*x1 + 2*b*x2 + x**2*x1**2 - 2*x**2*x1*x2 + x**2*x2**2 - 2*x*x1**2*x2 + x*x1*x2**2 + 2*x*y1*y2 - x*y2**2 + x1**2*x2**2 + x1*y2**2 - 2*x2*y1*y2)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "factor(_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On peut maintenant diviser par $x-x_1$ :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle a x x_{1} - a x_{2}^{2} + b x + b x_{1} - 2 b x_{2} - x^{2} x_{1}^{2} + 2 x^{2} x_{1} x_{2} - x^{2} x_{2}^{2} + 2 x x_{1}^{2} x_{2} - x x_{1} x_{2}^{2} - 2 x y_{1} y_{2} + x y_{2}^{2} - x_{1}^{2} x_{2}^{2} - x_{1} y_{2}^{2} + 2 x_{2} y_{1} y_{2}$"
      ],
      "text/plain": [
       "a*x*x1 - a*x2**2 + b*x + b*x1 - 2*b*x2 - x**2*x1**2 + 2*x**2*x1*x2 - x**2*x2**2 + 2*x*x1**2*x2 - x*x1*x2**2 - 2*x*y1*y2 + x*y2**2 - x1**2*x2**2 - x1*y2**2 + 2*x2*y1*y2"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "simplify(_/(x-x1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On recommence avec $(x_2,y_2)$ :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle a x x_{1} - a x_{2}^{2} + b x + b x_{1} - 2 b x_{2} - x^{2} x_{1}^{2} + 2 x^{2} x_{1} x_{2} - x^{2} x_{2}^{2} + 2 x x_{1}^{2} x_{2} - x x_{1} x_{2}^{2} - 2 x y_{1} y_{2} + x \\left(a x_{2} + b + x_{2}^{3}\\right) - x_{1}^{2} x_{2}^{2} - x_{1} \\left(a x_{2} + b + x_{2}^{3}\\right) + 2 x_{2} y_{1} y_{2}$"
      ],
      "text/plain": [
       "a*x*x1 - a*x2**2 + b*x + b*x1 - 2*b*x2 - x**2*x1**2 + 2*x**2*x1*x2 - x**2*x2**2 + 2*x*x1**2*x2 - x*x1*x2**2 - 2*x*y1*y2 + x*(a*x2 + b + x2**3) - x1**2*x2**2 - x1*(a*x2 + b + x2**3) + 2*x2*y1*y2"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "_.subs({y2**2:x2**3+a*x2+b})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle - \\left(x - x_{2}\\right) \\left(- a x_{1} - a x_{2} - 2 b + x x_{1}^{2} - 2 x x_{1} x_{2} + x x_{2}^{2} - x_{1}^{2} x_{2} - x_{1} x_{2}^{2} + 2 y_{1} y_{2}\\right)$"
      ],
      "text/plain": [
       "-(x - x2)*(-a*x1 - a*x2 - 2*b + x*x1**2 - 2*x*x1*x2 + x*x2**2 - x1**2*x2 - x1*x2**2 + 2*y1*y2)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "factor(_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle a x_{1} + a x_{2} + 2 b - x x_{1}^{2} + 2 x x_{1} x_{2} - x x_{2}^{2} + x_{1}^{2} x_{2} + x_{1} x_{2}^{2} - 2 y_{1} y_{2}$"
      ],
      "text/plain": [
       "a*x1 + a*x2 + 2*b - x*x1**2 + 2*x*x1*x2 - x*x2**2 + x1**2*x2 + x1*x2**2 - 2*y1*y2"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "simplify(_/(x-x2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Il ne reste plus qu'à extraire la valeur de $x_3$ :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(a*x1 + a*x2 + 2*b + x1**2*x2 + x1*x2**2 - 2*y1*y2)/(x1**2 - 2*x1*x2 + x2**2)]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "solve(_,x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\frac{a x_{1} + a x_{2} + 2 b + x_{1}^{2} x_{2} + x_{1} x_{2}^{2} - 2 y_{1} y_{2}}{\\left(x_{1} - x_{2}\\right)^{2}}$"
      ],
      "text/plain": [
       "(a*x1 + a*x2 + 2*b + x1**2*x2 + x1*x2**2 - 2*y1*y2)/(x1 - x2)**2"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "factor(_[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "En remplaçant $ax_1+b$ par $y_1^2-x_1^3$ et $ax_2+b$ par $y_2^2-x_2^3$, on voit que cette expression vaut\n",
    "$$x_3=s^2-x_1-x_2.$$\n",
    "Et pour finir,\n",
    "$$y_3 = -s(x_3-x_1)-y_1$$\n",
    "d'après l'équation de la droite $P_1P_2$.\n",
    "\n",
    "Si $P_2=P_1$, la droite $P_1P_2$ est remplacée par la tangente, qui a pour équation\n",
    "$$\\frac{\\partial F}{\\partial x}(x-x_1)+\\frac{\\partial F}{\\partial y}(y-y_1)=0$$\n",
    "avec $F(x,y)=y^2-x^3-ax-b$, soit\n",
    "$$y = s(x-x1)+y_1$$\n",
    "avec cette fois\n",
    "$$s=\\frac{3x_1^2+a}{2y_1}.$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
