Add Miller-Rabin

This commit is contained in:
Johannes Røsvik 2020-05-23 15:28:54 +02:00
parent 2f78cfe3f1
commit abe2ae2f80
No known key found for this signature in database
GPG Key ID: 8A47E30339E13FFD
1 changed files with 89 additions and 24 deletions

View File

@ -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
}