Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

* Install the Python library ` pycryptodome ` by executing the following in a code cell. ` ` ` ! pip install pycryptodome ` `

* Install the Python library `pycryptodome` by executing the following in a code cell.
```
!pip install pycryptodome
```
* Import some functions we will use by executing the following code. (This will raise an error if `pycryptodome` hasn't been successfully installed.)
```
from Crypto.Util.number import getPrime, getRandomNBitInteger
from sympy.ntheory import n_order
from Lab2_Helper import (
only_letters,
weave,
shift_string,
add_spaces,
to_base_b,
from_base_b
)
```
def naive_dlog(g, h, p):
output =1
for i in range(p-1):
output = output*g%p
if output == h:
return i
return None
import string
import textwrap
def string_for_code_block(X, linewidth=60):
return '
'.join(textwrap.wrap(X, width=linewidth))
def add_spaces(X, width=5, linewidth=60):
one_line =''.join(textwrap.wrap(X, width=width))
many_lines = string_for_code_block(one_line, linewidth=linewidth)
return many_lines
def only_letters(X, case=None):
'''Returns the string obtained from X by removing everything but the letters.
If case="upper" or case="lower", then the letters are all
converted to the same case.'''
X =''.join(c for c in X if c in string.ascii_letters)
if len(X)==0:
return None
if case is None:
return X
elif case == "lower":
return X.lower()
elif case == "upper":
return X.upper()
def shift_char(ch, shift_amt):
'''Shifts a specific character by shift_amt.
Example:
shift_char("Y",3) returns "B"
'''
if ch in string.ascii_lowercase:
base ='a'
elif ch in string.ascii_uppercase:
base ='A'
# It's not clear what shifting should mean in other cases
# so if the character is not upper or lower-case, we leave it unchanged
else:
return ch
return chr((ord(ch)-ord(base)+shift_amt)%26+ord(base))
def shift_string(X, shift_amt):
'''Shifts all characters in X by the same amount.'''
return ''.join(shift_char(ch, shift_amt) for ch in X)
def weave(string_list):
output =''.join([''.join(tup) for tup in zip(*string_list)])
# The rest is just to deal with the case of unequal string lengths
# We assume the only possibility is that the early strings are one character longer
last_length = len(string_list[-1])
extra =[s[-1] for s in string_list if len(s)> last_length]
return output +''.join(extra)
def to_base_b(num, base):
'''Returns the digits of `num` when written in base `base`.
Adapted from code on Stack Overflow.'''
digits =[]
while num >0:
num, rem = divmod(num, base)
digits.append(rem)
return digits[::-1]
def from_base_b(digit_list, base):
'''Converts from a list of digits in base `base` to an integer.'''
return sum(d*base**i for i, d in enumerate(digit_list[::-1]))
Choose a prime `p0` using the `getPrime` function. (See the next few instructions to help you decide how large the prime should be.)
Find a generator `g0` for $(\mathbb{Z}_{p_0})^{*}$.(Hint. Use the `n_order` function that we imported from SymPy. Call `help(n_order)` to see how this function works. What order do we need to have a generator? You will have to do some guessing-and-checking (or better, use a `for` loop, calling `break` when you've found a generator), but it shouldn't take many guesses before you find a generator.)
Call `naive_dlog(g0,0, p0)`, and time how long it takes using `%%time` at the top of the cell. We already know that no discrete logarithm exists in this case (why?), so the point of this is just to see how long the naive discrete logarithm takes to run in the worst-case scenario.
* We want a prime for which this naive discrete logarithm calculation takes 1-4 seconds. If your prime takes an amount of time outside of this range, then change the values of `p0` and `g0` above until you find values for which it takes 1-4 seconds.
* Again using the getPrime function, find a prime `p` which is `20` bits larger (add, don't multiply) than the prime `p0` you found above.
* As above, find a generator `g` for $(\mathbb{Z}_{p})^{*}$.
* We estimate that multiplying `p0` by `M` will multiply the amount of time the naive discrete logarithm takes by `M`. Using this estimate, how many *days* would you expect the naive discrete logarithm to take for `p`?(Your answer should depend on `p/p0` and on the number of seconds given by your timing computation above. **Do not** try to run the naive discrete logarithm function on `p` directly. Be sure your answer is in days, not in seconds.)

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access with AI-Powered Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Students also viewed these Databases questions