{
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "<img src=\"data:image/png;base64,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GRThCmArK6n/07KSrSxnapER1Yj5OD39Th0AXBsAX0XT01P7pqe/HkKavQdAR+aMLpcYFtHvB3ASusZQ0AL/Yv8AzygF6bJ+DZEAAAGeaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA1LjQuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjEyMTU8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MjI0PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Civ/7UsAAEAASURBVHgB7L0FnJzXee//s5aZGcUrZrDYIMtsy2zLlp2kmP7btI3btElumqQpJOn9F5IUchuQbMmxjDHIKNkii3HFsFpm5lmQ7/MceXsNknZ2d+DMzO/ks1l5Z+Z9z/s9Z973nAd+z3UfSwMbCZAACZAACZAACZAACZAACZAACZAACZAACfghgVF+eE28JBIgARIgARIgARIgARIgARIgARIgARIgARIwBGj84kQgARIgARIgARIgARIgARIgARIgARIgARLwWwI0fvnt0PLCSIAESIAESIAESIAESIAESIAESIAESIAEaPziHCABEiABEiABEiABEiABEiABEiABEiABEvBbAjR++e3Q8sJIgARIgARIgARIgARIgARIgARIgARIgARo/OIcIAESIAESIAESIAESIAESIAESIAESIAES8FsCNH757dDywkiABEiABEiABEiABEiABEiABEiABEiABGj84hwgARIgARIgARIgARIgARIgARIgARIgARLwWwI0fvnt0PLCSIAE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\" width=\"100%\" alt=\"Cryptographie et sécurité\" />"
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# TP3. Cryptographie appliquée\n",
        "\n",
        "Dans ce TP nous travaillerons en Python 3, directement à l'intérieur de ce notebook jupyter.\n",
        "\n",
        "Nous avons choisi d'utiliser la bibliothèque [PyCryptodome](http://www.pycryptodome.org/). Pour rejouer cette fiche en dehors du TP, il  convient d'installer une version récente de [PyCryptodome](http://www.pycryptodome.org/) sur votre système.\n",
        "\n",
        "L'objectif du TP est d'expérimenter des éléments vus en cours et en TD dans deux cas pratique. Ces deux exemples sont inspirés du Challenge de crypto 2019/2020."
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## 1. Chiffrement de VPN avec IPSec\n",
        "\n",
        "[IPsec](http://fr.wikipedia.org/wiki/Internet_Protocol_Security) offre un mécanisme normalisé et donc interopérable de chiffrement des données en mode host-to-host ou lan-to-lan (avec tunnel). L'ensemble des RFCs décrivant IPsec est touffu, on se contentera de lire dans un premier temps la [page Wikipedia IPsec](http://en.wikipedia.org/wiki/IPsec) et dans un second temps seulement [An Illustrated Guide to IPsec](http://www.unixwiz.net/techtips/iguide-ipsec.html).\n",
        "\n",
        "Le protocole [IKE](https://fr.wikipedia.org/wiki/Internet_Key_Exchange) permet de négocier les paramètres de connexion. C'est la bonne manière d'utiliser IPSec. Dans ce TP, afin de nous focaliser sur le mécanisme de chiffrement des paquets, nous avons opté pour une configuration statique du VPN en manipulant directement la configuration noyau à l'aide de la commande `ip`.\n",
        "\n",
        "Dans cet exercice, il s'agit de comprendre les grands principes d'IPSec afin de décoder des échanges réseau chiffrés à partir de la connaissance des paramètres cryptographiques utilisés. En effet, l'avantage d'un protocole normalisé est d'être débugable, ici à l'aide de [Wireshark](https://www.wireshark.org).\n"
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "Téléchargez le [fichier pcap](https://pdicost.univ-orleans.fr/cryptodm/micmac.php?user=110&data=7&apikey=ee6d2b7a1338ded6267165f91b5a860643f5df5442e2885584b17841d8e7bb6f) à ouvrir dans Wireshark."
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "L'objectif est de pouvoir accéder au contenu en clair des paquets comme sur la copie d'écran ci-dessous.\n",
        "\n",
        "PS. Le fichier pcap correspond à une écoute sur toutes les interfaces d'un routeur intermédiaire, chaque trame apparait donc dupliquée. Pour que ce soit plus lisible, vous pouvez par exemple utiliser le même filtre que sur la copie d'écran.\n",
        "\n",
        "![une fois déchiffré](https://pdicost.univ-orleans.fr/cryptodm/micmac.php?user=110&data=8&apikey=037f1e32a51ef99c259f0271c0d6366fa136ce7e1e8b615317969f70a6ca572c)"
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "Voici le script qui a été utilisé pour configurer un des routeurs qui mettent en place le tunnel IPSec.\n",
        "\n",
        "\n",
        "```bash\n",
        "#!/bin/sh\n",
        "####### STATE\n",
        "ip xfrm state flush\n",
        "ip xfrm state add src 100.10.10.10 dst 100.20.20.20 \\\n",
        "\tproto esp spi 0x539 mode tunnel \\\n",
        "\tenc \"cbc(aes)\" \"micmac is sha256\" \\\n",
        "\tauth-trunc \"hmac(md5)\" \"(K+M) which is v\" 96\n",
        "ip xfrm state add src 100.20.20.20 dst 100.10.10.10 \\\n",
        "\tproto esp spi 0x539 mode tunnel \\\n",
        "\tenc \"cbc(aes)\" \"ulnerable to len\" \\\n",
        "\tauth-trunc \"hmac(md5)\" \"gth extension at\" 96\n",
        "###### POLICY\n",
        "ip xfrm policy flush\n",
        "ip xfrm policy add src 192.168.2.0/24 dst 192.168.1.0/24 \\\n",
        "\tdir fwd tmpl src 100.20.20.20 dst 100.10.10.10 \\\n",
        "\t\tproto esp mode tunnel\n",
        "ip xfrm policy add src 192.168.2.0/24 dst 192.168.1.0/24 \\\n",
        "\tdir in tmpl src 100.20.20.20 dst 100.10.10.10 \\\n",
        "\t\tproto esp mode tunnel\n",
        "ip xfrm policy add src 192.168.1.0/24 dst 192.168.2.0/24 \\\n",
        "\tdir out tmpl src 100.10.10.10 dst 100.20.20.20 \\\n",
        "\t\tproto esp mode tunnel\n",
        "\n",
        "```"
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "En vous aidant de la [documentation de Wireshark sur l'écoute IPSec](https://gitlab.com/wireshark/wireshark/-/wikis/ESP_Preferences), déchiffrez l'échange TCP entre Alice et Bob !"
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## 2. Qu'est-ce que c'est que ce micmac ?\n",
        "\n",
        "Observez les URLs utilisées pour obtenir le fichier pcap et les copies d'écran ci-dessus, par exemple `https://pdicost.univ-orleans.fr/cryptodm/micmac.php?user=110&data=8&apikey=037f1e32a51ef99c259f0271c0d6366fa136ce7e1e8b615317969f70a6ca572c`\n",
        "\n",
        "Elles sont servies par un script PHP dont voici le code source :\n"
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "```\n",
        "<?php\n",
        "  //////////////////////////////////////////////////\n",
        "  // Da micmac (wanabe) secure data API.          //\n",
        "  // Share files that have been approved by user. //\n",
        "  //////////////////////////////////////////////////\n",
        "  function fail() { header('HTTP/1.0 403 Forbidden'); header('Content-Type: text/plain'); echo \"Access Denied\\n\"; exit; }\n",
        "  function get($k) { return isset($_GET[$k]) ? $_GET[$k] : fail(); }\n",
        "  // We want file $data for user $user with API key $apikey\n",
        "  $user=intval(get('user'));\n",
        "  $data=intval(get('data'));\n",
        "  $h=get('apikey');\n",
        "  // Fetch $user secret API generation key\n",
        "  $db=new SQLite3('/var/www/db/micmacdb');\n",
        "  $st=$db->prepare('SELECT secret FROM users WHERE user = :user');\n",
        "  $st->bindParam(':user',$user);\n",
        "  $res=$st->execute();\n",
        "  $secret=\"FAIL\";\n",
        "  while($x = $res->fetchArray(SQLITE3_NUM)) $secret=hex2bin($x[0]);\n",
        "  if (strlen($secret) !== 32) fail();\n",
        "  // Check if the API key is correct for that URL\n",
        "  $s=urldecode($_SERVER['QUERY_STRING']);\n",
        "  $pos=strpos($s, \"&apikey=\");\n",
        "  if ($pos !== false) {\n",
        "      $h=substr($s,$pos+8);\n",
        "      $s=substr($s,0,$pos);\n",
        "  }\n",
        "  $hh=hash('sha256',$secret . $s);\n",
        "  if (strcmp($h,$hh) !== 0) fail();\n",
        "  // Ok we are good, we can provide the data if it exists in the DB\n",
        "  $st=$db->prepare('SELECT mimetype FROM files WHERE rowid = :data');\n",
        "  $st->bindParam(':data',$data);\n",
        "  $res=$st->execute();\n",
        "  $mimetype=FALSE;\n",
        "  while($x = $res->fetchArray(SQLITE3_NUM)) { $mimetype=$x[0]; }\n",
        "  if ($mimetype === FALSE) fail();\n",
        "  $f=$db->openBlob('files', 'content', $data);\n",
        "  header('Content-Type: ' . $mimetype);\n",
        "  while(!feof($f)) echo fread($f,8192);\n",
        "  fclose($f);\n",
        "?>\n",
        "```"
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "Les URLs sont du type `https://pdicost.univ-orleans.fr/cryptodm/micmac.php?user=👩‍🦰&data=#️⃣&apikey=🍰` où le champ `apikey` contient en hexadécimal la valeur `SHA256(K+M)` avec `K` un secret de 32 octets et `M` la chaîne `user=👩‍🦰&data=#️⃣` (du caractère qui suit le `?` jusqu'au pied de `&apikey`).\n",
        "\n",
        "Comme nous l'avons vu en cours, une attaque par extension de longueur est possible sur `SHA256`. Ici, elle va nous permettre d'accéder à toutes les paires de valeur `(user,data)` que l'on souhaite en construisant des URLs de la forme : `https://pdicost.univ-orleans.fr/cryptodm/micmac.php?user=👩‍🦰&data=#️⃣PADDING&data=NOUVELLEVALEUR&apikey=NOUVEAUMICMAC`.\n",
        "\n",
        "À vous de jouer : trouvez une URL valide pour accéder à la ressource `data=3`.\n",
        "\n",
        "Pour vous aider dans votre tâche, voici le code source d'une mise en œuvre en Python de SHA256."
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "SHA_BLOCKSIZE = 64\n",
        "SHA_DIGESTSIZE = 32\n",
        "\n",
        "\n",
        "def new_shaobject():\n",
        "    return {\n",
        "        'digest': [0]*8,\n",
        "        'count_lo': 0,\n",
        "        'count_hi': 0,\n",
        "        'data': [0]* SHA_BLOCKSIZE,\n",
        "        'local': 0,\n",
        "        'digestsize': 0\n",
        "    }\n",
        "\n",
        "ROR = lambda x, y: (((x & 0xffffffff) >> (y & 31)) | (x << (32 - (y & 31)))) & 0xffffffff\n",
        "Ch = lambda x, y, z: (z ^ (x & (y ^ z)))\n",
        "Maj = lambda x, y, z: (((x | y) & z) | (x & y))\n",
        "S = lambda x, n: ROR(x, n)\n",
        "R = lambda x, n: (x & 0xffffffff) >> n\n",
        "Sigma0 = lambda x: (S(x, 2) ^ S(x, 13) ^ S(x, 22))\n",
        "Sigma1 = lambda x: (S(x, 6) ^ S(x, 11) ^ S(x, 25))\n",
        "Gamma0 = lambda x: (S(x, 7) ^ S(x, 18) ^ R(x, 3))\n",
        "Gamma1 = lambda x: (S(x, 17) ^ S(x, 19) ^ R(x, 10))\n",
        "\n",
        "def sha_transform(sha_info):\n",
        "    W = []\n",
        "    \n",
        "    d = sha_info['data']\n",
        "    for i in range(0,16):\n",
        "        W.append( (d[4*i]<<24) + (d[4*i+1]<<16) + (d[4*i+2]<<8) + d[4*i+3])\n",
        "    \n",
        "    for i in range(16,64):\n",
        "        W.append( (Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]) & 0xffffffff )\n",
        "    \n",
        "    ss = sha_info['digest'][:]\n",
        "    \n",
        "    def RND(a,b,c,d,e,f,g,h,i,ki):\n",
        "        t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i];\n",
        "        t1 = Sigma0(a) + Maj(a, b, c);\n",
        "        d += t0;\n",
        "        h  = t0 + t1;\n",
        "        return d & 0xffffffff, h & 0xffffffff\n",
        "    \n",
        "    ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],0,0x428a2f98);\n",
        "    ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],1,0x71374491);\n",
        "    ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],2,0xb5c0fbcf);\n",
        "    ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],3,0xe9b5dba5);\n",
        "    ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],4,0x3956c25b);\n",
        "    ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],5,0x59f111f1);\n",
        "    ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],6,0x923f82a4);\n",
        "    ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],7,0xab1c5ed5);\n",
        "    ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],8,0xd807aa98);\n",
        "    ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],9,0x12835b01);\n",
        "    ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],10,0x243185be);\n",
        "    ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],11,0x550c7dc3);\n",
        "    ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],12,0x72be5d74);\n",
        "    ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],13,0x80deb1fe);\n",
        "    ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],14,0x9bdc06a7);\n",
        "    ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],15,0xc19bf174);\n",
        "    ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],16,0xe49b69c1);\n",
        "    ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],17,0xefbe4786);\n",
        "    ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],18,0x0fc19dc6);\n",
        "    ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],19,0x240ca1cc);\n",
        "    ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],20,0x2de92c6f);\n",
        "    ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],21,0x4a7484aa);\n",
        "    ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],22,0x5cb0a9dc);\n",
        "    ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],23,0x76f988da);\n",
        "    ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],24,0x983e5152);\n",
        "    ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],25,0xa831c66d);\n",
        "    ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],26,0xb00327c8);\n",
        "    ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],27,0xbf597fc7);\n",
        "    ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],28,0xc6e00bf3);\n",
        "    ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],29,0xd5a79147);\n",
        "    ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],30,0x06ca6351);\n",
        "    ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],31,0x14292967);\n",
        "    ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],32,0x27b70a85);\n",
        "    ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],33,0x2e1b2138);\n",
        "    ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],34,0x4d2c6dfc);\n",
        "    ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],35,0x53380d13);\n",
        "    ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],36,0x650a7354);\n",
        "    ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],37,0x766a0abb);\n",
        "    ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],38,0x81c2c92e);\n",
        "    ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],39,0x92722c85);\n",
        "    ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],40,0xa2bfe8a1);\n",
        "    ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],41,0xa81a664b);\n",
        "    ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],42,0xc24b8b70);\n",
        "    ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],43,0xc76c51a3);\n",
        "    ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],44,0xd192e819);\n",
        "    ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],45,0xd6990624);\n",
        "    ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],46,0xf40e3585);\n",
        "    ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],47,0x106aa070);\n",
        "    ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],48,0x19a4c116);\n",
        "    ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],49,0x1e376c08);\n",
        "    ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],50,0x2748774c);\n",
        "    ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],51,0x34b0bcb5);\n",
        "    ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],52,0x391c0cb3);\n",
        "    ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],53,0x4ed8aa4a);\n",
        "    ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],54,0x5b9cca4f);\n",
        "    ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],55,0x682e6ff3);\n",
        "    ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],56,0x748f82ee);\n",
        "    ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],57,0x78a5636f);\n",
        "    ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],58,0x84c87814);\n",
        "    ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],59,0x8cc70208);\n",
        "    ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],60,0x90befffa);\n",
        "    ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],61,0xa4506ceb);\n",
        "    ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],62,0xbef9a3f7);\n",
        "    ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],63,0xc67178f2);\n",
        "    \n",
        "    dig = []\n",
        "    for i, x in enumerate(sha_info['digest']):\n",
        "        dig.append( (x + ss[i]) & 0xffffffff )\n",
        "    sha_info['digest'] = dig\n",
        "\n",
        "def sha_init():\n",
        "    sha_info = new_shaobject()\n",
        "    sha_info['digest'] = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19]\n",
        "    sha_info['count_lo'] = 0\n",
        "    sha_info['count_hi'] = 0\n",
        "    sha_info['local'] = 0\n",
        "    sha_info['digestsize'] = 32\n",
        "    return sha_info\n",
        "\n",
        "def sha_update(sha_info, buffer):\n",
        "    if isinstance(buffer, str):\n",
        "        raise TypeError(\"Unicode strings must be encoded before hashing\")\n",
        "    count = len(buffer)\n",
        "    buffer_idx = 0\n",
        "    clo = (sha_info['count_lo'] + (count << 3)) & 0xffffffff\n",
        "    if clo < sha_info['count_lo']:\n",
        "        sha_info['count_hi'] += 1\n",
        "    sha_info['count_lo'] = clo\n",
        "    \n",
        "    sha_info['count_hi'] += (count >> 29)\n",
        "    \n",
        "    if sha_info['local']:\n",
        "        i = SHA_BLOCKSIZE - sha_info['local']\n",
        "        if i > count:\n",
        "            i = count\n",
        "        \n",
        "        # copy buffer\n",
        "        sha_info['data'][sha_info['local']:sha_info['local']+i] = buffer[buffer_idx:buffer_idx+i]\n",
        "        \n",
        "        count -= i\n",
        "        buffer_idx += i\n",
        "        \n",
        "        sha_info['local'] += i\n",
        "        if sha_info['local'] == SHA_BLOCKSIZE:\n",
        "            sha_transform(sha_info)\n",
        "            sha_info['local'] = 0\n",
        "        else:\n",
        "            return\n",
        "    \n",
        "    while count >= SHA_BLOCKSIZE:\n",
        "        # copy buffer\n",
        "        sha_info['data'] = list(buffer[buffer_idx:buffer_idx + SHA_BLOCKSIZE])\n",
        "        count -= SHA_BLOCKSIZE\n",
        "        buffer_idx += SHA_BLOCKSIZE\n",
        "        sha_transform(sha_info)\n",
        "        \n",
        "    \n",
        "    # copy buffer\n",
        "    pos = sha_info['local']\n",
        "    sha_info['data'][pos:pos+count] = buffer[buffer_idx:buffer_idx + count]\n",
        "    sha_info['local'] = count\n",
        "\n",
        "def sha_final(sha_info):\n",
        "    lo_bit_count = sha_info['count_lo']\n",
        "    hi_bit_count = sha_info['count_hi']\n",
        "    count = (lo_bit_count >> 3) & 0x3f\n",
        "    sha_info['data'][count] = 0x80;\n",
        "    count += 1\n",
        "    if count > SHA_BLOCKSIZE - 8:\n",
        "        # zero the bytes in data after the count\n",
        "        sha_info['data'] = sha_info['data'][:count] + ([0] * (SHA_BLOCKSIZE - count))\n",
        "        sha_transform(sha_info)\n",
        "        # zero bytes in data\n",
        "        sha_info['data'] = [0] * SHA_BLOCKSIZE\n",
        "    else:\n",
        "        sha_info['data'] = sha_info['data'][:count] + ([0] * (SHA_BLOCKSIZE - count))\n",
        "    \n",
        "    sha_info['data'][56] = (hi_bit_count >> 24) & 0xff\n",
        "    sha_info['data'][57] = (hi_bit_count >> 16) & 0xff\n",
        "    sha_info['data'][58] = (hi_bit_count >>  8) & 0xff\n",
        "    sha_info['data'][59] = (hi_bit_count >>  0) & 0xff\n",
        "    sha_info['data'][60] = (lo_bit_count >> 24) & 0xff\n",
        "    sha_info['data'][61] = (lo_bit_count >> 16) & 0xff\n",
        "    sha_info['data'][62] = (lo_bit_count >>  8) & 0xff\n",
        "    sha_info['data'][63] = (lo_bit_count >>  0) & 0xff\n",
        "    \n",
        "    sha_transform(sha_info)\n",
        "    \n",
        "    dig = []\n",
        "    for i in sha_info['digest']:\n",
        "        dig.extend([ ((i>>24) & 0xff), ((i>>16) & 0xff), ((i>>8) & 0xff), (i & 0xff) ])\n",
        "    return bytes(dig)\n",
        "\n",
        "class sha256(object):\n",
        "    digest_size = digestsize = SHA_DIGESTSIZE\n",
        "    block_size = SHA_BLOCKSIZE\n",
        "\n",
        "    def __init__(self, s=None):\n",
        "        self.name = 'sha256'\n",
        "        self._sha = sha_init()\n",
        "        if s:\n",
        "            sha_update(self._sha, s)\n",
        "    \n",
        "    def update(self, s):\n",
        "        sha_update(self._sha, s)\n",
        "    \n",
        "    def digest(self):\n",
        "        return sha_final(self._sha.copy())[:self._sha['digestsize']]\n",
        "    \n",
        "    def hexdigest(self):\n",
        "        return ''.join(['%.2x' % i for i in self.digest()])\n",
        "\n",
        "    def copy(self):\n",
        "        new = sha256.__new__(sha256)\n",
        "        new._sha = self._sha.copy()\n",
        "        return new\n"
      ],
      "outputs": [],
      "execution_count": 1,
      "metadata": {
        "execution": {
          "iopub.execute_input": "2020-11-26T15:47:16.914Z",
          "iopub.status.busy": "2020-11-26T15:47:16.873Z",
          "iopub.status.idle": "2020-11-26T15:47:16.953Z",
          "shell.execute_reply": "2020-11-26T15:47:16.987Z"
        },
        "jupyter": {
          "outputs_hidden": false,
          "source_hidden": false
        },
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# exemple d'utilisation\n",
        "dgst=sha256(b\"The cake is a lie.\")\n",
        "print(dgst.hexdigest())\n",
        "print(\"État de l'algorithme :\",dgst._sha)"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0f802c63154b269693741bfd54ec01ab6b2a07abe748c46f60be1eb1a36a1729\n",
            "État de l'algorithme : {'digest': [1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225], 'count_lo': 144, 'count_hi': 0, 'data': [84, 104, 101, 32, 99, 97, 107, 101, 32, 105, 115, 32, 97, 32, 108, 105, 101, 46, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'local': 18, 'digestsize': 32}\n"
          ]
        }
      ],
      "execution_count": 4,
      "metadata": {
        "execution": {
          "iopub.execute_input": "2020-11-26T15:47:27.827Z",
          "iopub.status.busy": "2020-11-26T15:47:27.814Z",
          "iopub.status.idle": "2020-11-26T15:47:27.875Z",
          "shell.execute_reply": "2020-11-26T15:47:27.913Z"
        },
        "jupyter": {
          "outputs_hidden": false,
          "source_hidden": false
        },
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "Suggestion de plan de bataille :\n",
        " - écrire une fonction de padding `pad(msglen)` qui retourne le padding utilisé pour un message de longueur `msglen` ;\n",
        " - écrire une fonction `sha_cont(msglen,hexdgst)` qui, à partir d'une longueur de message `msglen` et d'une empreinte SHA256 `hexdgst` du message donnée en hexadécimal, retourne une instance de la classe `sha256` prête à recevoir de nouvelles `update` : toute l'astuce consiste à construire un dictionnaire `_sha` correspondant à l'état de l'algorithme après padding ;\n",
        " - en déduire une fonction `extend(msglen,hexdgst,more)` qui à partir de la longueur `msglen`, de l'empreinte `hexdgst` et d'une chaîne supplémentaire `more`, retourne la chaîne `pad(msglen)+more` et l'empreinte du message étendu par cette chaîne."
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "code",
      "source": [],
      "outputs": [],
      "execution_count": null,
      "metadata": {
        "collapsed": true,
        "jupyter": {
          "source_hidden": false,
          "outputs_hidden": false
        },
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    }
  ],
  "metadata": {
    "kernel_info": {
      "name": "python3"
    },
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3.6.12",
      "mimetype": "text/x-python",
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "pygments_lexer": "ipython3",
      "nbconvert_exporter": "python",
      "file_extension": ".py"
    },
    "nteract": {
      "version": "0.26.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 1
}