---
# System prepended metadata

title: Homework 7 (FCS)

---

# Homework 7 (FCS)


# Ex 1

--------------------------------------
#### Advantages:

1. Encrypt-and-Authenticate : 

Better performance, as encryption and decryption can happen in parallel (for sender and receiver respectively).
Adheres to the Horton principle (authenticate what is meant, not what is said).

2. Authenticate-then-Encrypt : 

Eavesdropper is only able to see the ciphertext and is unable to see the tag of the initial message.
Adheres to the Horton principle.

3. Encrypt- then-Authenticate :

Efficient, as bogus messages could be discarded without wasting resources to decrypt.

#### Disadvantage:

1. Encrypt-and-Authenticate : 

Eavesdropper can view the tag of the initial message (not of the ciphertext), which could leak information about the message itself.
Receiver has to decrypt the ciphertext first before checking authenticity (unlike sender’s case – in parallel). CPU computations would have been wasted on decrypting bogus messages.

2. Authenticate-then-Encrypt : 

The receiver has to decrypt first before checking the tag. If the message were bogus, CPU computations would have been wasted on the decryption process.

3. Encrypt- then-Authenticate :

Eavesdropper can collect valid (message, tag) pairs.
Violates the Horton principle. Receiver might decrypt with a wrong key (and get a different plaintext) even after successful tag verification.


----------------------------------------
# Ex 2

SSL/TLS uses both asymmetric and symmetric encryption to protect the confidentiality and integrity of data-in-transit. Asymmetric encryption is used to establish a secure session between a client and a server (protect Confidentiality), and symmetric encryption is used to exchange data within the secured session ( protects integrity ) . 

# Ex 3

## a)

------------------------------
Exercise 3a
Ciphertext C is:  960b10b82e0cc77c097dd1a8eab3a331d1e86de370be8979c7a49f389c7ce52f7b9046b64b5cf7fc79755eb193f06b6d
Authentication tag T is:  3a99580e2844f519f6e9ddaf6f23adda
Decrypted Plaintext as:  b'SUTD-MSSD-51.505*Foundations-CS*SUTD-MSSD-51.505'

------------------------------


## b)


Exercise 3b
Ciphertext C is:  **7b9046b64b5cf7fc79755eb193f06b6dd1e86de370be8979c7a49f389c7ce52f960b10b82e0cc77c097dd1a8eab3a331**
Authentication tag T is:  3a99580e2844f519f6e9ddaf6f23adda
MAC Tag not valid. Entire message should not be trusted.



## c)
```
Exercise 3c
Ciphertext C is:  960b10b82e0cc77c097dd1a8eab3a331d1e86de370be8979c7a49f389c7ce52f
Authentication tag T is:  3a99580e2844f519f6e9ddaf6f23adda
MAC Tag not valid. Entire message should not be trusted.
```

## d)

-------------------
Exercise 3d
Ciphertext C is: **960b10b82e0cc77c097dd1a8eab3a331d1e86de370be8979c7a49f389c7ce52f7b9046b64b5cf7fc79755eb193f06b6e**
Authentication tag T is:  3a99580e2844f519f6e9ddaf6f23adda
MAC Tag not valid. Entire message should not be trusted.

-------------------

## e)

It is difficult for any attackers to change the ciphertext message (integrity protected). The tag verification would need to be done and as such any manipulated ciphertext would not be able to be decrypted with the original authentication tag.



# Ex 4

