{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Courbes elliptiques\n", "\n", "## De quoi sont les courbes elliptiques ?\n", "\n", "Pour faire court, ce sont, du troisième degré, les courbes planes non singulières, autrement dit, les courbes définies par une équation $P(x,y)=0$, où $P$ est un polynôme de degré 3 en au moins une des variables, et qui admettent en chaque point une tangente unique (ce qui exclut par exemple le folium de Descartes $x^3+y^3=3axy$ (un point double : cubique nodale) ou la parabole semi-cubique $y^2−x^3=0$ (une tangente double au point anguleux), ainsi que toutes le courbes qui se décomposent en une droite et une conique.\n", "\n", "On peut faire quelques dessins avec jupyter, sympy et matplotlib." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from sympy import *\n", "from sympy.plotting import plot, plot_parametric\n", "import math\n", "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline " ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(x, y)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "var('x y')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Par exemple,\n", "$$y^2=x^3-3x$$\n", "est une courbe elliptique :" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/png": "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xUMMHDggde3q9odk5A44NkbsgBgpXVrq1s2dHbthg3WaxJebK910k9S/f+FK3VtvvaWvv/5aklShQoUYpUOslCghlSrl/g39+KN1GsD7KHZADF17rXTccdIzz1gnSWx790p9+7q/x4Jcgv3Z0qVL1a5dO43871DPww8/HKOEiKW//EX65z+lb76xTgJ4H8UOiKELL3QbrD7xhLRpk3WaxBSJSHfc4fYHbNSo4M9bu3atWrVqpf79+6tDhw6SpJkzZ+rTTz+NUVLEyhlnuLcHDtjmABIBc+yAGNuyRTrzTKlpUzc3DIXTpYt0/PHS3/9e8Od8//33atSokRo3bqxx48YpHA4rGAzqqquu0oEDBzRnzpzYBUZMjB7t9rP7+GPrJIC3lbIOAPhdhQrSk09KgwZJn34q1a1rnSgx7N/v/t4iEWngwMI996STTtJXX331m/unTp2q9PT0KCVEPFWqJOXnSxs3SqedZp0G8C4uxQJx0LmztG+f25MLBZOT40Zohg51L+pIbm3aSHl50ltvWScBvI1iB8TJU0+57ToeecSNQuHI5s6VbrtNWrTI7VkHSFKrVtLrr1unALyNYgfEyQ03SDffLN13n7RihXUabzpwwJ0oMWaM29z5+OOtE8FLrrnGbR/0ixPiAPwKiyeAONqyRbr4YqliRWnmTKl8eetE3vLxx26vugULpGgeDvHz4olQKMQcuwS2c6f7Benss9msGDgSRuyAOKpQQRo+XFqyhBemX3viCbdY4pNPolvq4B/lykk33ij961/S999bpwG8iRE7wEC3btL06W5xQKtWbnf9ZJWfL111lTtd4LXXpJIlo/85GLHzj717pdRUd37s2WdbpwG8J4lfTgA7gwZJVapIrVtLn39uncbODz9IDz8s/e530pQpsSl18JfSpaU//1kaP946CeBNFDvAQNWq7oXpzDOlrCw39y7ZrF4tderkCu7YsVIwaJ0IiaBkSXeiCweIAIdHsQOMXHyxm1f26adutV9+vnWi+DhwQHrzTalePalnT6lrV+tESDTduknbt0uvvGKdBPAeih1g6OqrpWnT3GTwJk2kDRusE8VWKCT16eMupb36qvuagcI64QSpfXvp2WetkwDeQ7EDjLVu7fZu+/BDd0JFKGSdKDZWrnTn5a5e7VYFN21qnQiJrGlTt9chgENR7AAPaNPGnUzx9ttS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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Une courbe elliptique\n", "p1 = plot_implicit(Eq(y**2,x**3-3*x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Le *folium de Descartes*\n", "$$x^3+y^3=6xy$$\n", "n'en est pas une. C'est le logo de la cité Descartes (regarder les panneaux)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Folium de Descartes\n", "p2 = plot_implicit(Eq(x**3+y**3,6*x*y))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La *parabole semi-cubique*\n", "$$y^2=x^3$$\n", "n'en est pas une non plus (point anguleux) :" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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hpCVlZWQ16xWrRqZmZls3Lhxm/eosLCQunXr7tb7lpWVtfX5558ff6xbF79xYupU+OILuPhib55Idv55Tg++z9vndieSdmry5Ml07dqVo446iuzsbE477TReeeUVcnNzmThxIkuXLuXII49kyZIlCXn9KlWq0KJFCxYuXLjN9YULF3L88ceX+evvv3+84I0cGd/e5Omn4Q9/gAUL4lugSFIycbsTSTs1YsQIWrVqxRVXXEGrVq1o2bIlVatW3frrV111FSNHjqRLly688847CcnQu3dvLrvsMlq2bMlxxx3HXXfdxcqVK+nevXu5vUalSlC7NowfH9+guGdPeO45OPlk97KTlDwsdjtQtWpVBg8evM0/YEo9vs+7tmrVql0+p2vXrgwcODBhGTp16sTnn3/O0KFDWbNmDU2bNuUvf/kLBx98cKk+/4f3t7Tvc/XqcPfd/z1SbPHi+AkULVrs8begCuCf5/Tg+7xz7mMnqcxisRgvvvgiJ510Uugo27W9fexK67vvYMUKGD4cGjeGm25KUEhJKgcWO0kpryzF7gclJfFRvEWL4PTT4ZJLoEqVcg4qSWXkzROSVAqZmXDNNTB9OqxZA7//ffy/khQlFjtJ2k39+0PXrnDFFfDKK6HTSNJ/ORUrKeWVx1Ts9hQUQPfu0LQp9O0bH9Xbxd6hkpRQjthJ0h7KzoZHHoHDD49vbDxpEnz7behUktKZxW43FBUV0axZMzIyMli6dGnoOCpHH330EV27dqVhw4ZUr16dRo0aMXjwYIqLi0NHUxlNnDiRX//61wC0bt2al156qdxf46KLYPZsKCyEa6+FTz8t95fQTuTn53PMMceQlZVFnTp1aN++Pe+//37oWEqg/Px8MjIy6NWrV+gokWOx2w033ngjdevWDR1DCfDee++xZcsWpkyZwrJly7jtttuYPHky/fv3Dx1NZTBz5kx69epFnz59ADjuuOM488wzWblyZUJer18/6NYNLr8cXn01IS+h7Vi0aBG5ubm89tprLFy4kO+//562bduyadOm0NGUAG+88QZ33XUXRx11VOgokeQau1J65pln6N27N48//jhNmjTh7bffplmzZqFjKYHGjBnDpEmTWLFiRego2kM5OTk0b96c0aNHb11jl5OTQ/v27cnPz0/Y637zDVx1FRx1FPTp47YoFW39+vXUqVOHRYsW0bp1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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Parabole semi-cubique\n", "p3 = plot_implicit(Eq(y**2-x**3,0))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un autre forme possible pour une courbe elliptique (en un seul morceau)\n", "$$y^2=x^3-x+1$$" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnYAAAHVCAYAAAB8NLYkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA0BklEQVR4nO3de5yOdf7H8fftfJoZp4aEyO6mpKYYQ4ksq4MtVH4lKseadpBmrWOiwhAdFaLCRggRoUihk7CS1KbFMpOJzMp9o8wY7t8f39DEMGPue77Xdd2v5+Mxj+U2h3dmy9vn+h58wWAwKAAAALheEdsBAAAAEBoUOwAAAI+g2AEAAHgExQ4AAMAjKHYAAAAeQbEDAADwCIodAACAR1DsAHheMBhUIBAQx3YC8DqKHQDPO3jwoGJiYnTw4EHbUYCQ6thRWrfOdgo4CcUOAAAX+vxzyeeTGjWynQROQrEDAMCFxoyRBgywnQJOQ7EDAMBl1qyRypeXrrrKdhI4TTHbAQAAQN4dOCCNGiXNmGE7CZyIiR0AAC6yfr3UuLFUubLtJHAiJnYAALjErl3S6NHSnDm2k8CpmNgBAOASn30m/elPTOuQOyZ2AAC4xBtvSBMm2E4BJ2NiBwCAC0ybJsXHS9Wr204CJ2NiBwCAw+3fL82cKb35pu0kcDomdgAAONycOdJNN0kVKthOAqdjYgcAgINt2iStXCnNm2c7CdyAiR0AAA729tvS3XfbTgG3oNgBAOBQn3wiffmldNtttpPALSh2AAA40LFj5vFru3ZSiRK208AtKHYAADjQp59K6enSnXfaTgI3odgBAOBAU6ZIHTtKZcrYTgI3odgBAOAwixZJxYqZx7BAflDsAABwmBEj2AmL80OxAwDAQWbPllq3Nm9AfnFAMQAADvHLL1JiovT557aTwK2Y2AEA4BCzZ0v/+Id06aW2k8CtmNgBAOAABw5ICxaYjRPA+WJiBwCAA0yeLDVubDsF3I6JHQAAlh05Iv3736bcAQXBxA4AAIuCQWn4cKlJE6l4cdtp4HYUOwAALNq4Ufr2W+mee2wngRdQ7AAAsGjSJKlTJ6lcOdtJ4AUUOwAALFm+XDp4UOrQwXYSeAXFDgAAS0aONNM6IFQodgAAWLBggdSokXTrrbaTwEs47gQAAAu6d5fef992CngNEzsAAArZzJlSr17SNdfYTgKvYWIHAEAh2rFDGjhQ2rXLdhJ4ERM7AAAK0ZIlUteuks9nOwm8iIkdAACF5F//ktaskWbNotghPJjYAQBQSBYvlpKTpWKMVRAmFDsAAArBpk3m+rB69WwngZdR7AAACLNgUHrtNXN9WHS07TTwMoodAABh9vHH0vffS7GxtpPA6yh2AFwlJSVFPp9Pffv2tR0FyJO9e6WUFGnsWNbWIfwodgBcY/369Zo8ebKuvPJK21GAPFu5UqpaVapTx3YSRAKKHQBXOHTokDp16qQpU6aoQoUKtuMAeXLkiPTqq9Jjj9lOgkhBsQPgCklJSWrTpo1atWp1zvfNzMxUIBDI8QbYMHSo9I9/SLVq2U6CSEGxA+B4s2fP1saNG5WSkpKn909JSVFMTMzJtxo1aoQ5IXC69HRp82apWTPbSRBJKHYAHC0tLU0PP/ywZsyYoVKlSuXpYwYNGiS/33/yLS0tLcwpgdM98YTUr59UpoztJIgkvmAwGLQdAgBys3DhQrVv315FixY9+dqxY8fk8/lUpEgRZWZm5vi1MwkEAoqJiZHf71c0h4ihEMyfL40aZa4QAwoTG68BOFrLli311Vdf5Xita9euqlu3rgYMGHDOUgfYMG+eOYwYKGwUOwCOFhUVpSuuuCLHa2XLllWlSpVOex1wgkmTzE0T8fG2kyASUewAAAiRQMBM6yZPtp0EkYpiB8B1Vq1aZTsCcEZTpki33y5dcontJIhUFDsAAEJg7VrpjTfYMAG7OO4EAIAQeOstKTHRdgpEOoodAAAF9OGH0r59UteutpMg0lHsAAAogKNHpdmzzbl1xVjgBMsodgAAFMDKlVJmplSxou0kAJsnAAA4bzt3SmPGmPV1JUvaTgMwsQMA4Lx98onUp49UoYLtJIBBsQMA4DykpUmvvy4lJNhOApxCsQMAIJ8yM6W//10aPFiqVs12GuAUih0AAPm0f7/0/ffSlVfaTgLkRLEDACAfDh+WkpKk556Type3nQbIiWIHAEA+vPKKmdQ1amQ7CXA6ih0AAPnw1lvSrbfaTgGcGefYAQCQB8ePm9slOnSQGjSwnQY4M4odAAB58PXX0qefSnPm2E4C5I5iBwDAOezbZ443mTRJioqynQbIHWvsAAA4h2++kcqWlS65xHYS4OyY2AEAcBaBgDRypPTCC7aTAOfGxA4AgFwcPy4NGSJ17SrVrWs7DXBuFDsAAHKRlSWtWCE1b247CZA3FDsAAM7g2DHpkUekp5/mPli4B8UOAIAzWLBAOnpUatPGdhIg79g8AQDA7+zcKb32mrk+DHATJnYAAPzO0qVS/fo8goX7MLEDAOA3fvpJeuMNcycs4DZM7AAA+NWhQ+Zok+eek2JjbacB8o9iBwDAr2bOlHbvlho2tJ0EOD8UOwAAZA4jfvtt6cUXbScBzh/FDgAASaNHS3/+s5SQYDsJcP7YPAEAiHhbt0pr1kizZ9tOAhQMxQ4AENH275ceekiaNk0qX952GqBgeBQLAIhoW7dKpUtL1avbTgIUHMUOABCx9u+XRoyQxo2TivAnIjyA/xsDACLWiBHSnXdKl11mOwkQGhQ7AEBEWrPGnFnXsaPtJEDoUOwAABFn716pb1+pUyepVCnbaYDQodgBACLO+vXSlVdKbdrYTgKEFsedAAAiys6d5naJadOkokVtpwFCi4kdACCiPP641KePVLWq7SRA6FHsAAAR4623pAsukG65xXYSIDx4FAsAiAjp6dLf/y59+aXtJED4MLEDAESEAQOk22+Xypa1nQQIHyZ2AADP27JF8vulV19lwwS8jYkdAMDzUlKkwYOlEiVsJwHCi2IHAPC0yZPNmXWNG9tOAoQfj2IBAJ61e7e0YIE0d67tJEDhYGIHAPCkn3+W7r/f3C5RrpztNEDhoNgBADxpwgTp+HGpVy/bSYDCw6NYAIAnzZkjvfKK7RRA4aLYAQA85fhxadQoqWdP6aqrbKcBChfFDgDgKZs2SZ9/biZ2QKSh2AEAPOPHH6VHH5XGj5fKlLGdBih8bJ4AAHjGM89IbdtKderYTgLYQbEDAHjChx9K+/ZJPXrYTgLYw6NYAIDrHTwojRkjTZvGXbCIbEzsAACu99RT5jDiqlVtJwHsYmIHAHC1Vauk6dOl1FTbSQD7mNgBAFzrwAEpMVGaNMl2EsAZKHYAAFfKzpYGDJBatpRuucV2GsAZeBQLAHCllSulTz4x/wvAYGIHAHCdXbukwYPNuXVVqthOAzgHxQ4A4DqPPy41aSK1bm07CeAsPIoFALjK/PnSN99ICxfaTgI4D8UOAOAamZnSAw9ICxZwZh1wJjyKBQC4Qmam1KWL9NBD0vXX204DOBMTOwCAK8ydK335pTRrlu0kgHMxsQMAON5//mN2wE6caDsJ4GwUOwCAowWDUr9+0m23Sc2b204DOBvFDgDgaDNmSD/9JPXqZTsJ4HyssQMAONZ//iMNGSItXSpVrmw7DeB8TOwAAI6VnCx17y5dcYXtJIA7UOwAAI700kuS32+uDgOQNzyKBQA4TmqqNHy4tHq1VLy47TSAezCxAwA4it8vPfigNGyYdPnlttMA7kKxAwA4ymuvSUeOSH/7m+0kgPvwKBYA4Bjr1pm3Dz6QfD7baQD3YWIHAHCMUaPMZglKHXB+KHYAAEcYN0668Uapfn3bSQD34lEsAMC65583O2Dfest2EsDdmNgBcLSUlBTFx8crKipKsbGxateunbZu3Wo7FkJo3Tpp2jTzGJajTYCCodgBcLTVq1crKSlJa9eu1YoVK5Sdna3WrVvr8OHDtqMhRPr0kXr25BEsEAq+YDAYtB0CAPJq3759io2N1erVq9WsWbM8fUwgEFBMTIz8fr+io6PDnBD5MXastGaNNGeOVKaM7TSA+7HGDoCr+P1+SVLFihVzfZ/MzExlZmae/HkgEAh7LuTfpk1mXd3s2ZQ6IFR4FAvANYLBoJKTk9W0aVNdcZZb4VNSUhQTE3PyrUaNGoWYEnmxf780dKj01FNSuXK20wDewaNYAK6RlJSkJUuW6OOPP1b16tVzfb8zTexq1KjBo1gHSUiQunSRHnrIdhLAW3gUC8AVevfurUWLFmnNmjVnLXWSVLJkSZUsWbKQkiE/gkFpzBipShWpa1fbaQDvodgBcLRgMKjevXtrwYIFWrVqlWrXrm07Egrgiy9Msdu+XSpVynYawHsodgAcLSkpSW+88YbefvttRUVFac+ePZKkmJgYlS5d2nI65EdGhllX9/nn0ln2vgAoANbYAXA0Xy6Xhk6dOlVdunTJ0+fguBNniI+XevSQHnzQdhLAu5jYAXA0/u7pfsePS08+KdWsKXXrZjsN4G0UOwBAWG3cKL30kvT111wZBoQb59gBAMLmxx/Nurq1a6ULLrCdBvA+ih0AIGxuuUVq31665BLbSYDIQLEDAITc8ePS4MFSnTpmwwSAwsEaOwBAyD31lPTvf0szZkhFGCEAhYZiBwAIqfXrpUmTpDVrpLJlbacBIgt/jwIAhMyxY9KoUdLrr5vjTQAULoodACAkjhyRmjaV2rSRrr/edhogMlHsAAAh8eyz0oUXSh072k4CRC6KHQCgwF544dRBxKyrA+xh8wQAoEDWrpWmT5emTTMTOwD2MLEDAJy3HTvMPbDJyVL9+rbTAKDYAQDOy/790gMPSO3aSZ062U4DQKLYAQDOU4cO0o03Sj172k4C4ATW2AEA8iUYlFJSpBIlpH79bKcB8FsUOwBAvkyaJK1aJb35puTz2U4D4Ld4FAsAyLPp06V33pGmTJHKl7edBsDvMbEDAOTJunVmWvf889LFF9tOA+BMKHYAgHPas0e6+WbzCJZjTQDn4lEsAOCs/vtfqVEjacgQSh3gdBQ7AECuvvtO6txZuu8+6ZFHbKcBcC48igUAnNGhQ9KwYVKrVtKjj7IDFnADih0A4DRHjphbJerUkR5/3HYaAHnFo1gAQA5padL//Z9UqRKlDnAbih0A4KTjx6Xhw6ULL5RGjZKKFrWdCEB+8CgWACBJOnpU6tVLSk2Vpk6VoqJsJwKQXxQ7AID27ZMGDjTlbulSqXhx24kAnA+KHQBAY8ZIfr/00kuUOsDNKHYAEMECAalDBzOxe/NNqUoV24kAFATFDsB5CwSkXbvy/3HVqpkdl7ArEJDGjjX3vi5cKJUubTsRgIKi2AHIk6NHpffeMz9evFjavt1MeUqUOH3Kk5golSp16udvvimlp5/6ed260rFj0ldfSUWKSH36mNfj4qTq1cP6j4Ffffed1KWLFBMjLVtmOw2AUPEFg8Gg7RAAnOnoUWnyZGn6dCkjw5SAa6+V/vpX6Q9/MO9z4YVSuXL5/9x+v/Tjj+bHmzaZy+UrVZJmzTLXV1WsKF19tfl6BRUIBBQTEyO/36/o6OiCf0KX+/ln8/i1USOpXz+pbFnbiQCECsUOQA4HDkiffSbNnGkmdPHx5q7QO+8007ViYZzzB4OmTEpmZ+a2baZUNm1qrrW69lqpQoWc08C8oNidsm6d1LWr+Z4OHMg1YYDXUOwASJL27pVGjJCWLJFiY80f/G3aSLVr205mrrdauFDascPk3LvXXHd1zTVS+fLn/niKnZSdLU2cKKWkSMnJZlIHwHtYYwdEuJ9+kgYMkN5/X7ruOjOpa9LEdqqcSpWS7r7b/DgzU9q40Uzzli0zU774eOmGG9jReTYffihNmCAtWCAlJNhOAyBcmNgBEerE5oX77jPr5F57TbrgArMZwi2ys806va1bzWPj7783d5zefHPOs9gieWJ37Ji5ImzCBGnGDPN7A8C7KHZABNq8WerUySyi791b6tvXdqLQefllM8m7/HLp/vvNUR5ZWZFZ7NLSpLvuMuvopk8/teEFgHdR7IAIM3Giudz9gQekwYO9e8n7li3SO++Y9XixsQENHhxZxW7+fOmRR0yxGz6cna9ApKDYARHC75ceflj6+GNpyhSpRQvbiQrHL79ImzYFdO21Mbr9dr9uvTVaXbrYThU+x46ZCezbb0vPPGN2MwOIHBQ7IAJkZUlt25p1Z6+/bs6jiyQn1tjt3u3Xp59Ga/Fic/vFrbeaQ5HLlLGdMDS2bjWPn0uXNo9ea9a0nQhAYaPYAR6Xnm7OLcvKMjsjI9GZNk/s3SstWmQORr7sMlN869e3m/N8paZKjz1mdjZ36iSNGWM7EQBbKHaAh+3ZY24XaN9eGjbM3OYQic61K3btWvPo0u83R720amV2CrvB3LnmEXu3bub73KCB7UQAbKLYAR61fbu5C7RxY2n0aO9uksiLvB53cuCAOSNv5UpzGPI995jHtU60apXUo4c5vPmll8zEEQAodoAH+f1SYqKZOo0bZ64Ci2T5PccuGJSOH5deeUVavFhq2NAcftyund1J3oED5kqwbt2kw4fNYdI33hjZpR1AThQ7wGOysqQHHzSTnGeflapWtZ3IvoIeUPz112Y93gcfmPPxbrvNXGVWWI89166VZs82171VqiR17Giue+NcOgC/R7EDPGbhQmnoUHOsSaTtfs1NKG+eSEuTVq82v8+7dpmNFzfdZKZ6f/pTaPKe+DrvvGNuBNm40VyZ1qGD1LMnEzoAuaPYAR6ydKnUubNZUN+ype00zhGOK8Wys6X9+6VvvjHXma1fL/3nP9Ltt0uxsWaH7e+/B8WLS8V+vaE7K8ucOXfC2rXm7eBB8wjY5zOvd+smPfSQmby66bo3AHZQ7ACPyMgwGyU6dzY3DeCUwrwrdv58ad8+c23bBx+cen3HDqlp01NTvRUrzGtlykg1apjXatc+tQnixHl0AJAfFDvAA7KyzCO62Fhp7FjbaZynMItdbj76SDp06PTXK1eW4uMLPw8AbypmOwCAgluyxEyIVq60nQS5uf562wkARIIIPwQBcL9t26TBg83C+kg9gBgAYFDsAJf78EOzTmvwYNtJAAC28SgWcLGtW6UXXpAmT7adBADgBEzsAJcKBs1ZalWrmvtNAQBgYge4VCAgjRwpbdliOwkAwCmY2AEuNXGiuQ+2Zk3bSQAATsHEDnChPXuk99+Xpk+3nQQA4CRM7AAX2rRJuuAC6aKLbCcBADgJxQ5wob59pdtus50CAOA0FDvAZebPlypUkFq0sJ0EAOA0FDvAZVJTpb/8xRxzAgDAb7F5AnCRX36R+vWTvv7adhIAgBMxsQNc5L//lVq3lqpVs50EAOBEFDvARUaPlurWlaKjbScBADgRxQ5wiWBQKlKETRMAgNxR7ACX+Owzac4cjjkBAOSOYge4yKWX2k4AAHAyih3gEk88ISUn204BAHAyih3gEnv2SMWL204BAHAyih3gEgkJUseOtlMAAJyMYge4wMKF0o4dtlMAAJyOYge4wO7d0uHDtlMAAJyOYge4xB132E4AAHA6ih3gEq1b204AAHA6ih3gcNnZ0lNP2U4BAHADih3gAqmpthMAANyAYgcAAOARFDvABdq0kWrVsp0CAOB0FDvABS6+WIqKsp0CAOB0FDsArjBhwgTVrl1bpUqVUoMGDfTRRx/ZjgQAjkOxA3BWaWlptiNozpw56tu3r4YMGaIvvvhC119/vW6++WalsqsEAHKg2AE4q7p162ro0KE6bPHqi2eeeUbdu3dXjx49dNlll+m5555TjRo1NHHiRGuZAMCJiuXlnYLBoA4ePBjuLADOIDtbysqSAgE7X3/hwoUaNGiQpkyZoscee0ydO3cu1K+flZWlDRs2qE+fPgr85jehefPmWrNmTY7XTsjMzFRmZubJn5/479eZ3hcA3CIqKko+n++s7+MLBoPBc32iQCCgmJiYkAUDAABA/vj9fkVHR5/1ffJU7CJxYhcIBFSjRg2lpaWd8zcR7uWG73N2tjRggPT007aTSL/88oueeeYZjR8/Xn/+85/15JNPqk6dOmH9mj/88IPq1q2rFStWqFGjRidfHzt2rGbPnq1//etfp33M7yd2P/zwgxo1aqRvvvlGF110UVjzwh43/PuMgovk73NeJnZ5ehTr8/ki7jfvhOjo6Ij9Z48kTv4+Z2dLJUpITohXrFgx3XrrrcrKytILL7yg999/X0lJSRo+fLiiwnQeS6lSpVS0aFEdPHgwx/coEAioWrVq+fq+RUVFOfb7jNBx8r/PCB2+z2fG5gkAZzVp0iR1795dV155pWJiYtSqVSt98sknSkpK0oQJE7Rp0yZdfvnl2rBhQ1i+fokSJdSgQQOtWLEix+srVqzQtddeG5avCQBulaeJHYDINXLkSDVu3Fj333+/GjdurIYNG6pkyZInf71bt24aNWqUunTpoi1btoQlQ3Jysu699141bNhQTZo00eTJk5WamqrExMSwfD0AcCuKXS5KliypYcOG5fgDDN7jlu/zrl1mV6yNpw55Oceue/fuGjp0aNgy3HXXXfrf//6nJ554Qj/88IOuuOIKLV26VBdffHGePv7E99fp32cUjFv+fUbB8H0+uzxtngBgT3a2VLy4tHmzVL++7TRnFgwGtWbNGjVv3tx2lDM6sbM/LzvKAMDNWGMHoMB8Pp9jSx0ARBKKHeACNWvaTgAAcAOKHeBwxYpJ/fvbTgEAcAOKHeASy5fbTgAAcDqKHeAS8+fbTgAAcDqKXT5kZmYqLi5OPp9PmzZtsh0HIbRz5051795dtWvXVunSpVWnTh0NGzZMWVlZtqNJki66SCpb1nYKd5owYYLq/7qduFmzZvroo48sJ0KopaSkKD4+XlFRUYqNjVW7du20detW27EQRikpKfL5fOrbt6/tKI5DscuH/v37q1q1arZjIAy+/fZbHT9+XC+//LK+/vprPfvss5o0aZIGDx5sO5okqV076ZJLbKdwnzlz5qhv377q16+fJKlJkya6+eablZqaajkZQmn16tVKSkrS2rVrtWLFCmVnZ6t169Y6fPiw7WgIg/Xr12vy5Mm68sorbUdxJM6xy6Nly5YpOTlZ8+fPV7169fTFF18oLi7OdiyE0dixYzVx4kTt2LHDdhRJUlycNGCA1LGj7STukZCQoGuuuUZjxow5eY5dQkKC2rVrp5SUFNvxECb79u1TbGysVq9erWbNmtmOgxA6dOiQrrnmGk2YMEEjRoxQXFycnnvuOduxHIWJXR7s3btXPXv21Ouvv64yZcrYjoNC4vf7VbFiRdsxTqpaVTp61HYK98jKytK//vUvtW7dOsfrrVu31qeffmopFQqD3++XJEf9+4vQSEpKUps2bdSqVSvbURyLYncOwWBQXbp0UWJioho2bGg7DgrJ9u3bNX78eEfdRfrYY9Kzz9pO4R4ZGRk6duyYqlSpkuP1KlWqaM+ePZZSIdyCwaCSk5PVtGlTXXHFFbbjIIRmz56tjRs3Mm0/h4gtdsOHD5fP5zvr24YNGzR+/HgFAgENGjTIdmSch7x+n38rPT1dN910kzp06KAePXpYSn5m335rO4H7+Hy+HD8PBoOnvQbv6NWrlzZv3qxZs2bZjoIQSktL08MPP6wZM2aoVKlStuM4WsSuscvIyFBGRsZZ36dWrVq6++67tXjx4hx/EBw7dkxFixZVp06dNH369HBHRQHk9ft84j8U6enpatGihRISEjRt2jQVKeKcv/scPy516ybdfrt022220zhfVlaWypQpo7lz56ply5Yn19gNHTpUmzZt0urVq21HRIj17t1bCxcu1Jo1a1S7dm3bcRBCCxcuVPv27VW0aNGTrx07dkw+n09FihRRZmZmjl+LZBFb7PIqNTVVgUDg5M/T09N14403at68eUpISFD16tUtpkMo7d69Wy1atFCDBg00Y8YMR/5H4r77pEqVeCSbVwkJCWrQoIFGjx59stg1btxYbdu25XGOhwSDQfXu3VsLFizQqlWr9Mc//tF2JITYwYMHtWvXrhyvde3aVXXr1tWAAQN47P4bxWwHcLqav7uks1y5cpKkOnXqUOo8JD09XTfccINq1qypcePGad++fSd/rWrVqhaT5TRwoNSvnxQISNHRttM4X3Jysu69917Vq1dPkjRw4EClpqY6au0kCi4pKUlvvPGG3n77bUVFRZ1cQxkTE6PSpUtbTodQiIqKOq28lS1bVpUqVaLU/Q7FDpC0fPlybdu2Tdu2bTutsDtpqF27tvTee1J6OsUuL+666y7973//0+jRoyVJn376qZYuXaqLL77YcjKE0sSJEyVJN9xwQ47Xp06dqi5duhR+IMAiHsUCLvPss9JPP0lPPGE7iXsEAoGTj2KjacQAPMw5K8MB5EnNmtKKFRIndgAAfo9iB7jMHXeYid2HH9pOAgBwGood4ELPPSctWmQ7BQDAaSh2gAvFxUn79km7d9tOAgBwEood4EJVq0qtWknPP287CQDASdgVC7iU3y/VqCFt2WI2VCB37IoFECmY2AEuFR0tDRkide9uOwkAwCkodoBL+XxSu3bm2JPPPrOdBgDgBBQ7wMUuvVTq00fq1ct2EgCAE1DsAJdr0UL6+Wdp1CjbSQAAtlHsAJf7wx9MqZs7V9q/33YaZ5k1a5ZKlSql9PT0k6/16NFDV155pfx+v8VkABAe7IoFPCArS+rZU4qNlcaOtZ3GOYLBoOLi4pSQkKApU6Zo4MCBmjFjhtauXauLLrqoULN8/LF06NDpr1eqJMXHF2oUAB5GsQM8IiNDatxYuvdeadgw22mc45133tEdd9yhrKwslS9fXh9//LHq1asXtq/31lvm8OjNm6WVK0+9vmOHdN110p/+ZH7+/vvmtTJlzLE1klS7ttkQI0n33SeVLh22mAA8imIHeMjSpabYvfmm1LKl7TTOcdVVV2nz5s1asmSJbrnllpB8zuxs8+j73/+W3ntPWr9e+u47qX17MzmtX98cIv1bxYtLxYqZH2dlSceOnfq1tWvN7uaDB6VXXzW7niVznM1DD0lVqkglSoQkOgAPo9gBHrNggfTYY+bRX0yM7TT2vffee2rXrp2OHDmi9evXq2HDhgX6fGlp0urV0ttvSzt3SnXrSjfdJDVsaHYph0pqqvTOO9LUqdLGjdINN0j/939Sjx5S0aKh+zoAvIViB3hMZqaUmCgdOSI9+6y5fixSbdy4UTfccIPGjRunBx98UG3bttXChQvz/Xm+/lpavFj64APpssuk226TypeXGjQIeeQz+uwzac4cackSqXJlqWNH6ZZbzMYZAPgtih3gQX6/KXfVqknjxp16rBdJdu7cqSZNmqh3797q1auXYn4dX27YsEENztHIgkHzNmWKKXTx8dIFF5j1b9WqFUL4XPz0k3nk262bdPiwNHOmmRYW4XwDAL+i2AEetX27dP/9UpMm0ujRkfX4bv/+/bruuuvUrFkzvfzyyyfvir355pt1/Phxvfvuu2f8uAMHpC++MBsbtm+XOnWSbr21cLPn1apVZv1dZqY0YYKZIgIAxQ7wsD17pEaNzIL+4cOlChVsJ7LjRLHz+/2Kjo4+7dc//1xauNAUuyZNpL/8RbrwwkKPeV7mzjW3j/ToYb7P11xjOxEAmyh2gMelp0tdu5pdmB9+aDuNHWcqdnv35lw3166d2cnqRqmp0tCh5niVzp3NhBZAZKLYAREgK0tq29Yct/H665G3W/ZEsdu926/PPovWokVmInfbbVJcnDlLzgu2bjWP30uXlqZPl2rWtJ0IQGFjyS0QAUqUkGbPNo9iGzaMrMndL7+YXa2S1Lu3FAiY0jN6tHTttd4pdZI5buWTT6R69aTrr5fmzbOdCEBhY2IHRJiJE83dsg88IA0e7N1NFVu2mONB9u6VKlcOaMiQ3NfYedG8eVJysnT33eYmkrJlbScCUBgodkAE+vJLsxbr55/NFKtvX9uJQufll6V33zXr5u67T6pVS8rKOvvmCa9KS5PuusschzJtGufeAZGAYgdEqOxs6auvzJqsatWk114zZ7UVL247Wd5lZ5t7WbdulZYtMxtFOnSQbr455z/HuXbFetmxY2ZH9IQJ0owZ5vcGgHdR7IAI99NP0oAB0ooVUtOmUlKS1Lix7VS5y8oyV2xt2yZt2mRei483V25VqXLmj4nkYnfCihXmWJRp06SEBNtpAIQLxQ6AJLMWbcQIsy4tNla6916pTRvzKNO2I0fM3aw7dkg//GCyPvigObOtfPlzfzzFzkw3J0wwm0b+/nfzBsB7KHYAcjhwwNxNOnOm9N57ZhrWubN0551mrVaxYuH72sGgdPSo+fHSpWYqN326mSS2amV2sVaoIJUqlb/PS7E7Zd06c65h587SwIGRed0c4GUUOwC5OnpUmjzZlKuMDHP+3bXXSn/966mF+BdeKJUrl//P7fdLP/5ofrxpk7kiq1IladYss+mhYkXp6qvN1ysoil1OP/9s1iI2aiT168eOWcBLKHYA8uToUTPBk8yNDdu3m40LJUqcvrYtMTHnVO3NN83GhhPq1jWL+r/6ykwB+/Qxr8fFSdWrhz47xe50330ndeliyvqyZbbTAAgVih2A8xYISLt25f/jqlUz07nCQrE7s0BAGjvWrFl8/nlzYwUAd6PYAfA8il3uAgHzWHbfPjNZ5aw7wN24UgwAIlh0tHnE/uc/m80Ue/faTgSgICh2AAANGGDW2/3jH6d2JgNwH4odAEAXXCBNmmTW2d1yi/T997YTATgfFDsAgCRzDdvEiVLNmtKTT0oHD9pOBCC/KHYAgJOKFDF3y/7wgzR4sDmWBoB7UOwAADnUqCHNmWMOpR4+3HYaAPlBsQMAnKZ0aXPryLZtptxlZ9tOBCAvKHYAgDOKipIef1xascKUO049BZwvjNd5AwDc7k9/kmbMkJo1M/f3JifbTgTgbCh2AICzql1bWr9eqldP+stfpPr1bScCkBsexQIAzqlqVWnZMumBB0zJA+BMFDsAQJ40aiQlJpp1d7t22U4D4EwodgCAPLv/fqlNG6lnT+nAAdtpAPwexQ4AkC+JiVLz5lLHjuyUBZyGYgcAyBefTxoyRMrKkp5+2nYaAL9FsQMAnJe5c6V335WmTLGdBMAJFDsAwHmpWNHcTrFggTRzpu00ACSKHQCgAC65RBo6VHrmGemrr2ynAUCxAwAUSJMm0n33SU88If3wg+00QGSj2AEACuzhh6VrrpGSkqTDh22nASIXxQ4AEBKPPGImdrNm2U4CRC6KHQAgJEqVkj76SHrnHenjj22nASITxQ4AEDLFipkz7jp3ltLSbKcBIg/FDgAQUvHx5naKPn1YbwcUNoodACDk+veXLrtM6tZNOn7cdhogclDsAAAhV6SINGqUtH279MorttMAkYNiBwAIm6VLzc0UO3bYTgJEBoodACBsYmOlJ5+UGjeW9u2znQbwPoodACCsThxcnJgoHT1qOw3gbRQ7AEBYFSkiDRsmpaZKr71mOw3gbRQ7AEChWLZMWrRI+u4720kA76LYAXCsnTt3qnv37qpdu7ZKly6tOnXqaNiwYcrKyrIdDeehcmWz3i4hQdq/33YawJuK2Q4AALn59ttvdfz4cb388sv6wx/+oC1btqhnz546fPiwxo0bZzsezsPVV0sDBkhdukhvvmmuIQMQOr5gMBi0HQIA8mrs2LGaOHGiduTj/IxAIKCYmBj5/X5FR0eHMR3yKiHBlLuHHrKdBPAWHsUCcBW/36+KFSue9X0yMzMVCARyvMFZli0zZ9x9843tJIC3UOwAuMb27ds1fvx4JSYmnvX9UlJSFBMTc/KtRo0ahZQQeVWxollv17+/dOiQ7TSAd1DsABS64cOHy+fznfVtw4YNOT4mPT1dN910kzp06KAePXqc9fMPGjRIfr//5FtaWlo4/3FwnuLipObNpY4dpZ9/tp0G8AbW2AEodBkZGcrIyDjr+9SqVUulfl1Zn56erhYtWighIUHTpk1TkSL5+zspa+ycjfV2QOiwKxZAoatcubIqV66cp/fdvXu3WrRooQYNGmjq1Kn5LnVwvvHjpQcflJo2lerXt50GcDcmdgAcKz09Xc2bN1fNmjX1z3/+U0WLFj35a1WrVs3z52Fi53zPPy+tXCnNny8VL247DeBeTOwAONby5cu1bds2bdu2TdWrV8/xa/yd1FseftjcI/vqq+ZOWQDnh4kdAM9jYuce7dpJI0ZIV1xhOwngTixWAQA4xuDB0qhRtlMA7kWxAwA4RqNGUny81KKFdPy47TSA+1DsAACO0q2buUN2wgTbSQD3YY0dAM9jjZ37pKZKDRpIq1dLl19uOw3gHkzsAACOU7OmNHy42SF79KjtNIB7UOwAAI6UlCTFxLCZAsgPih0AwLGeecacbbdli+0kgDtQ7AAAjvXHP0ojR0p/+5t0juuFAYhiBwBwuM6dpQoVpBdftJ0EcD6KHQDA0Xw+adw4adEis0sWQO4odgAAx/vjH6XkZOmhh2wnAZyNYgcAcIUOHaSrrpIefVTiBFbgzIrZDgAAQF6ULClNmyZVqya1bi01a2Y7EeA8TOwAAK5RsqQ0ebLUv7+0Z4/tNIDzUOwAAK5yxx3mmrERI2wnAZyHYgcAcJ1hw6TPPpOWL7edBHAWih0AwHUuvthcNZacLO3dazsN4BwUOwCAK7VsKV13nfTEE7aTAM5BsQMAuFKxYtKYMdLKldLSpbbTAM5AsQMAuFb58tKkSVJiou0kgDNQ7AAArnbDDdL990tvvGE7CWAfxQ4A4Hr9+0v//Cdn2wEUOwCA60VFSQMGSIMHS8eO2U4D2EOxAwB4QosWUmysNGWK7SSAPRQ7AIBnJCdLixZJ27bZTgLYQbEDAHhGbKy5auyRR6Sff7adBih8FDsAgKfExUkJCdKMGbaTAIWPYgcA8JQiRaRHHzVr7b780nYaoHBR7AAAnnTXXeaRLBBJKHYAAE/629/M9O7FF20nAQoPxQ4A4EllykjTp0tLlkiHDtlOAxQOih0AwLMuukhq31566SXbSYDCQbEDAHjaAw9ImzdLa9faTgKEH8UOAOB5gwZJo0ZJWVm2kwDhRbEDAHjeFVdIMTGm4HGXLLyMYgcAiAhjxkhvvSUdPmw7CRA+FDsAQESoVk16+mlz5RjgVRQ7AEDEuP12ad8+aelS20mA8KDYAQAiyrBh0gsvSHv22E4ChB7FDgAQUWrVknr1kgYOZCMFvIdiBwCIOPHx5my7JUtsJwFCi2IHAIg4VapIzz0nzZwpHTliOw0QOhQ7AEBEatbMXDk2a5btJEDoUOwAABHr0UelefOkf//bdhIgNCh2AICIVbGiKXf9+knHj9tOAxQcxQ4AENEuvVT65Rfp++9tJwEKjmIHAIhoFStKEydKDzwgHThgOw1QMBQ7AEDEu/RSs5nilVdsJwEKhmIHAIDMgcUffCB9/rntJMD5o9gBACCpSBGpbVtzKwXgVhQ7AAB+1amTOdtuwwbbSYDzQ7EDAOBX5cpJU6dKfftKP/5oOw2QfxQ7AAB+o0IF6Z57pKeftp0EyD+KHQAAv3PLLdKWLVJ6uu0kQP5Q7AAA+J1ataSuXaVhw2wnAfKHYgcAwBm0by8VKyYtXWo7CZB3vmAwGLQdAgDCKRAIKCYmRn6/X9HR0bbjwEWOHJGuvlpauVKqVs12GuDcmNgBAJCLEiWkli2l1attJwHyhmIHAEAuihSRRo40R6B8+63tNMC5UewAADiLmBhp8GBp0CDbSYBzo9gBAHAO9epJhw9L//2v7STA2VHsAAA4hwsuMAcW9+olHTxoOw2QO4odAAB5UK+e1KSJNH267SRA7ih2AADkQZEi0qOPSnPnShs22E4DnBnFDgCAfLj9dumdd2ynAM6MYgcAQD706CF99ZW0bp3tJMDpKHYAAORD2bLSiy9KfftKBw7YTgPkRLEDACCfKlaUqleXNm+2nQTIiWIHAEA+lSxpjj8ZNUpKT7edBjiFYgcAwHmoUUO6917p889tJwFOodgBAHCerrtOeuEF6aefbCcBDIodAADnqVYtacAA6ZFHpMxM22kAih0AAAXSsqVUqpS0f7/tJADFDgCAAileXLrrLmnwYOnoUdtpEOkodgAAFFCLFtIFF0jTptlOgkhHsQMAIARuv12aNMl2CkQ6ih0AACHQuLF0zz3ShAm2kyCSUewAAAiRnj2lBQukHTtsJ0GkotgBABAi0dHSHXeYjRSADRQ7AK6QmZmpuLg4+Xw+bdq0yXYcIFeJiZLPJ61bZzsJIhHFDoAr9O/fX9WqVbMdA8iTO++UHnrIdgpEIoodAMdbtmyZli9frnHjxtmOAuTJHXdI8fHSihW2kyDSFLMdAADOZu/everZs6cWLlyoMmXK5OljMjMzlfmb+50CgUC44gG5euwxqVs3c59sHv+vCxQYEzsAjhUMBtWlSxclJiaqYcOGef64lJQUxcTEnHyrUaNGGFMCZ1atmlS/vrR6te0kiCQUOwCFbvjw4fL5fGd927Bhg8aPH69AIKBBgwbl6/MPGjRIfr//5FtaWlqY/kmAs3vySWnsWGnnTttJECl8wWAwaDsEgMiSkZGhjIyMs75PrVq1dPfdd2vx4sXy+XwnXz927JiKFi2qTp06afr06Xn6eoFAQDExMfL7/YqOji5QdiC/3njDrLWbOtV2EkQCih0Ax0pNTc2xPi49PV033nij5s2bp4SEBFWvXj1Pn4diB5v27pW6dpXGj5fq1LGdBl7H5gkAjlWzZs0cPy9XrpwkqU6dOnkudYBtVapIgwZJ//iH9OabUjH+5EUYscYOAIAwa9pUuugiad8+20ngdRQ7AK5Rq1YtBYNBxcXF2Y4C5IvPJ3Xvbm6l4PQdhBPFDgCAQhAXJ119tfT117aTwMsodgAAFJJbb5WeeUbKzradBF5FsQMAoJA0aCA1ayY98YTEmRQIB4odAACFqE0bc6YdxQ7hQLEDAKAQXXKJNHq0NHy47STwIg4oBuB5HFAMJ6pYUVq50myoAEKFiR0AABa8+qq5bgwIJYodAAAWtG8vrVsnLV5sOwm8hGIHAIAlQ4ZIM2faTgEvodgBAGBJ69ZSVJQ0b57tJPAKih0AABY9+KA0Y4Z06JDtJPACih0AABY1aCBdeikbKRAaFDsAACzy+aTHH5c++0w6etR2GrgdxQ4AAMtKlZIuu0waN852ErgdxQ4AAAd44AEztQMKgmIHAIADlC8vtWsnjRxpOwncjCvFAHgeV4rBLX75RbrwQunzz82GCiC/mNgBAOAQpUtLkyZJr79uOwncimIHAICD3H23tHy5tGKF7SRwI4odAAAOM2SINGuW7RRwI4odAAAO07atlJ0tLVxoOwnchmIHAIAD9exppnY//2w7CdyEYgcAgANde61UrZo0f77tJHATih0AAA5UtKh0553SggVSVpbtNHALih0AAA513XXSVVdJixbZTgK3oNgBAOBgbdtKs2fbTgG3oNgBAOBgcXFSy5bS00/bTgI3oNgBAOBwd90lvfuu9NNPtpPA6Sh2AAA4XMWKUqdO0osv2k4Cp6PYAQDgAl26SOvXS99/bzsJnIxiBwCAS9xzjzRypO0UcDKKHQAALtGkifTdd1JGhu0kcCqKHQAALnHxxdLAgay1Q+4odgAAuEh8vLR2LVM7nBnFDgAAFylfXho8WOrf33YSOBHFDgAAl2nWTDpwQPryS9tJ4DQUOwAAXGjAAGnMGNsp4DQUOwAAXCghQQoGpXXrbCeBk/iCwWDQdggACKdAIKCYmBj5/X5FR0fbjgMAYUOxA+B5wWBQBw8eVFRUlHw+n+04ABA2FDsAAACPYI0dAACAR1DsAAAAPIJiBwAA4BEUOwAAAI+g2AEAAHgExQ4AAMAjKHYAAAAe8f+VRi39KYPzIgAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Autre courbe elliptique\n", "p4 = plot_implicit(Eq(y**2,x**3-x+1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La classification des courbes planes du troisième degré, commencée par Newton au XVIIème siècle, est [très compliquée](https://en.wikipedia.org/wiki/Cubic_plane_curve), et fait même encore l'objet de travaux récents.\n", " \n", "\n", "Pour simplifier les choses, les mathématiciens leur rajoutent deux sortes de points : les *points imaginaires* et les *points à l'infini*. La définition des points imaginaires est naturelle : on autorise les variables $x,y$ à prendre des valeurs complexes, et on voit donc la courbe comme un sous-ensemble de ${\\mathbb C}^2$. \n", "\n", "La définition des points à l'infini est un peu plus subtile : on imagine notre plan comme étant le plan $z=1$ dans l'espace à 3 dimensions, on remplace l'équation de la courbe par celle du cône d'origine O qui s'appuie sur elle, un polynôme homogène du troisième degré $\\hat P(x,y,z)=0$, tel que $\\hat P(x,y,1)=P(x,y)$. \n", "\n", "Par exemple, pour la courbe elliptique $y^2+x^3+x=0$, on a l'équation (dite projective) $y^2z+x^3+xz^2=0$. On identifie deux triplets $(x,y,z)$ et $(x′,y′,z′)$ s'il sont proportionnels : $(x′,y′,z′)=(ax,ay,az)$. L'ensemble des classes de triplets non nuls de nombres complexes est appelé *plan projectif complexe*. Ceux pour lesquels $z\\not=0$ correspondent aux points ordinaires de notre courbe. Ceux pour lesquels $z=0$ sont nouveaux, ce sont les points à l'infini. \n", "\n", "\n", "Pourquoi cette construction ? L'introduction des points imaginaires permet d'éliminer les discussions sur le nombre de racines des équations. Celle des points à l'infini élimine la question des asymptotes. Par exemple, la classification projective des courbes du second degré ne contient plus que trois cas. En effet, un polynôme homogène de degré 2 peut soit ne pas se factoriser (une conique), soit être un produit de deux polynômes du premier degré distincts (deux droites sécantes), soit enfin être le carré d'un polynôme du premier degré (une droite double). Au niveau projectif, il n'y a plus de distinction entre les trois types de coniques. Si on choisit une projection (par exemple le plan $z=1$) pour regarder la courbe, alors, elle pourra ne pas avoir de point à l'infini réel (ellipse), en avoir un (parabole) ou deux (hyperbole). On ne distingue pas non plus les droites sécantes ou parallèles (les parallèles se coupent à l'infini), etc. Donc, en [géométrie projective](https://fr.wikipedia.org/wiki/G%C3%A9om%C3%A9trie_projective), c'est beaucoup plus simple.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pourquoi elliptiques ?\n", "\n", "C'est parce qu'elles sont paramétrables par des fonctions\n", "spéciales appelées [fonctions elliptiques](http://fr.wikipedia.org/wiki/Fonction_elliptique)\n", "(il restera à expliquer le nom de ces fonctions).\n", "\n", "Dans un sens, les fonctions elliptiques généralisent les fonctions\n", "circulaires. Les coniques sont paramétrables par des fonctions\n", "circulaires (ou hyperboliques), par exemple une ellipse sera\n", "$x=a\\cos\\theta, y=b\\sin\\theta$. \n", "On ne les appelle pas pour autant\n", "courbes circulaires, car elles sont en fait paramétrables par des\n", "fonctions *rationnelles* :\n", "si $t=\\tan\\frac{\\theta}{2}$, on a $\\cos\\theta=\\frac{1-t^2}{1+t^2}$ et $\\sin\\theta=\\frac{2t}{1+t^2}$\n", ". On les\n", "appelle donc *courbes rationnelles*.\n", "\n", "Il n'y a pas que les coniques qui soient rationnelles. Certaines cubiques le sont aussi.\n", "Par exemple, en posant $y=tx$ dans l'équation du folium de Descartes, on trouve $(t^3+1)x^3 = 3atx^2$\n", "et on a donc le paramètrage $x = \\frac{3at}{t^3+1}$, $y=\\frac{3at^2}{t^3+1}$. De même, la parabole semi-cubique\n", "se paramètre par $x=t^2$, $y=t^3$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Et les fonctions elliptiques, alors ?\n", "\n", "Leur nom vient du fait qu'elles peuvent être définies comme les\n", "fonctions réciproques des [intégrales elliptiques](http://fr.wikipedia.org/wiki/Intégrale_elliptique), qui ont enfin quelque chose à voir avec les ellipses : si on essaie de calculer la longueur d'un arc d'ellipse,\n", "on tombe sur une intégrale elliptique. \n", "\n", "\n", "\n", "Il y a plusieurs versions de\n", "la théorie des fonctions elliptiques. La plus utilisée en physique\n", "ou en ingénierie est [celle de Jacobi](https://fr.wikipedia.org/wiki/Fonction_elliptique_de_Jacobi).\n", "\n", "Elle permet d'exprimer les solutions de nombreuses équations différentielles, comme celle des grandes oscillations du\n", "pendule, par exemple (et la période est alors donnée par une intégrale elliptique)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mais la version qui nous intéresse pour la cryptographie est [celle de Weierstrass](http://fr.wikipedia.org/wiki/Fonction_elliptique_de_Weierstrass).\n", "\n", "Sachant, de par les travaux de ses prédécesseurs, que les extensions au plan complexe des fonctions elliptiques sont doublement périodiques : \n", "elles vérifient \n", "$$f(z+n\\omega_1+m\\omega_2)=f(z)$$\n", "pour tous $(m,n)\\in{\\mathbb Z}^2$ et tout $z\\in{\\mathbb C}$ pour lequel\n", "$f(z)$ est défini, où $\\omega_1,\\omega_2$ sont deux nombres complexes dont le rapport n'est pas réel, \n", "Weierstrass s'est demandé s'il existait un moyen simple de construire directement de telles fonctions doublement périodiques. Son raisonnement est bien expliqué dans l'article de Wikipédia. L'idée est de partir d'une fonction\n", "quelconque $f$ et de former la somme infinie\n", "$$F(z)=\\sum_{m,n\\in{\\mathbb Z}} f(z+n\\omega_1+m\\omega_2)$$\n", "\n", "\n", "Si la série converge, $F$ sera doublement périodique. Il faut donc que $f$ tende assez vite vers 0 à l'infini. La construction\n", "marche avec $f(z)=z^{-3}$, mais on peut faire mieux en bricolant un peu la série associée à $f(z)=z^{-2}$. Telle quelle, elle ne\n", "converge pas, mais en retranchant à chaque terme son équivalent asymptotique, on peut montrer que ça marche encore. Le résultat est\n", "la fameuse fonction \n", "$$\\wp(z) = {1\\over z^2} + {\\sum_{(n_1,n_2)\\not = (0,0)}}\\left[\n", "{1\\over (z+n_1\\omega_1+n_2\\omega_2)^2} - {1\\over\n", "(n_1\\omega_1+n_2\\omega_2)^2}\\right]$$\n", "\n", "(le caractère $\\wp$ n'appartient à aucune police connue, il a été\n", "réalisé spécialement pour Weierstrass)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut maintenant rentrer dans le vif du sujet. En développant chaque terme de la série en série de puissances de $z$, on peut montrer que la fonction $\\wp$ vérifie l'équation différentielle\n", "\n", "$$\\wp'(z)^2=4\\wp(z)^3-g_2\\wp(z)-g_3$$\n", "\n", "où $g_2=60G_4$ et $g_3=140G_6$, avec\n", "\n", "$$G_k={\\sum_{(m,n)\\not=(0,0)}}{1\\over (m\\omega_1+n\\omega_2)^k}$$\n", "\n", "et\n", "\n", "$$\\wp(z)={1\\over z^2}+\\sum_{k\\ge 2}(2k-1)G_{2k}(\\tau)z^{2k-2}$$\n", "\n", "Donc, $x=\\wp(t), y=\\wp'(t)$ fournit directement un paramétrage de la courbe elliptique \n", "$$y^2=4x^3-g_2x-g_3$$ \n", "Un peu de géométrie projective élémentaire permet de montrer que toute courbe elliptique admet une équation de cette forme dans un repère approprié. La fonction de Weierstrass fournit donc une méthode simple et élégante pour paramétrer les courbes elliptiques par des fonctions elliptiques.\n", "\n", "Elle montre en particulier qu'on peut *additionner* les points\n", "d'une courbe elliptique ! Si $P_1 = (\\wp(t_1),\\wp'(t_1))$ et\n", "$P_2=(\\wp(t_2),\\wp'(t_2))$, on peut poser \n", "\n", "$$P_1\\oplus P_2 = (\\wp(t_1+t_2),\\wp'(t_1+t_2))$$\n", "\n", "Cette opération définit une structure de groupe commutatif sur la\n", "courbe. \n", "\n", "On peut vérifier que géométriquement, la somme est le\n", "symétrique par rapport à l'axe horizontal du troisième point\n", "d'intersection de la droite passant par $P_1,P_2$ avec la courbe\n", "(c'est souvent présenté comme la définition de l'addition sur la\n", "courbe, ce qui n'est pas franchement naturel...), et que l'élément\n", "neutre est son point à l'infini.\n", "\n", "Il reste à la calculer (c'est le théorème d'addition pour la\n", "fonction $\\wp$). Ce n'est pas évident, mais on aboutit à un\n", "résultat intéressant : les coordonnées (projectives) de $P_1\\oplus P_2$ sont\n", "des fonctions rationnelles à coefficients entiers des\n", "coordonnées de $P_1$ et $P_2$ :\n", "\n", "Si l'on pose\n", "$$s = \\frac{y_2-y_1}{x_2-x_1}$$\n", "les coordonnées $(x_3,y_3)$ de $P_1\\oplus P_2$ sont\n", "$$\n", "x_3 = s^2-x_1-x_2\n", "$$\n", "$$\n", "y_3 = s(x_1-x_3) - y_1.\n", "$$\n", "Il faut traiter séparément le cas où $P_1=P_2$. Les fomules sont les mêmes, mais avec\n", "$$s = \\frac{3x_1^2+a}{2y_1.}$$\n", "\n", "On trouvera le calcul ici.

\n", "En fait, le théorème d'addition pour la fonction $\\wp$ s'obtient en remarquant que si $t_3$ est le paramètre du troisème point d'intersection $P_3$ de la droite $(P_1P_2)$ avec la courbe, alors $t_1+t_2+t_3\\in{\\mathbb Z}\\omega_1\\oplus{\\mathbb Z}\\omega_2$.\n", "C'est une conséquence simple de résultats généraux sur les zéros et les pôles d'une fonction elliptique.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Courbes elliptiques sur les corps finis\n", "\n", "On peut donc appliquer les formules d'addition à la courbe modulo un nombre\n", "premier $p$, c'est à dire à l'ensemble des solutions de\n", "l'équation projective dans $({\\mathbb Z}/p{\\mathbb Z})^3$. Dans\n", "les bons cas, on obtiendra un très grand groupe dans lequel le\n", "problème du logarithme discret est encore beaucoup plus difficile\n", "que dans un corps fini (à cause de la non-linéarité des fomules\n", "d'addition). \n", "\n", "Le [système proposé](http://en.wikipedia.org/wiki/Elliptic_curve_cryptography)\n", "(indépendamment par Koblitz et Miller) est\n", "donc essentiellement un ElGamal dans le groupe d'une courbe\n", "elliptique modulo un grand nombre premier. Par rapport au RSA, il\n", "permet d'avoir des clés plus courtes à sécurité équivalente.\n", "\n", "On notera que, si la description du RSA est relativement simple, le\n", "choix des clés n'est pas trivial. Pour les courbes elliptiques,\n", "c'est encore plus complexe. Il est donc recommandé d'utiliser les\n", "courbes proposées dans divers standards.\n", "\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "from ent3 import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Par exemple, la courbe elliptique\n", "$$y^2=x^3+x$$\n", "sur ${\\mathbb F}_{23}={\\mathbb Z}/{\\mathbb 23 Z}$ est formée des couples d'entiers modulo 23 suivants :" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(0, 0), (1, 5), (1, 18), (9, 5), (9, 18), (11, 10), (11, 13), (13, 5), (13, 18), (15, 3), (15, 20), (16, 8), (16, 15), (17, 10), (17, 13), (18, 10), (18, 13), (19, 1), (19, 22), (20, 4), (20, 19), (21, 6), (21, 17)]\n" ] }, { "data": { "text/plain": [ "23" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "C = [(x,y) for x in range(23) for y in range(23) if (pow(y,2,23)-pow(x,3,23)-x) %23==0]\n", "print(C)\n", "len(C)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "E = (1,0,23) # On donne a,b,p" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 18)" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ellcurve_add(E,(11,13), (19,1))" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = (1-13)*inversemod(19-11,23) % 23;s" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(s*s - 11 - 19)%23" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "18" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(s*(11-1)-13) %23" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cette courbe est d'ordre 24 (avec le point à l'infini, de coordonnées homogènes $(0:1:0)$). " ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Identity (1, 5) (0, 0) (1, 18) Identity (1, 5) (0, 0) (1, 18) Identity (1, 5) (0, 0) (1, 18) Identity (1, 5) (0, 0) (1, 18) Identity (1, 5) (0, 0) (1, 18) Identity (1, 5) (0, 0) " ] } ], "source": [ "G = (1,5)\n", "for i in range(23): print(ellcurve_mul(E, i,G), end=' ')" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Identity (11, 13) (13, 5) (15, 3) (9, 5) (19, 1) (1, 18) (17, 13) (18, 10) (20, 4) (16, 15) (21, 6) (0, 0) (21, 17) (16, 8) (20, 19) (18, 13) (17, 10) (1, 5) (19, 22) (9, 18) (15, 20) (13, 18) (11, 10) Identity " ] } ], "source": [ "# Le groupe est cyclique malgré tout\n", "G = (11,13)\n", "for i in range(25): print(ellcurve_mul(E, i,G), end=' ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Le code pour manipuler les courbes elliptiques n'est pas compliqué. Voici la formule d'addition :" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "\n", "def ellcurve_add(E, P1, P2):\n", " \"\"\"\n", " Returns the sum of P1 and P2 on the elliptic \n", " curve E.\n", " Input:\n", " E -- an elliptic curve over Z/pZ, given by a \n", " triple of integers (a, b, p), with p odd.\n", " P1 --a pair of integers (x, y) or the \n", " string \"Identity\".\n", " P2 -- same type as P1\n", " Output:\n", " R -- same type as P1\n", " Examples:\n", " >>> E = (1, 0, 7) # y**2 = x**3 + x over Z/7Z\n", " >>> P1 = (1, 3); P2 = (3, 3)\n", " >>> ellcurve_add(E, P1, P2)\n", " (3, 4)\n", " >>> ellcurve_add(E, P1, (1, 4))\n", " 'Identity'\n", " >>> ellcurve_add(E, \"Identity\", P2)\n", " (3, 3)\n", " \"\"\" \n", " a, b, p = E\n", " assert p > 2, \"p must be odd.\"\n", " if P1 == \"Identity\": return P2\n", " if P2 == \"Identity\": return P1\n", " x1, y1 = P1; x2, y2 = P2\n", " x1 %= p; y1 %= p; x2 %= p; y2 %= p\n", " if x1 == x2 and y1 == p-y2: return \"Identity\"\n", " if P1 == P2:\n", " if y1 == 0: return \"Identity\"\n", " lam = (3*x1**2+a) * inversemod(2*y1,p)\n", " else:\n", " lam = (y1 - y2) * inversemod(x1 - x2, p)\n", " x3 = lam**2 - x1 - x2\n", " y3 = -lam*x3 - y1 + lam*x1\n", " return (x3%p, y3%p)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Testons sur la courbe P-256 du NIST :" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "a = 115792089210356248762697446949407573530086143415290314195533631308867097853948\n", "b = 41058363725152142129326129780047268409114441015993725554835256314039467401291\n", "p = 2**256-2**224+2**192+2**96-1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Son équation est \n", "$$y^2=x^3+ax+b\\ {\\rm mod}\\ p$$\n", "\n", "Voici un point de la courbe :" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "xP=48439561293906451759052585252797914202762949526041747995844080717082404635286\n", "yP=36134250956749795798585127919587881956611106672985015071877198253568414405109" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pow(yP,2,p) == (pow(xP,3,p) + a*xP + b) % p" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Et un autre :" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "xQ=91120319633256209954638481795610364441930342474826146651283703640232629993874\n", "yQ=80764272623998874743522585409326200078679332703816718187804498579075161456710\n", "\n", "pow(yQ,2,p) == (pow(xQ,3,p) + a*xQ + b) % p" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(90311347416124380843053629782909799863811022113695181534556410735564918416699,\n", " 4439786493922664689351604000024584586041837813305394846042624716681282749942)" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "E = (a,b,p)\n", "P = (xP,yP)\n", "Q = (xQ,yQ)\n", "ellcurve_add(E,P,Q)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il faut aussi définir la multiplication $P\\rightarrow nP$ par un entier :" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "def ellcurve_mul(E, m, P):\n", " \"\"\"\n", " Returns the multiple m*P of the point P on \n", " the elliptic curve E.\n", " Input:\n", " E -- an elliptic curve over Z/pZ, given by a \n", " triple (a, b, p).\n", " m -- an integer\n", " P -- a pair of integers (x, y) or the \n", " string \"Identity\"\n", " Output:\n", " A pair of integers or the string \"Identity\".\n", " Examples:\n", " >>> E = (1, 0, 7)\n", " >>> P = (1, 3)\n", " >>> ellcurve_mul(E, 5, P)\n", " (1, 3)\n", " >>> ellcurve_mul(E, 9999, P)\n", " (1, 4)\n", " \"\"\" \n", " assert m >= 0, \"m must be nonnegative.\"\n", " power = P\n", " mP = \"Identity\"\n", " while m != 0:\n", " if m%2 != 0: mP = ellcurve_add(E, mP, power)\n", " power = ellcurve_add(E, power, power)\n", " m //= 2\n", " return mP\n" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(56515219790691171413109057904011688695424810155802929973526481321309856242040,\n", " 3377031843712258259223711451491452598088675519751548567112458094635497583569)" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ellcurve_mul(E,2,P)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il n'est pas évident de calculer le nombre de points de cette courbe. Le système sage connaît des algorithmes sophistiqués :\n", "\n", "```Python\n", "sage: E = EllipticCurve([GF(p)(0),0,0,a,b])\n", "sage: E.abelian_group()\n", "Additive abelian group isomorphic to Z/115792089210356248762697446949407573529996955224135760342422259061068512044369 embedded in Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 115792089210356248762697446949407573530086143415290314195533631308867097853948*x + 41058363725152142129326129780047268409114441015993725554835256314039467401291 over Finite Field of size 115792089210356248762697446949407573530086143415290314195533631308867097853951\n", "```\n", "Ainsi cette courbe est d'ordre\n", "$$q=115792089210356248762697446949407573529996955224135760342422259061068512044369$$\n", "\n", "C'est un nombre premier. Donc, le groupe de la courbe est cyclique, et il existe un entier $m$\n", "tel que $Q=mP$.\n", "\n", "Il est en pratique impossible de le calculer, mais la question de savoir si $m$\n", "n'avait pas été choisi par la NSA a fait [beaucoup jaser](https://en.wikipedia.org/wiki/Dual_EC_DRBG#cite_note-blog.0xbadc0de.be-31) il y a quelques années.\n", "\n", "Ce sera l'objet du dernier TD.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Paramètres de domaine\n", "\n", "Les paramètres à fourinir sont les suivants. Le nombre premier $p$\n", "qui définit le corps de base, les coefficients a et b de l'équation $y^2=x^3+ax+b$, un point $G$ générateur d'un grand sous-groupe, et son ordre $n$, en général premier. Le théorème de Lagrange entraîne que le nombre $h=\\frac1n|E({\\mathbb F}_p)|$ est un entier. On demande que ce nombre, appelé le cofacteur, soit petit $h≤4$) et de préférence h=1\n", "\n", "Les paramètres de domaine sont donc $(p,a,b,G,n,h)$.\n", "\n", "\n", "\n", "Il n'est pas facile de calculer le nombre de points de la courbe, ni de vérifier l'abscence de faiblesses éventuelles. On utilise donc en général des courbes standardisées." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il n'est pas évident de calculer le nombre de points de la courbe. Le système `sage` connaît des algorithmes sophistiqués :\n", "```sage\n", "sage: E = EllipticCurve([GF(p)(0),0,0,a,b])\n", "sage: E.abelian_group()\n", "Additive abelian group isomorphic to Z/115792089210356248762697446949407573529996955224135760342422259061068512044369 embedded in Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 115792089210356248762697446949407573530086143415290314195533631308867097853948*x + 41058363725152142129326129780047268409114441015993725554835256314039467401291 over Finite Field of size 115792089210356248762697446949407573530086143415290314195533631308867097853951\n", "```\n", "\n", "Ainsi cette courbe est d'ordre\n", "$$q = 115792089210356248762697446949407573529996955224135760342422259061068512044369 $$\n", "\n", "C'est un nombre premier. Donc, le groupe de la courbe est cyclique, et il existe un entier $m$ tel que $Q=mP$.\n", "\n", "Il est en pratique impossible de le calculer, mais la question de savoir si $m$ n'avait pas été choisi par la NSA a fait [beaucoup jaser](https://en.wikipedia.org/wiki/Dual_EC_DRBG#cite_note-blog.0xbadc0de.be-31) il y a quelques années.\n", "\n", "Ce sera l'objet du dernier TD.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Le cryptosystème\n", "\n", "Avec les paramètres publics, ci-dessus, la clé secrète d'un utilisateur est un entier $m$, et sa clé publique le point $P=mG$.\n", "\n", "Les messages à chiffrer doivent être représentés par des points $M$ de la courbe.\n", "\n", "Pour chiffrer $M$, on tire au hasard un entier $k$, et on calcule \n", "$$(C_1,C_2)=(kG,M\\oplus kP)$$\n", "\n", "Pour déchiffrer : \n", "$$M=C_2\\ominus mC_1.$$\n", "\n", "### ECDH (Elliptic Curve Diffie-Hellemann)\n", "\n", "A envoie $aG$ à $B$, $B$ envoie $bG$ à A, et les deux calculent $K=abG$.\n", "\n", "\n", "### ECDSA (Elliptic Curve Digital Signature Algorithm)\n", "#### Signature\n", "\n", "Pour signer un hachage $h$,\n", "- choisir de manière aléatoire un nombre $k$ entre 1 et $n−1$\n", "- calculer $(i,j)=kG$\n", "- calculer $x = i\\mod n$; si $x=0$ revenir à la première étape\n", "- calculer $y=k^{−1}(h+sx)\\mod n$; si $y=0$ revenir à la première étape\n", "\n", "La signature est le couple $(x,y)$.\n", "\n", "\n", "#### Vérification\n", "- vérifier que $P$ est différent de $O$\n", "- Vérifier que $nP$ donne $O$\n", "- contrôler que $x$ et $y$ sont bien entre 1 et $n−1$\n", "- calculer $(i,j)=(hy^{−1}\\mod n)G+(xy^{−1}\\mod n)P$\n", "- vérifier que $x=i\\mod n$.\n", "\n", "\n", "\n", "### Exemple\n", "\n", "Détails de la vérification de la signature du faux pass sanitaire d'Hitler.\n", "\n", "On reprend la clé publique et la signature sur le document précédent.\n" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgu/WJBn1Q+RCOfQx3NLT5oIGUCHsqSRXuu7EZsqfqZN5PvHk6/E++88wvj2fMrfmAptk5tVld2xBH4P4tRs8JQ==\n", "VerifyingKey.from_string(b'\\x03\\x82\\xef\\xd6$\\x19\\xf5C\\xe4B9\\xf41\\xdc\\xd2\\xd3\\xe6\\x82\\x06P!\\xec\\xa9$W\\xba\\xee\\xc4f\\xca\\x9f\\xa9\\x93', NIST256p, sha256)\n" ] } ], "source": [ "import ecdsa\n", "keypem = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgu/WJBn1Q+RCOfQx3NLT5oIGUCHsqSRXuu7EZsqfqZN5PvHk6/E++88wvj2fMrfmAptk5tVld2xBH4P4tRs8JQ=='\n", "\n", "vk = ecdsa.VerifyingKey.from_pem(keypem, hashfunc=ecdsa.util.sha256)\n", "print(keypem)\n", "print(vk)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'\\xf8\\xe4=~\\x98\\x0c\\xc6\\x18\\x91\\xe2\\t\\xfc\\x8e\\xa8C\\x0b\\xd3\\xe8\\x8a\\xe1\\xee\\xda\\x9e1*\\xe1\\xce^\\xfa\\xf2,E\\x164o\\xef\\t\\xaf\\x00WY\\x9e\\xa6\\xb0N\\xa7\\xe2\\xb0\\xf0\\xbb\\xb0x\\x020\\xe0\\xfa\\xf0\\xe7\\xaf\\xaa\\x9e\\xabj]'\n" ] } ], "source": [ "sg = b'\\xf8\\xe4=~\\x98\\x0c\\xc6\\x18\\x91\\xe2\\t\\xfc\\x8e\\xa8C\\x0b\\xd3\\xe8\\x8a\\xe1\\xee\\xda\\x9e1*\\xe1\\xce^\\xfa\\xf2,E\\x164o\\xef\\t\\xaf\\x00WY\\x9e\\xa6\\xb0N\\xa7\\xe2\\xb0\\xf0\\xbb\\xb0x\\x020\\xe0\\xfa\\xf0\\xe7\\xaf\\xaa\\x9e\\xabj]'\n", "print(sg)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "112576851998912693404353932021788403678010647881836694883786474447117814475845\n", "10043531254491885728639917010112825819310590278507613083131603450074657155677\n" ] } ], "source": [ "# ordre de la courbe\n", "q=115792089210356248762697446949407573529996955224135760342422259061068512044369\n", "x,y = ecdsa.util.sigdecode_string(sg,q)\n", "print(x)\n", "print(y)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'\\x84jSignature1M\\xa2\\x01&\\x04H\\xe7qN\\x8d\\x7f\\xf8h\\x9b@X\\xe2\\xa4\\x01dCNAM\\x04\\x1ae)\\xbd\\xe0\\x06\\x1aaw*\\xfe9\\x01\\x03\\xa1\\x01\\xa4av\\x81\\xaabcix\\x1dURN:UVCI:01:FR:T5DWTJYS4ZR8#4bcobFRbdn\\x02bdtj2021-10-01bisdCNAMbmamORG-100030215bmplEU/1/20/1528bsd\\x02btgi840539006bvpgJ07BX03cdobj1900-01-01cnam\\xa4bfnfHITLERbgneADOLFcfntfHITLERcgnteADOLFcvere1.3.0'\n" ] } ], "source": [ "# le message à signer\n", "msg = b'\\x84jSignature1M\\xa2\\x01&\\x04H\\xe7qN\\x8d\\x7f\\xf8h\\x9b@X\\xe2\\xa4\\x01dCNAM\\x04\\x1ae)\\xbd\\xe0\\x06\\x1aaw*\\xfe9\\x01\\x03\\xa1\\x01\\xa4av\\x81\\xaabcix\\x1dURN:UVCI:01:FR:T5DWTJYS4ZR8#4bcobFRbdn\\x02bdtj2021-10-01bisdCNAMbmamORG-100030215bmplEU/1/20/1528bsd\\x02btgi840539006bvpgJ07BX03cdobj1900-01-01cnam\\xa4bfnfHITLERbgneADOLFcfntfHITLERcgnteADOLFcvere1.3.0'\n", "print(msg)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La courbe NIST-P256 a pour équation \n", "$$y^2=x^3+ax+b\\mod p$$\n", "avec \n", "$$p=p_{256}=2^{256}−2^{224}+2^{192}+2^{96}−1$$\n", "et les valeurs de $a$ et $b$ ci-dessous :" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "p = 2**256 - 2**224 + 2**192 + 2**96 - 1\n", "a = 115792089210356248762697446949407573530086143415290314195533631308867097853948\n", "b = 41058363725152142129326129780047268409114441015993725554835256314039467401291\n", " # Nombre de points de la courbe\n", "q = 115792089210356248762697446949407573529996955224135760342422259061068512044369\n", " # Génerateur\n", "xG = 48439561293906451759052585252797914202762949526041747995844080717082404635286\n", "yG = 36134250956749795798585127919587881956611106672985015071877198253568414405109" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "59224424711316661084877973301841821584140021680113528472675651838972371380627\n", "54841068689176540860306147861276004028606373898471432794562118907413910993957\n" ] } ], "source": [ "# La clef publique est un point $P=kG$, $k$ est la clé secrète.\n", "xP = vk.pubkey.point.x()\n", "yP = vk.pubkey.point.y()\n", "print(xP); print(yP)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [], "source": [ "# conventions de ent3.py\n", "E = (a,b,p)\n", "G = (xG,yG)\n", "P = (xP,yP)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "40852368101005595805886344965825869156100034153287450520391396900461008874188" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# le hachage à signer, converti en entier\n", "import codecs\n", "H = ecdsa.util.sha256(msg).digest()\n", "h = int(codecs.encode(H,'hex'),16); h" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Identity'" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# IL est clair que P!=O, et on vérifie qP=O\n", "ellcurve_mul(E,q,P)" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# On vérifie que x et y sont bien < q\n", "0