diff --git a/CB.EN.P2CSE19011-Diffie_Hellman_key_exchange.ipynb b/CB.EN.P2CSE19011-Diffie_Hellman_key_exchange.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..42d9ed9524ee993f41616727fe3de0a30fe468da
--- /dev/null
+++ b/CB.EN.P2CSE19011-Diffie_Hellman_key_exchange.ipynb
@@ -0,0 +1,729 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Code for Finding a large prime number (min 20-digit) "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from random import randrange, getrandbits\n",
+    "def is_prime(n, k=128):\n",
+    "    \"\"\" Test if a number is prime\n",
+    "        Args:\n",
+    "            n -- int -- the number to test\n",
+    "            k -- int -- the number of tests to do\n",
+    "        return True if n is prime\n",
+    "    \"\"\"\n",
+    "    # Test if n is not even.\n",
+    "    # But care, 2 is prime !\n",
+    "    if n == 2 or n == 3:\n",
+    "        return True\n",
+    "    if n <= 1 or n % 2 == 0:\n",
+    "        return False\n",
+    "    # find r and s\n",
+    "    s = 0\n",
+    "    r = n - 1\n",
+    "    while r & 1 == 0:\n",
+    "        s += 1\n",
+    "        r //= 2\n",
+    "    # do k tests\n",
+    "    for _ in range(k):\n",
+    "        a = randrange(2, n - 1)\n",
+    "        x = pow(a, r, n)\n",
+    "        if x != 1 and x != n - 1:\n",
+    "            j = 1\n",
+    "            while j < s and x != n - 1:\n",
+    "                x = pow(x, 2, n)\n",
+    "                if x == 1:\n",
+    "                    return False\n",
+    "                j += 1\n",
+    "            if x != n - 1:\n",
+    "                return False\n",
+    "    return True\n",
+    "def generate_prime_candidate(length):\n",
+    "    \"\"\" Generate an odd integer randomly\n",
+    "        Args:\n",
+    "            length -- int -- the length of the number to generate, in bits\n",
+    "        return a integer\n",
+    "    \"\"\"\n",
+    "    # generate random bits\n",
+    "    p = getrandbits(length)\n",
+    "    # apply a mask to set MSB and LSB to 1\n",
+    "    p |= (1 << length - 1) | 1\n",
+    "    return p\n",
+    "def generate_prime_number(length=60):\n",
+    "    \"\"\" Generate a prime\n",
+    "        Args:\n",
+    "            length -- int -- length of the prime to generate, in          bits\n",
+    "        return a prime\n",
+    "    \"\"\"\n",
+    "    p = 4\n",
+    "    # keep generating while the primality test fail\n",
+    "    while not is_prime(p, 128):\n",
+    "        p = generate_prime_candidate(length)\n",
+    "    return p\n",
+    "print(generate_prime_number())"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "610292520201647"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Code for finding Primitive root "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Smallest primitive root of 610292520201647 is 5\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Python3 program to find primitive root  \n",
+    "# of a given number n  \n",
+    "from math import sqrt \n",
+    "  \n",
+    "# Returns True if n is prime  \n",
+    "def isPrime( n):  \n",
+    "  \n",
+    "    # Corner cases  \n",
+    "    if (n <= 1): \n",
+    "        return False\n",
+    "    if (n <= 3): \n",
+    "        return True\n",
+    "  \n",
+    "    # This is checked so that we can skip  \n",
+    "    # middle five numbers in below loop  \n",
+    "    if (n % 2 == 0 or n % 3 == 0): \n",
+    "        return False\n",
+    "    i = 5\n",
+    "    while(i * i <= n): \n",
+    "        if (n % i == 0 or n % (i + 2) == 0) : \n",
+    "            return False\n",
+    "        i = i + 6\n",
+    "  \n",
+    "    return True\n",
+    "  \n",
+    "\"\"\" Iterative Function to calculate (x^n)%p \n",
+    "    in O(logy) */\"\"\"\n",
+    "def power( x, y, p):  \n",
+    "  \n",
+    "    res = 1 # Initialize result  \n",
+    "  \n",
+    "    x = x % p # Update x if it is more  \n",
+    "              # than or equal to p  \n",
+    "  \n",
+    "    while (y > 0):  \n",
+    "  \n",
+    "        # If y is odd, multiply x with result  \n",
+    "        if (y & 1): \n",
+    "            res = (res * x) % p  \n",
+    "  \n",
+    "        # y must be even now  \n",
+    "        y = y >> 1 # y = y/2  \n",
+    "        x = (x * x) % p  \n",
+    "  \n",
+    "    return res  \n",
+    "  \n",
+    "# Utility function to store prime \n",
+    "# factors of a number  \n",
+    "def findPrimefactors(s, n) : \n",
+    "  \n",
+    "    # Print the number of 2s that divide n  \n",
+    "    while (n % 2 == 0) : \n",
+    "        s.add(2)  \n",
+    "        n = n // 2\n",
+    "  \n",
+    "    # n must be odd at this po. So we can   \n",
+    "    # skip one element (Note i = i +2)  \n",
+    "    for i in range(3, int(sqrt(n)), 2): \n",
+    "          \n",
+    "        # While i divides n, print i and divide n  \n",
+    "        while (n % i == 0) : \n",
+    "  \n",
+    "            s.add(i)  \n",
+    "            n = n // i  \n",
+    "          \n",
+    "    # This condition is to handle the case  \n",
+    "    # when n is a prime number greater than 2  \n",
+    "    if (n > 2) : \n",
+    "        s.add(n)  \n",
+    "\n",
+    "def findPrimitive( n) : \n",
+    "    s = set()  \n",
+    "  \n",
+    "    # Check if n is prime or not  \n",
+    "    if (isPrime(n) == False):  \n",
+    "        return -1\n",
+    "  \n",
+    "    # Find value of Euler Totient function  \n",
+    "    # of n. Since n is a prime number, the  \n",
+    "    # value of Euler Totient function is n-1  \n",
+    "    # as there are n-1 relatively prime numbers. \n",
+    "    phi = n - 1\n",
+    "  \n",
+    "    # Find prime factors of phi and store in a set  \n",
+    "    findPrimefactors(s, phi)  \n",
+    "  \n",
+    "    # Check for every number from 2 to phi  \n",
+    "    for r in range(2, phi + 1):  \n",
+    "  \n",
+    "        # Iterate through all prime factors of phi.  \n",
+    "        # and check if we found a power with value 1  \n",
+    "        flag = False\n",
+    "        for it in s:  \n",
+    "  \n",
+    "            # Check if r^((phi)/primefactors) \n",
+    "            # mod n is 1 or not  \n",
+    "            if (power(r, phi // it, n) == 1):  \n",
+    "  \n",
+    "                flag = True\n",
+    "                break\n",
+    "              \n",
+    "        # If there was no power with value 1.  \n",
+    "        if (flag == False): \n",
+    "            return r  \n",
+    "  \n",
+    "    # If no primitive root found  \n",
+    "    return -1\n",
+    "\n",
+    "n = 610292520201647\n",
+    "print(\"Smallest primitive root of\",n, \"is\", findPrimitive(n)) "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Code for Diffie–Hellman"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "g:  3  (a shared value), n:  610292520201647  (a prime number)\n",
+      "\n",
+      "Alice calculates:\n",
+      "a (Alice random):  37856\n",
+      "Alice value (A):  23079533594046  (g^a) mod p\n",
+      "\n",
+      "Bob calculates:\n",
+      "b (Bob random):  50018\n",
+      "Bob value (B):  69387698405719  (g^b) mod p\n",
+      "\n",
+      "Alice calculates:\n",
+      "Key:  573821206942293  (B^a) mod p\n",
+      "Key:  f4cb54ce1c55e40a6482af8ee396da4f565d243f4532ad83d006dcf526499322\n",
+      "\n",
+      "Bob calculates:\n",
+      "Key:  573821206942293  (A^b) mod p\n",
+      "Key:  f4cb54ce1c55e40a6482af8ee396da4f565d243f4532ad83d006dcf526499322\n"
+     ]
+    }
+   ],
+   "source": [
+    "import random\n",
+    "import hashlib\n",
+    "import sys\n",
+    "\n",
+    "g=3\n",
+    "p=610292520201647\n",
+    "\n",
+    "a=random.randint(10000,99999)\n",
+    "\n",
+    "b=random.randint(10000,99999)\n",
+    "\n",
+    "A = (g**a) % p\n",
+    "B = (g**b) % p\n",
+    "\n",
+    "print('g: ',g,' (a shared value), n: ',p, ' (a prime number)')\n",
+    "\n",
+    "print('\\nAlice calculates:')\n",
+    "print('a (Alice random): ',a)\n",
+    "print('Alice value (A): ',A,' (g^a) mod p')\n",
+    "\n",
+    "print('\\nBob calculates:')\n",
+    "print('b (Bob random): ',b)\n",
+    "print('Bob value (B): ',B,' (g^b) mod p')\n",
+    "\n",
+    "print('\\nAlice calculates:')\n",
+    "keyA=(B**a) % p\n",
+    "print('Key: ',keyA,' (B^a) mod p')\n",
+    "print('Key: ',hashlib.sha256(str(keyA).encode()).hexdigest())\n",
+    "\n",
+    "print('\\nBob calculates:')\n",
+    "keyB=(A**b) % p\n",
+    "print('Key: ',keyB,' (A^b) mod p')\n",
+    "print('Key: ',hashlib.sha256(str(keyB).encode()).hexdigest())"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Code to Find an integer k such that  where a and m are relatively prime."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2\n",
+      "1\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Python3 program to calculate \n",
+    "# discrete logarithm \n",
+    "import math; \n",
+    "\n",
+    "# Iterative Function to calculate \n",
+    "# (x ^ y)%p in O(log y) \n",
+    "def powmod(x, y, p): \n",
+    "\n",
+    "\tres = 1; # Initialize result \n",
+    "\n",
+    "\tx = x % p; # Update x if it is more \n",
+    "\t\t\t# than or equal to p \n",
+    "\n",
+    "\twhile (y > 0): \n",
+    "\t\t\n",
+    "\t\t# If y is odd, multiply x with result \n",
+    "\t\tif (y & 1): \n",
+    "\t\t\tres = (res * x) % p; \n",
+    "\n",
+    "\t\t# y must be even now \n",
+    "\t\ty = y >> 1; # y = y/2 \n",
+    "\t\tx = (x * x) % p; \n",
+    "\treturn res; \n",
+    "\n",
+    "# Function to calculate k for given a, b, m \n",
+    "def discreteLogarithm(a, b, m): \n",
+    "\tn = int(math.sqrt(m) + 1); \n",
+    "\n",
+    "\tvalue = [0] * m; \n",
+    "\n",
+    "\t# Store all values of a^(n*i) of LHS \n",
+    "\tfor i in range(n, 0, -1): \n",
+    "\t\tvalue[ powmod (a, i * n, m) ] = i; \n",
+    "\n",
+    "\tfor j in range(n): \n",
+    "\t\t\n",
+    "\t\t# Calculate (a ^ j) * b and check \n",
+    "\t\t# for collision \n",
+    "\t\tcur = (powmod (a, j, m) * b) % m; \n",
+    "\n",
+    "\t\t# If collision occurs i.e., LHS = RHS \n",
+    "\t\tif (value[cur]): \n",
+    "\t\t\tans = value[cur] * n - j; \n",
+    "\t\t\t\n",
+    "\t\t\t# Check whether ans lies below m or not \n",
+    "\t\t\tif (ans < m): \n",
+    "\t\t\t\treturn ans; \n",
+    "\t\n",
+    "\treturn -1; \n",
+    "\n",
+    "# Driver code \n",
+    "a = 610292520201647; \n",
+    "b = 12542369; \n",
+    "m = 5; \n",
+    "print(discreteLogarithm(a, b, m)); \n",
+    "\n",
+    "a = 610292520201647; \n",
+    "b = 1852642; \n",
+    "m = 5; \n",
+    "print(discreteLogarithm(a, b, m)); \n",
+    "\n",
+    "# This code is contributed by mits \n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Applying this code to see how long it takes to break your chosen 3 keys. Record your observation as shown in the table(min 3 (p,g) values and for each (p,g) 3 private keys (weak, medium strong and strong) "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2\n",
+      "1\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Python3 program to calculate \n",
+    "# discrete logarithm \n",
+    "import math; \n",
+    "\n",
+    "# Iterative Function to calculate \n",
+    "# (x ^ y)%p in O(log y) \n",
+    "def powmod(x, y, p): \n",
+    "\n",
+    "\tres = 1; # Initialize result \n",
+    "\n",
+    "\tx = x % p; # Update x if it is more \n",
+    "\t\t\t# than or equal to p \n",
+    "\n",
+    "\twhile (y > 0): \n",
+    "\t\t\n",
+    "\t\t# If y is odd, multiply x with result \n",
+    "\t\tif (y & 1): \n",
+    "\t\t\tres = (res * x) % p; \n",
+    "\n",
+    "\t\t# y must be even now \n",
+    "\t\ty = y >> 1; # y = y/2 \n",
+    "\t\tx = (x * x) % p; \n",
+    "\treturn res; \n",
+    "\n",
+    "# Function to calculate k for given a, b, m \n",
+    "def discreteLogarithm(a, b, m): \n",
+    "\tn = int(math.sqrt(m) + 1); \n",
+    "\n",
+    "\tvalue = [0] * m; \n",
+    "\n",
+    "\t# Store all values of a^(n*i) of LHS \n",
+    "\tfor i in range(n, 0, -1): \n",
+    "\t\tvalue[ powmod (a, i * n, m) ] = i; \n",
+    "\n",
+    "\tfor j in range(n): \n",
+    "\t\t\n",
+    "\t\t# Calculate (a ^ j) * b and check \n",
+    "\t\t# for collision \n",
+    "\t\tcur = (powmod (a, j, m) * b) % m; \n",
+    "\n",
+    "\t\t# If collision occurs i.e., LHS = RHS \n",
+    "\t\tif (value[cur]): \n",
+    "\t\t\tans = value[cur] * n - j; \n",
+    "\t\t\t\n",
+    "\t\t\t# Check whether ans lies below m or not \n",
+    "\t\t\tif (ans < m): \n",
+    "\t\t\t\treturn ans; \n",
+    "\t\n",
+    "\treturn -1; \n",
+    "\n",
+    "# Driver code \n",
+    "a = 610292520201647; \n",
+    "b = 12542369; \n",
+    "m = 5; \n",
+    "print(discreteLogarithm(a, b, m)); \n",
+    "\n",
+    "a = 610292520201647; \n",
+    "b = 1852642; \n",
+    "m = 5; \n",
+    "print(discreteLogarithm(a, b, m)); \n",
+    "\n",
+    "# This code is contributed by mits "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "54\n",
+      "49\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Python3 program to calculate \n",
+    "# discrete logarithm \n",
+    "import math; \n",
+    "\n",
+    "# Iterative Function to calculate \n",
+    "# (x ^ y)%p in O(log y) \n",
+    "def powmod(x, y, p): \n",
+    "\n",
+    "\tres = 1; # Initialize result \n",
+    "\n",
+    "\tx = x % p; # Update x if it is more \n",
+    "\t\t\t# than or equal to p \n",
+    "\n",
+    "\twhile (y > 0): \n",
+    "\t\t\n",
+    "\t\t# If y is odd, multiply x with result \n",
+    "\t\tif (y & 1): \n",
+    "\t\t\tres = (res * x) % p; \n",
+    "\n",
+    "\t\t# y must be even now \n",
+    "\t\ty = y >> 1; # y = y/2 \n",
+    "\t\tx = (x * x) % p; \n",
+    "\treturn res; \n",
+    "\n",
+    "# Function to calculate k for given a, b, m \n",
+    "def discreteLogarithm(a, b, m): \n",
+    "\tn = int(math.sqrt(m) + 1); \n",
+    "\n",
+    "\tvalue = [0] * m; \n",
+    "\n",
+    "\t# Store all values of a^(n*i) of LHS \n",
+    "\tfor i in range(n, 0, -1): \n",
+    "\t\tvalue[ powmod (a, i * n, m) ] = i; \n",
+    "\n",
+    "\tfor j in range(n): \n",
+    "\t\t\n",
+    "\t\t# Calculate (a ^ j) * b and check \n",
+    "\t\t# for collision \n",
+    "\t\tcur = (powmod (a, j, m) * b) % m; \n",
+    "\n",
+    "\t\t# If collision occurs i.e., LHS = RHS \n",
+    "\t\tif (value[cur]): \n",
+    "\t\t\tans = value[cur] * n - j; \n",
+    "\t\t\t\n",
+    "\t\t\t# Check whether ans lies below m or not \n",
+    "\t\t\tif (ans < m): \n",
+    "\t\t\t\treturn ans; \n",
+    "\t\n",
+    "\treturn -1; \n",
+    "\n",
+    "# Driver code \n",
+    "a = 610292520201647; \n",
+    "b = 12542369; \n",
+    "m = 125; \n",
+    "print(discreteLogarithm(a, b, m)); \n",
+    "\n",
+    "a = 610292520201647; \n",
+    "b = 1852642; \n",
+    "m = 125; \n",
+    "print(discreteLogarithm(a, b, m)); \n",
+    "\n",
+    "# This code is contributed by mits "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "-1\n",
+      "-1\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Python3 program to calculate \n",
+    "# discrete logarithm \n",
+    "import math; \n",
+    "\n",
+    "# Iterative Function to calculate \n",
+    "# (x ^ y)%p in O(log y) \n",
+    "def powmod(x, y, p): \n",
+    "\n",
+    "\tres = 1; # Initialize result \n",
+    "\n",
+    "\tx = x % p; # Update x if it is more \n",
+    "\t\t\t# than or equal to p \n",
+    "\n",
+    "\twhile (y > 0): \n",
+    "\t\t\n",
+    "\t\t# If y is odd, multiply x with result \n",
+    "\t\tif (y & 1): \n",
+    "\t\t\tres = (res * x) % p; \n",
+    "\n",
+    "\t\t# y must be even now \n",
+    "\t\ty = y >> 1; # y = y/2 \n",
+    "\t\tx = (x * x) % p; \n",
+    "\treturn res; \n",
+    "\n",
+    "# Function to calculate k for given a, b, m \n",
+    "def discreteLogarithm(a, b, m): \n",
+    "\tn = int(math.sqrt(m) + 1); \n",
+    "\n",
+    "\tvalue = [0] * m; \n",
+    "\n",
+    "\t# Store all values of a^(n*i) of LHS \n",
+    "\tfor i in range(n, 0, -1): \n",
+    "\t\tvalue[ powmod (a, i * n, m) ] = i; \n",
+    "\n",
+    "\tfor j in range(n): \n",
+    "\t\t\n",
+    "\t\t# Calculate (a ^ j) * b and check \n",
+    "\t\t# for collision \n",
+    "\t\tcur = (powmod (a, j, m) * b) % m; \n",
+    "\n",
+    "\t\t# If collision occurs i.e., LHS = RHS \n",
+    "\t\tif (value[cur]): \n",
+    "\t\t\tans = value[cur] * n - j; \n",
+    "\t\t\t\n",
+    "\t\t\t# Check whether ans lies below m or not \n",
+    "\t\t\tif (ans < m): \n",
+    "\t\t\t\treturn ans; \n",
+    "\t\n",
+    "\treturn -1; \n",
+    "\n",
+    "# Driver code \n",
+    "a = 610292520201647; \n",
+    "b = 12542369; \n",
+    "m = 63456456; \n",
+    "print(discreteLogarithm(a, b, m)); \n",
+    "\n",
+    "a = 610292520201647; \n",
+    "b = 1852642; \n",
+    "m = 465464; \n",
+    "print(discreteLogarithm(a, b, m)); \n",
+    "\n",
+    "# This code is contributed by mits "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "MemoryError",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[1;31mMemoryError\u001b[0m                               Traceback (most recent call last)",
+      "\u001b[1;32m<ipython-input-2-e09ae1952765>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m     53\u001b[0m \u001b[0mb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m12542369\u001b[0m\u001b[1;33m;\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     54\u001b[0m \u001b[0mm\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m610292520201644\u001b[0m\u001b[1;33m;\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 55\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdiscreteLogarithm\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mb\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mm\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m;\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     56\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     57\u001b[0m \u001b[0ma\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m610292520201647\u001b[0m\u001b[1;33m;\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
+      "\u001b[1;32m<ipython-input-2-e09ae1952765>\u001b[0m in \u001b[0;36mdiscreteLogarithm\u001b[1;34m(a, b, m)\u001b[0m\n\u001b[0;32m     27\u001b[0m         \u001b[0mn\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmath\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msqrt\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mm\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m;\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     28\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 29\u001b[1;33m         \u001b[0mvalue\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0mm\u001b[0m\u001b[1;33m;\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     30\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     31\u001b[0m         \u001b[1;31m# Store all values of a^(n*i) of LHS\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
+      "\u001b[1;31mMemoryError\u001b[0m: "
+     ]
+    }
+   ],
+   "source": [
+    "# Python3 program to calculate \n",
+    "# discrete logarithm \n",
+    "import math; \n",
+    "\n",
+    "# Iterative Function to calculate \n",
+    "# (x ^ y)%p in O(log y) \n",
+    "def powmod(x, y, p): \n",
+    "\n",
+    "\tres = 1; # Initialize result \n",
+    "\n",
+    "\tx = x % p; # Update x if it is more \n",
+    "\t\t\t# than or equal to p \n",
+    "\n",
+    "\twhile (y > 0): \n",
+    "\t\t\n",
+    "\t\t# If y is odd, multiply x with result \n",
+    "\t\tif (y & 1): \n",
+    "\t\t\tres = (res * x) % p; \n",
+    "\n",
+    "\t\t# y must be even now \n",
+    "\t\ty = y >> 1; # y = y/2 \n",
+    "\t\tx = (x * x) % p; \n",
+    "\treturn res; \n",
+    "\n",
+    "# Function to calculate k for given a, b, m \n",
+    "def discreteLogarithm(a, b, m): \n",
+    "\tn = int(math.sqrt(m) + 1); \n",
+    "\n",
+    "\tvalue = [0] * m; \n",
+    "\n",
+    "\t# Store all values of a^(n*i) of LHS \n",
+    "\tfor i in range(n, 0, -1): \n",
+    "\t\tvalue[ powmod (a, i * n, m) ] = i; \n",
+    "\n",
+    "\tfor j in range(n): \n",
+    "\t\t\n",
+    "\t\t# Calculate (a ^ j) * b and check \n",
+    "\t\t# for collision \n",
+    "\t\tcur = (powmod (a, j, m) * b) % m; \n",
+    "\n",
+    "\t\t# If collision occurs i.e., LHS = RHS \n",
+    "\t\tif (value[cur]): \n",
+    "\t\t\tans = value[cur] * n - j; \n",
+    "\t\t\t\n",
+    "\t\t\t# Check whether ans lies below m or not \n",
+    "\t\t\tif (ans < m): \n",
+    "\t\t\t\treturn ans; \n",
+    "\t\n",
+    "\treturn -1; \n",
+    "\n",
+    "# Driver code \n",
+    "a = 610292520201647; \n",
+    "b = 12542369; \n",
+    "m = 610292520201644; \n",
+    "print(discreteLogarithm(a, b, m)); \n",
+    "\n",
+    "a = 610292520201647; \n",
+    "b = 1852642; \n",
+    "m = 610292520201644; \n",
+    "print(discreteLogarithm(a, b, m)); \n",
+    "\n",
+    "# This code is contributed by mits "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "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.7.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}