diff --git a/TTM4135.ipynb b/TTM4135.ipynb index 26da398..da75faf 100644 --- a/TTM4135.ipynb +++ b/TTM4135.ipynb @@ -46,7 +46,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -245,14 +245,14 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "1105 is composite\n" + "1105 is probable prime\n" ] } ], @@ -283,21 +283,93 @@ ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# Miller-Rabin\n", - "n = 137\n", - "k = 20\n", + "## Miller-Rabin\n", + "From https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test \n", + "This test is not fooled by Charmichael numbers.\n", "\n", + "To test `n`, you choose different `a` values, and test if \n", + "\n", + "> $a^{d*2^i} \\equiv 1 \\pmod{n}$ for $i = (0, 1, 2, ... r)$\n", + "\n", + "If this happens, look at the congruence on the calculation just before you got `1`. If that value is not -1 (aka n-1), the value is composite aka not prime." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "168 = 21*2^3 = 168\n", + "65536 = 1*2^16 = 65536\n", + "\n", + "16127 is probably prime.\n", + "561 is composite.\n", + "2465 is composite.\n", + "65537 is probably prime.\n" + ] + } + ], + "source": [ + "# Miller-Rabin primality test\n", + "# This test is not fooled by Charmichael numbers.\n", + "\n", + "from math import log2, floor\n", "from random import randint\n", - "def miller_rabin(n):\n", - " for O in range(k):\n", - " d = n-1\n", - " a = randint(2,n-2)\n", - " x = (a**d) % " + "\n", + "def decompose_even_number(n):\n", + " '''Find the values r and d such that n == d * 2**r.'''\n", + " r = 0\n", + " d = n\n", + " for i in range(1, floor(log2(n)) + 1):\n", + " if (d/2).is_integer():\n", + " d = d/2\n", + " r += 1\n", + " else:\n", + " break\n", + " return (r, int(d))\n", + "\n", + "verbose = False # Print during execution\n", + "\n", + "def miller_rabin_prime(n):\n", + " ''':param n: should be odd, and n>3. No primes can be even, for obvious reasons.'''\n", + " accuracy = 3 # How many different `a` to test\n", + " r, d = decompose_even_number(n-1) # n is odd, thus n-1 is even\n", + " verbose and print(f\"Testing {n} a maximum of {accuracy} times...\")\n", + " \n", + " for _ in range(accuracy):\n", + " try:\n", + " a = randint(2, n-2) # The \"witness\". TODO: don't reuse a witness.\n", + " verbose and print(f\"\\tTesting {n} with a={a}\")\n", + "\n", + " x = (a**d) % n\n", + " if x == 1 or x == n-1:\n", + " verbose and print(f\"\\t({a}**{d})%{n} was 1 or -1 already!\")\n", + " continue # This witness was immediately 1 or -1 (aka n-1), so it can't help us any more.\n", + " for squaring in range(r-1):\n", + " x = (x**2) % n\n", + " verbose and print(f\"\\tx={x}\")\n", + " if x == n-1:\n", + " raise Exception(\"Try next witness\") # This witness can't help any more.\n", + " return \"composite\" # The witness didnt uphold the criteria for a prime, so n is composite!\n", + " except Exception as tryNext:\n", + " continue\n", + " return \"probably prime\"\n", + " \n", + "s, d = decompose_even_number(168)\n", + "print(f\"168 = {d}*2^{s} = {d*(2**s)}\")\n", + "s, d = decompose_even_number(65536)\n", + "print(f\"65536 = {d}*2^{s} = {d*(2**s)}\")\n", + "print()\n", + "\n", + "for value in [16127, 561, 2465, 65537]:\n", + " print(f\"{value} is {miller_rabin_prime(value)}.\")\n" ] }, { @@ -371,7 +443,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -428,7 +500,7 @@ "print(f\"y = g^x mod p ==> {y} = {g}^{x} mod {p}\")\n", "\n", "# Don't run the test with big numbers!\n", - "if x < 10000: print(f\"Test: {disc_log_test(y,g,x,p)}\")" + "if x<10000: print(f\"Test: {disc_log_test(y,g,x,p)}\")" ] }, { @@ -446,13 +518,6 @@ "- `P = D(C, K)`: Decryption function" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 10, @@ -501,5 +566,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 }