Uploaded by vafwxgxgeafxhqztmf

A4 Cryptography Fall2022

advertisement
PSUT: 25347 (Cryptography)
Fall 2022
Assignment 4
(Simple DES)
Overview:
In this assignment, you will implement the Simplified DES (SDES) cryptographic
scheme. The implementation will use the Electronic Book (ECB) and Cipher Block
Chaining (CBC) modes.
General Instructions:
1. Create a python project called: "A4"
2. Rename the file: A4_template.py to sdes.py. This is the only file that you
are expected to edit and will contain your entire solution to this assignment.
3. Add the mod class to the bottom of the sdes.py file.
4. Insert your credentials on top of the sdes.py file.
5. When you are done, submit only one file: sdes.py. DO NOT submit a zip file.
6. Compare your results to the A4_output.txt file. Use the free online tool:
https://text-compare.com/. Your results should EXACTLY match the output of
the output file.
7. Your program SHOULD NEVER crash. If it crashes for any reason, then you lose
25% of the assignment grade. If the grader was not able to fix your error in a
short time, a grade of 0 is assigned.
8. Deadline: Thursday, Jan 19th at midnight. You can submit one day late with 50%
late penalty. Submissions are not accepted after that.
9. The instructor will ask you to run your code and present your solution for
grading purposes.
© Qutaiba Albluwi
PSUT: 25347 (Cryptography)
Fall 2022
General Notes:
The implementation of SDES is not complex. However, having a full implementation
that handles all exceptions is quite lengthy. Therefore, our focus will be on being
practical by handling the most common operations and errors. Therefore, you
might notice that the implementation is not comprehensive.
For error checking, in newly created methods in this assignment, you will either be
instructed to return an empty string, or print an error message and return an empty
string. For most cases, the former (which is returning empty string with no error
msg printing) will be used.
Because we are dealing with binary numbers, tracing the algorithm can be
challenging. Therefore, insert as many print statements (for debugging purposes)
as possible. Remember to remove these prints before submission.
In this assignment, you will use many functions in the utilities library. You might
need to use the following functions: is_binary, xor, dec_to_bin,
bin_to_dec, get_base, get_positions, clean_text,
decode, shift_string, insert_positions.
encode,
Assignment Structure:
The assignment can be broken into 8 steps:
12345678-
Implementation of PRNG
Implementation of SBOX
General outline of SDES focusing on parameter handling
SDES key handling
Feistel Network
Encryption and Decryption Dispatcher
ECB mode (encryption and decryption)
CBC mode (encryption and decryption)
We will present a short overview of each step.
[1] Implementation of PRNG:
In this course, we have learned two Pseudo Random Number Generator (PRNG)
algorithms: LFSR and Blum Blum Shub (BBS). We will only implement BBS.
© Qutaiba Albluwi
PSUT: 25347 (Cryptography)
Fall 2022
The PRNG class has one static methods: BBS. The method returns a stream of binary
bits. The number of bits is determined by the bits parameter.
Whenever there is an issue in the input parameters, the function returns an error
message (does not print).
Three values are passed to the method: p, q and bits. The function validates
inputs by insuring that bits is a positive integer and both p and q are positive
integers congruent to 3 mod 4.
The seed is computed as the nth prime number, where n = p*q. The prime number
can be obtained from the PRIMES_FILE which contains the first million primes. If
the seed is not relatively prime with n, then the function should pick the next prime
number and continue until a valid number is found.
Below is the output for testing PRNG.BBS:
---------------------------------------Start of PRNG Testing
Testing Blum Blum Shub:
PRNG.BBS(383,503,8) = 01110011
PRNG.BBS(11,19,4) = 1110
PRNG.BBS(27691,11,16) = 1111110111000011
PRNG.BBS(383,503,0) = Error(PRNG.BBS): invalid bits
PRNG.BBS(383,503,1) = Error(PRNG.BBS): invalid q
PRNG.BBS(384,503,1) = Error(PRNG.BBS): invalid p
End of PRNG Testing
----------------------------------------
[2] SBox Implementation:
SBOX is an integral part of the Feistel Network. It is also integrated in many other
ciphers like AES. Therefore, we will have a separate class for it. The class has the
following layout:
class SBOX:
def __init__(self,filename = '')
def is_empty(self):
def get_box(self):
def get_size(self):
def set_box(self,filename):
def substitute(self,value):
def __str__(self):
© Qutaiba Albluwi
PSUT: 25347 (Cryptography)
Fall 2022
Each SBOX has a size. If the size is n, then the input binary number should be nbits, and the output is (n-1) bits.
Also, each SBOX table should have a substitution table. The table is normally loaded
from a file, which can be performed using the __init__ and/or the set_box
methods. The box should be stored in a 2D list _box. Below is a sample file:
101-010-001-110-011-100-111-000
001-100-110-010-000-111-101-011
If the input is 1010, then MSB is 1 which represent the row number, and 010
represent the column number. In the above table, this corresponds to: 110.
Below is the output of testing the SBOX class:
---------------------------------------Start of SBOX class testing
Creating an empty SBOX:
SBOX(0):
[]
[]
sbox.substitute(1000) =
sbox.is_empty() = True
sbox.get_size() = 0
sbox.get_box() = [[], []]
Loading sbox1.txt:
sbox.set_box('sbox1.txt'): None
SBOX(4):
['101', '010', '001', '110', '011', '100', '111', '000']
['001', '100', '110', '010', '000', '111', '101', '011']
sbox.is_empty() = False
sbox.get_size() = 4
sbox.get_box() = [['101', '010', '001', '110', '011', '100', '111',
'000'], ['001', '100', '110', '010', '000', '111', '101', '011']]
sbox.substitute(1101) = 111
sbox.substitute(0010) = 001
sbox.substitute(0111) = 000
sbox.substitute(0000) = 101
sbox.substitute(010) =
sbox.substitute(1010) =
sbox.set_box('sbox2.txt'): None
SBOX(4):
['100', '000', '110', '101', '111', '001', '011', '010']
['101', '011', '000', '111', '110', '010', '001', '100']
sbox.substitute(1101) = 010
sbox.substitute(0010) = 110
sbox.substitute(0111) = 010
sbox.substitute(0000) = 100
sbox.substitute(010) =
sbox.substitute(1010) =
© Qutaiba Albluwi
PSUT: 25347 (Cryptography)
Fall 2022
End of SBOX class Testing
----------------------------------------
[3] SDES Basic Implementation:
The SDES class has 9 data members:
123456789-
_encoding: The default value of 'B6' will be always used
_rounds: number of Feistel network rounds. By default set to 2
_block_size: By default set to 12 bits
_key_length: By default set to 9 bits
_p: an integer value to be used in key generation
_q: an integer value to be used in key generation
_sbox1: An SBOX object to be used in Feistel Network
_sbox2: An SBOX object to be used in Feistel Network
_pad: a padding character to be used whenever necessary.
The __init__ method initializes the above data parameters, called SDES
parameters, to the to the default values.
The method get_value(parameter) receives a parameter name and returns the
corresponding value, as defined in the SDES object. The defined parameter names
are: encoding, rounds, block_size, key_length, p, q, sbox1, sbox2
and pad. If an invalid parameter name is passed, the method prints an error
message and returns an empty string. Note for sbox1 and sbox2, the method
returns a copy (not a reference) of the relevant SBOX object.
The method set_parameter(parameter, value) receives a parameter name
and a corresponding value and sets the parameter accordingly. The parameter
names are defined as in the get_value method. Below are some restrictions:
-
The encoding parameter can only be set to 'B6'.
The rounds should be an integer larger than 1
The p and q should be integers congruent to 3 mod 4
The sbox1 and sbox2 should be non-empty SBOX objects
The block_size should be a power of 2, greater than or equal to 4
© Qutaiba Albluwi
PSUT: 25347 (Cryptography)
Fall 2022
The key_length parameter can be set. However, when setting the block_size,
the key_length is automatically set to
π‘π‘™π‘œπ‘π‘˜_𝑠𝑖𝑧𝑒
2
+ 3 . (The 3 comes from 2 for
expand function, and 1 for key generation function).
Whenever the set operation is successful, the method updates the relevant data
member and returns True. If an invalid parameter name is passed, an error message
is printed and False is returned. If an invalid value is passed, the function returns
False. Running the SDES test will produce:
---------------------------------------Start of SDES basics testing
Testing default values (get_value):
sdes.get_value(rounds) = 2
sdes.get_value(key_length) = 9
sdes.get_value(block_size) = 12
sdes.get_value(encoding) = B6
sdes.get_value(sbox1) = SBOX(4):
['101', '010', '001', '110', '011', '100', '111', '000']
['001', '100', '110', '010', '000', '111', '101', '011']
sdes.get_value(sbox2) = SBOX(4):
['100', '000', '110', '101', '111', '001', '011', '010']
['101', '011', '000', '111', '110', '010', '001', '100']
sdes.get_value(p) = 103
sdes.get_value(q) = 199
sdes.get_value(pad) = Q
sdes.get_value(size) = Error(SDES.get_value): undefined parameter
Testing set_parameter:
sdes.set_parameter(rounds,5) = True
sdes.set_parameter(rounds,1) = False
sdes.set_parameter(rounds,4.3) = False
sdes.set_parameter(p,683) = True
sdes.set_parameter(p,899) = False
sdes.set_parameter(q,684) = False
sdes.set_parameter(q,13.2) = False
sdes.set_parameter(pad,r) = True
sdes.set_parameter(pad,ab) = False
sdes.set_parameter(pad,1) = False
sdes.set_parameter(pad,?) = False
sdes.set_parameter(encoding,B6) = True
sdes.set_parameter(encoding,ascii) = False
sdes.set_parameter(block_size,1024) = False
sdes.set_parameter(block_size,243) = False
sdes.set_parameter(block_size,512.0) = False
Error(SDES.set_parameter): undefined operation
sdes.set_parameter(key_length,64) = False
Error(SDES.set_parameter): undefined operation
sdes.set_parameter(sbox_size,128) = False
End of SDES basics Testing
© Qutaiba Albluwi
PSUT: 25347 (Cryptography)
Fall 2022
[4] SDES Keys:
An SDES key is generated using the Blum Blum Shub, defined in the PRNG class. The
parameters p and q are passed to the BBS method to generate key_length bits.
This is done by the method get_key().
The method get_subkey(i) generates the ith subkey, which is the key_length
bits starting at key index i, using circular method if necessary.
Note that there is no set_key method. Instead, a key can be set by setting the p and
q parameters.
Running the testing function would give:
---------------------------------------Start of SDES keys testing
Testing get_key:
p = 103, q = 199
sdes.get_key() = 100011001
p = 683, q = 199
sdes.get_key() = 010111101
p = 683, q = 503
sdes.get_key() = 101111010
Testing get_subkey:
key = 101111010
subkey(0) =
subkey(1) = 10111101
subkey(2) = 01111010
subkey(3) = 11110101
subkey(4) = 11101010
subkey(5) = 11010101
subkey(6) = 10101011
subkey(7) = 01010111
subkey(8) = 10101111
subkey(9) = 01011110
subkey(10) = 10111101
subkey(11) = 01111010
End of SDES keys Testing
----------------------------------------
[5] Feistel Network:
Building the Feistel Network requires implementing three methods:
First, the expand function which takes the right block side R, of size block_size/2,
and expands it by adding two extra bits.
© Qutaiba Albluwi
PSUT: 25347 (Cryptography)
Fall 2022
If the size of R is 6 bits, the output is of size 8 bits. The function swaps and repeats
the two middle bits, while keeping the other bits unchanged. For example, if
R = [R1R2R3R4R5R6] → [R1R2R4R3R4R3R5R6]
R = [R1R2R3R4R5R6R7R8] → [R1R2R3R5R4R5R4R6R7 R8]
The second is the F(Ri, ki), which receives an R block along with the
corresponding subkey, both at round i. The function performs five things:
12345-
Pass the Ri block to the expander function
XOR the output of [1] with ki
Divide the output of [2] into two equal sub-blocks
Pass the most significant bits of [3] to Sbox1 and least significant bits to sbox2
Concatenate the output of [4] as [sbox1][sbox2]
The third method is the feistel(Ri, ki), applies one round of Feistel Cipher.
This is represented as:
𝐿𝑖 = 𝑅𝑖−1
𝑅𝑖 = 𝐿𝑖−1 ⊕ 𝐹(𝑅𝑖−1 , π‘˜π‘– )
Running the testing function would give:
---------------------------------------Start of Feistel Network testing
Testing expand:
sdes.expand(011001) = 01010101
sdes.expand(00001111) = 0001010111
sdes.expand(0011) = 010101
sdes.expand() =
sdes.expand(1011) =
Testing F function:
F(111000,00011010) = 000001
F(100110,01100101) = 000100
F(10011,01100101) =
F(100110,0110010) =
Testing feistel:
feistel(011100100110,01100101) = 100110011000
feistel(010001100101,11000001) = 100101101100
feistel(01110010011,01100101) =
feistel(011100100110,0110010) =
End of Feistel Network Testing
----------------------------------------
© Qutaiba Albluwi
PSUT: 25347 (Cryptography)
Fall 2022
[6] Encryption/Decryption Dispatcher:
Now that the inner workings of the SDES cipher are ready, we can implement the
encrypt and decrypt methods. The methods have the following prototypes:
- encrypt(plaintext,mode)
- decrypt(ciphertext,mode)
The defined modes are: ECB and CBC. If one of these modes is passed, then the
appropriate encryption/decryption method is called. Otherwise, an empty string is
returned.
[7] ECB Mode:
Implement the two methods:
- _encrypt_ECB(plaintext)
- _decrypt_ECB(ciphertext)
The two methods use the ECB mode to encrypt/decrypt a given text. The feistel
network is called as many as rounds. For the last round, the two sides (R and L)
are swapped.
Only characters defined in the B6 base are encrypted/decrypted. This requires
cleaning the text and preserving their positions for the undefined characters before
processing, and restoring that before providing the output.
Since the B6 encoding is used, for the standard block_size of 12, every two
characters in the input text will correspond to one block. If the last block contains
one character, then it needs to be padded.
Watch out for the main difference between encryption and decryption which is the
subkeys used in each round. In decryption, the reverse order is used.
Below is the testing result for the ECB mode:
---------------------------------------Start of SDES ECB Mode testing
key = 111001101
plaintext = OK
ciphertext = kX
plaintext2 = OK
key = 000100011
plaintext = Sit
© Qutaiba Albluwi
PSUT: 25347 (Cryptography)
Fall 2022
ciphertext = GfRt
plaintext2 = Sit
key = 111111011
plaintext = beet
ciphertext = i41v
plaintext2 = beet
key = 101111010
plaintext = welcome
ciphertext = K3RFOg E
plaintext2 = welcome
key = 111100100
plaintext = "Cryptography" is power
ciphertext = "jjzAevJtKc20"gul4wjKUP
plaintext2 = "Cryptography" is power
key = 110010001
plaintext = go-go
ciphertext = GD-GD
plaintext2 = go-go
End of SDES ECB Mode Testing
----------------------------------------
[8] CBC Mode:
Implement the two methods:
- _encrypt_CBC(plaintext)
- _decrypt_CBC(ciphertext)
You would need to implement _get_IV() to generate the initial vector (IV) for
the first round. The length of the IV is the same as the block size. The function
returns a string representing a binary number, which is generated as:
One 1, two 0's, three 1's, four 0's, five 1's, six 0's and so forth
For a block size of 12, the output will be: 100111 000011
Remember that CBC uses padding if necessary.
Running the testing function would give:
---------------------------------------Start of SDES CBC Mode testing
key = 111001101
plaintext = go
ciphertext = yE
plaintext2 = go
© Qutaiba Albluwi
PSUT: 25347 (Cryptography)
Fall 2022
key = 110011101
plaintext = CAT
ciphertext = XCpt
plaintext2 = CAT
key = 111111011
plaintext = seed
ciphertext = go1g
plaintext2 = seed
key = 101111010
plaintext = go-go
ciphertext = pT-s4
plaintext2 = go-go
End of SDES CBC Mode Testing
----------------------------------------
© Qutaiba Albluwi
Download