Sage note 11.3.1. Another reminder to evaluate definitions.
Don’t forget to evaluate the commands below so we can use words as messages instead of just numbers.
xxxxxxxxxx
def encode(s): # Input must be in quotes!
s = str(s).upper()
return sum((ord(s[i])-64)*26^i for i in range(len(s)))
def decode(n):
n = Integer(n)
list = []
while n != 0:
if n%26==0:
list.append(chr(64+26))
n -= 1
else:
list.append(chr(n%26+64))
n //=26
return ''.join(list)
xxxxxxxxxx
p=29 # a prime number
e=9 # a number coprime to euler_phi(p)=p-1=28
message='MathIsCool'
secret=[encode(letter) for letter in message]
code=[mod(x,p)^e for x in secret]
print(code)
print(''.join([decode(m) for m in code]))
xxxxxxxxxx
f=mod(e,p-1)^-1 # the multiplicative inverse mod p-1 (!) to our encryption power
print(f)
print(''.join([decode(x^f) for x in code]))
xxxxxxxxxx
message='heymathiscooleverybody'
secret=encode(message)
secret
xxxxxxxxxx
p=next_prime(secret)
print(p)
print(factor(p-1))
xxxxxxxxxx
e=10103 # a number coprime to p-1
code=mod(secret,p)^e
code
xxxxxxxxxx
f=mod(e,p-1)^-1
print(f)
print(''.join(decode(code^f)))
next_prime()
. (If it fails, try changing e
to something coprime to xxxxxxxxxx
message='mathisreallycoolanditshouldntbeasecret'
secret=encode(message)
p=next_prime((secret)^5)
e=677 # hopefully coprime to p-1
code=mod(secret,p)^e
f=mod(e,p-1)^-1
pretty_print(html("My encoded message is $%s$"%secret))
pretty_print(html("A big prime bigger than that is $%s$"%p))
pretty_print(html("And I chose exponent $%s$"%e))
pretty_print(html("The encrypted message is $%s$"%code))
pretty_print(html("The inverse of $%s$ is $%s$"%(e,f)))
pretty_print(html("And the decrypted message turns out to be:"))
print(''.join(decode(code^f)))
xxxxxxxxxx
def _(message='mathiscool',e=677):
secret=encode(message)
p=next_prime(100*(secret))
if gcd(e,p-1) != 1:
pretty_print(html("Looks like $%s$ isn't coprime to the prime! Try another one."%e))
else:
code=mod(secret,p)^e
try:
f=mod(e,p-1)^-1
except:
pretty_print(html("Looks like $%s$ is not coprime to the prime we chose, $%s$"%(e,p)))
pretty_print(html("My encoded message is $%s$"%secret))
pretty_print(html("A big prime bigger than that is $%s$"%p))
pretty_print(html("And I chose exponent $%s$"%e))
pretty_print(html("The encrypted message is $%s$"%code))
pretty_print(html("The inverse of $%s$ is $%s$"%(e,f)))
pretty_print(html("And the decrypted message turns out to be:"))
print(''.join(decode(code^f)))
xxxxxxxxxx
def _(message='hi',p=991,e=677):
secret=encode(message)
if is_prime(p) and gcd(p,e)==1 and p>secret:
e=677 # hopefully coprime to p-1
code=mod(secret,p)^e
try:
f=mod(e,p-1)^-1
except:
pretty_print(html("Looks like $%s$ is not coprime to the prime we chose, $%s$"%(e,p)))
pretty_print(html("My encoded message is $%s$"%secret))
pretty_print(html("A big prime bigger than that is $%s$"%p))
pretty_print(html("And I chose exponent $%s$"%e))
pretty_print(html("The encrypted message is $%s$"%code))
pretty_print(html("The inverse of $%s$ is $%s$"%(e,f)))
pretty_print(html("And the decrypted message turns out to be:"))
print(''.join(decode(code^f)))
elif not is_prime(p):
pretty_print(html("Pick a prime $p$!"))
elif p <= secret:
pretty_print(html("Make sure your prime is bigger than your secret, $%s$"%secret))
else:
pretty_print(html("Make sure that $gcd(p,e)=1$!"))
xxxxxxxxxx
next_prime(11058)
xxxxxxxxxx
message='hi' # needs to be in quotes
secret=encode(message)
p=991 # needs to be bigger than secret
e=2 # NOT coprime to p-1
code=mod(secret,p)^e
code
message
in the preceding cell to encode your own secret.xxxxxxxxxx
f=mod(e,p-1)^-1
message,secret,code,decode(code^f) # prints all the steps
ZeroDivisionError
, which should sound relevant). It turns out not even to be possible to go backwards. Be warned that you must know the mathematics to use cryptography wisely.