# Homework/Project 2
**Student information:** Owen Sullivan (opsulli | C34243277)

## Introduction
For this assignment, I worked alone and thus did not divide up any of the work.

## Methodology

### Padding Oracle Attack
For the padding oracle attack (found in `padding_oracle.py`), I began by selecting one of the provided sample ciphertexts.

After reading through some of the code that was provided for the server's decryption functions, I determined that the initialization vector used for encryption can be found in the first 16 bytes of the ciphertext. I extracted the initialization vector, then split the remaining ciphertext into blocks of 16 bytes each.

Next, I began looping backwards from the last ciphertext block. From there, I generated every possible combination of bytes in a modified ciphertext block to test against the padding oracle. The ciphertext which resulted in an "invalid_mac" error from the oracle was used to get the intermediate decryption state, which was then translated into the plaintext for that block.

While doing all this, I had to make sure to update both the expected padding values and the bytes of the modified ciphertext which had already been confirmed as valid. Put simply, this all involved a lot of looping and XORing.

Finally, I removed the leftover padding from the plaintext message, as well as the MAC which isn't needed for interpreting the decrypted plaintext.

### Bleichenbacher's Attack
For the Bleichenbacher attack (found in `bleichenbacher.py`), I began by creating a `bytearray` for the forged signature and filling the first few bytes as follows: `00 01 FF 00`. This matches the schema: `00 01 [some number of FF bytes] 00`.

Then, I added the ASN.1 bytes for the SHA-256 hash algorithm: `30 31 30 0D 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20`. This matches the schema: `00 01 [some number of FF bytes] 00 [ASN.1 bytes]`.

Next, I found the SHA-256 hash of the message that's provided when the script is run, appended the hash to the forged signature, and appended 201 (`((2048 / 8) - 54) - 1`, where `1` is the number of `FF` bytes from earlier) arbitrary bytes.

Finally, I took the cube root of the forged signature, determined whether it needed to be rounded (by using the result from the `integer_nthroot()` function and adding 1 if rounding is needed), and converted it to base64 format. This results in a valid signature for the purposes of this assignment.