\( \def\ZZ{\mathbb{Z}} \def\GG{\mathbb{G}} \def\HH{\mathbb{H}} \)

Your Task

In this lab, you will write rsa.py.

GCD and Modular Multiplicative Inverse

[10pts] Part 1: Checking if a RSA Encryption Key is Valid

Write a function is_e_good(e, p, q) in rsa.py that checks if the public key e is good.

Sample Run

This example is from the homework.

>>> p = 3
>>> q = 5
>>> from rsa import *
>>> for e in range(2, p*q):
...   if is_e_good(e, p, q): print(e, "is good")
...
3 is good
5 is good
7 is good
9 is good
11 is good
13 is good

[10pts] Part 2: Computing the RSA decryption Key

Write a function compute_d(e, p, q) in rsa.py that computes the secret key d from (e, p, q).

Sample Run


>>> from rsa import *
>>> p = 3
>>> q = 5
>>> for e in range(2, p*q):
...   if is_e_good(e, p, q):
...      d = compute_d(e, p, q)
...      print("e=", e, " , d=", d)
...
e= 3 ,  d= 3
e= 5 ,  d= 5
e= 7 ,  d= 7
e= 9 ,  d= 1
e= 11 ,  d= 3
e= 13 ,  d= 5

[15pts] Part 3: Key Generation

Write a function gen() in rsa.py that implements the RSA key generation algorithm. The box below provides partial code, and fill the rest as necessary. You may want to check out the documentation.

from Cryptodome.Util.number import getPrime 
from Cryptodome.Random.random import randrange
def gen(bit_len):
  p = getPrime(bit_len//2)
  q = getPrime(bit_len//2)
  
  # ... fill the code ...

  pk = (n, e)
  sk = (n, d)
  return (pk, sk)

Sample Run

The numbers you see will be different since gen() generates a random key pair.

>>> from rsa import *
>>> pk, sk = gen(30)
>>> pk
(417820859, 76516999)
>>> sk
(417820859, 149906119)
>>> pk, sk = gen(128)
>>> pk
(290811551835070190548173514535831587391, 270485843771875936504095435141447615209)
>>> sk
(290811551835070190548173514535831587391, 112639414460916485729877867067724462489)

[25pts] Part 4: Encryption and Decryption

Add the following four functions in rsa.py: enc(), dec(), dec_oaep(), enc_oaep().

[15pts] Part 5: Full Domain Hash -- Verifying a signature

Write a function verify(pk, bytes_data, signature) that performs the verification of Full Domain Hash.

Sample Run

Read the following sample run carefully.

  >>> from rsa import *
>>> pk = (1034347805468283269827508936486170888522287052492910727094077050318809053334171091720678869, 
510877216672959214128776340810554985688514636215490153898356945128401661157079729351949307)
>>> D = open("pcap.tar", "rb").read()
>>> sig = 712827146594771643203555365704210706658776126768689151938275544697784235891977989236268064
>>> verify(pk, D, sig)
Hash of the data (bytes):  b"\xf6\x16\xdan\x0b\xf7\xfe\xe0\xc1\xe3Hz\xc9\xaeg)\xe6'/nI\xc4\x91\x8e\xc3\xc9\xbf\xdbl\xd8#5"
Hash of the data (number):  111309338934466844412421473807411338124723784588157710110020410251474569274165
True
>>> sig -= 1
>>> verify(pk, D, sig)
Hash of the data (bytes):  b"\xf6\x16\xdan\x0b\xf7\xfe\xe0\xc1\xe3Hz\xc9\xaeg)\xe6'/nI\xc4\x91\x8e\xc3\xc9\xbf\xdbl\xd8#5"
Hash of the data (number):  111309338934466844412421473807411338124723784588157710110020410251474569274165
False

[15pts] Part 6: Full Domain Hash -- Signing a message

Write a function sign(sk, bytes_data) that outputs the signature on the bytes_data using the secret key sk.

Sample Run


>>> from rsa import *
>>> sk = (1034347805468283269827508936486170888522287052492910727094077050318809053334171091720678869, 
538046828872107393782134652951416777717550347945260104579354655057630363967157872764116723)
>>> D = open("pcap.tar", "rb").read()
>>> sign(sk, D)
712827146594771643203555365704210706658776126768689151938275544697784235891977989236268064
>>> pk, sk = gen(500)
>>> verify(pk, D, sign(sk, D))
Hash of the data (bytes):  b"\xf6\x16\xdan\x0b\xf7\xfe\xe0\xc1\xe3Hz\xc9\xaeg)\xe6'/nI\xc4\x91\x8e\xc3\xc9\xbf\xdbl\xd8#5"
Hash of the data (number):  111309338934466844412421473807411338124723784588157710110020410251474569274165
True
>>> pk[0].bit_length() >= 450
True

[10pts] Part 7: Lab Report and Submission

Write a lab report by using the provided template. The writing quality of the lab report matters.

Deliverables

~/bin/submit -c=IT430 -p=lab10 rsa.py lab10_report.docx