```python=
class Peer(object):
	def __init__(self, key):
		self.key = key.encode(encoding='utf-8',errors='strict')
	def send(self, msg):
		cipher = AES.new(self.key, AES.MODE_GCM, NONCE)
		ciphertext, tag = cipher.encrypt_and_digest(msg.encode(encoding='UTF-8',errors='strict'))
		protected_msg = ciphertext.hex() + tag.hex() # concatenate: ciphertext || tag 

		# protect the message
		return protected_msg # type of protected_msg is ’str’
	def receive(self, protected_msg):
		ctxt = binascii.unhexlify(protected_msg[0:-128//4])
		tag = binascii.unhexlify(protected_msg[-128//4:])

		cipher = AES.new(self.key, AES.MODE_GCM, NONCE)
		try:
			msg = cipher.decrypt_and_verify(ctxt, tag)
			print(msg) # successfuly recovered plaintext
		except ValueError:
			print("MAC Tag not valid. Entire message should not be trusted.")
global NONCE
NONCE = binascii.unhexlify(hex(secrets.randbits(128))[2:].zfill(32))

alice = Peer("very secret key!")
bob = Peer("very secret key!")
msg1 = alice.send("Msg from alice to bob")
bob.receive(msg1)
msg2 = alice.send("Another msg from alice to bob")
bob.receive(msg2)
msg3 = bob.send("Hello alice")
alice.receive(msg3)

```

# Ex 5

Implementing a naive approach for a random number generator 0-127 using the specified method from the question.
```python=
def ex5(quantity):
	numList8bit = []
	numList7bit = []

	# quantity = 512

	for i in range(quantity):
		r8bit, r7bit = rnd8bitAnd7bit()
		numList8bit.append(r8bit)
		numList7bit.append(r7bit)

	cnt7bit = Counter(numList7bit)
	cnt8bit = Counter(numList8bit)

	cntItems7bit = cnt7bit.items()
	cntItems8bit = cnt8bit.items()

	sortedCnt8bit = sorted(cntItems8bit)
	cntDict8bit = {}
	for tup in sortedCnt8bit:
		cntDict8bit[tup[0]] = tup[1]

	sortedCnt7bit = sorted(cntItems7bit)
	cntDict7bit = {}
	for tup in sortedCnt7bit:
		cntDict7bit[tup[0]] = tup[1]

	print("Numbers generated:", quantity)
	print("8-bit set | mean:", np.mean(numList8bit),"std:", np.std(numList8bit))
	print("Modulo set | mean:", np.mean(numList7bit),"std:", np.std(numList7bit))

	plt.subplot(1, 2, 1)
	plt.title("8-bit set")
	plt.bar(range(len(cntDict8bit)), list(cntDict8bit.values()), align='center')

	plt.subplot(1, 2, 2)
	plt.title("Modulo set")
	plt.bar(range(len(cntDict7bit)), list(cntDict7bit.values()), align='center')

	plt.show()
    

ex5(512)

ex5(100000)

# Results 1
'''
Numbers generated: 512
8-bit set | mean: 128.177734375 std: 75.915825432626
Modulo set | mean: 62.177734375 std: 37.485643766873515
'''


# Results 2

'''
Numbers generated: 512
8-bit set | mean: 130.052734375 std: 73.2191378053627
Modulo set | mean: 65.052734375 std: 35.09839896221327
'''

# Results 3

'''
Numbers generated: 512
8-bit set | mean: 132.033203125 std: 74.72860317125892
Modulo set | mean: 63.033203125 std: 36.80280102352931
'''

# Results 4

'''
Numbers generated: 512
8-bit set | mean: 132.662109375 std: 73.84089400055052
Modulo set | mean: 66.162109375 std: 36.54843599493058
'''

# Results 5

'''
Numbers generated: 512
8-bit set | mean: 129.05859375 std: 74.23703382929884
Modulo set | mean: 64.05859375 std: 37.41329147873067
'''
```

**Sample graphs for the distributions**
![](https://i.imgur.com/OX4RZ79.png)
![](https://i.imgur.com/iF4phnq.png)
![](https://i.imgur.com/TnwKvhc.png)


if we take a step further and generate a larger amount of samples (100,000), the distribution will further evolve and approach a uniform distribution. The final random number set has a slightly more uniform distribution compared to the 8-bit set, from the “smoothening” effects of the modulo function. The uniform distribution has Pr(X = i) = Pr(X = j) for all i, j. This maximises entropy (uncertainty).



**Distribution for 100,000 samples**
![](https://i.imgur.com/RC5WYaY.png)
