Lab 2: Docker and PythonFall 2024

This lab seeks to help introduce you to the Docker and VS Code development workflow that the course uses for the rest of its projects, as well as to help you avoid some pitfalls with the use of Python in the Crypto Project. You will set up Docker for use, learn how to use some helpful tools in Python, do some visual debugging, and track down a nasty bug that many past students have run into!

Setup

If you haven’t already, follow our Docker guide to learn how to set up Docker on your computer. This will be useful for all the labs and projects in this class.

To get the code for this lab, create a repo using the GitHub template. Make sure to make this repo private. Clone the repo onto your system (you’ll need to supply your GT credentials for this), then open it in VS Code. If you successfully set up Docker, you should be greeted with a pop-up in the bottom right asking you to reopen the directory in the development container; do so now! After some time taken to build the container, you should be greeted with the lab file in a directory and a terminal connected to the container (as shown in the Docker guide).

If you’re having trouble at this point, please come to office hours or put up a post on Ed describing in as much detail as possible what is going wrong—having a working Docker installation is essential for the course (which is why we’re making sure that it works in this lab!).

Tasks

This lab contains five tasks. One is to ensure you have Docker setup correctly. The others are to help you get familiar with Python.

To run each of the four Python parts, you can use python3 part#.py in the terminal, where “#” is the part number.

Validation of Docker Installation

Open a terminal in the VS Code window (using the keyboard shortcut “Ctrl + `“), at which point you should be greeted with a prompt inside the container. Try running the command whoami. If it outputs cs3235, you’re good to go! If it outputs anything else, you’ll need to go back and fix your Docker setup. Come to office hours or post on Ed if you’re stuck.

Task To generate what you’ll submit to the Autograder, do the following:

  1. Put your GT username in the file gtusername.txt (must be done first!)
  2. Run the following command in the terminal:
tr -d ' \n\r\t' < gtusername.txt | cat - ~/.shhhh | openssl dgst -md5 -binary | xxd -p > openssl_output.txt

If you’re curious, here’s what each part of the command does:

tr -d ' \n\r\t' < gtusername.txt Read the file `gtusername.txt` ignoring whitespace
cat - ~/.shhhh Concatenate the output of the previous command with the contents of ~/.shhhh
openssl dgst -md5 -binary Compute the MD5 digest of the output of the previous command
xxd -p > openssl_output.txt Express the output of the previous command as hexadecimal and save it to openssl_output.txt

Altogether, this will generate a value that lets the Autograder check that your installation is working properly. (For the curious: I wonder what is in ~/.shhhh!)

The files gtusername.txt and openssl_output.txt are now ready to be submitted.

Python

Part 1: Bytes 35 pts

When implementing crytographic algorithms (such as in crypto project), you perform a lot of operations on bytes. Luckily, Python has built-in datatypes for this exact purpose. They are called bytes and bytearrays. Here you will get some practice working with them before Crypto Project.

Byte Literals

Byte literals work just like strings in Python, except you put a b before the opening quote.

You can write out each byte as a hexadecimal value:

b'\x01\x02\x03'

Or you can put ASCII characters, and each will be encoded as bytes:

b'Hello, world!'

Task In the file part1.py, edit the gtinfosec variable so that it is no longer None. The variable should hold a bytes object that stores the bytes 0x03 0x02 0x03 0x05.

Converting to bytes

Often times you’ll need to convert other datatypes to bytes.

Task In the file part1.py:

  • Write a function called str_to_bytes(s) that converts the string s to a bytes object using ASCII encoding, then returns the converted value
  • Write a function called hex_to_bytes(s) that converts the hexadecimal string s to a bytes object, then returns the converted value
  • Write a function called int_to_bytes(n) that converts the integer n to a bytes object with length 4 using big endianness, then returns the converted value

Try looking up how to perform these conversions online if you don’t already know to do them. They can each be done with a single line of code.

bytearrays

Normal bytes objects in Python cannot be modified in-place. If you want to modify them, you’ll need to convert them to a bytearray object.

bytes_object = b'\x01\x02\x03'
bytearray_object = bytearray(bytes_object)

You can now index into the bytearray object to modify the value.

Task In the file part1.py, write a function called set_end_to_zero(b) that sets the last byte in the bytearray b to 0x00. The function shouldn’t return anything, it should just modify the bytearray in-place.

Part 2: The Python Standard Library 15 pts

The Python Standard Library has tons of useful tools built-in, way more than C++. You’re welcome to import anything from it for this class. Scroll through it to see all the ways it can help save you time and effort.

Task In the file part2.py, write a function called sha_256(b) that returns the SHA-256 digest of the bytes object b. Look in the standard library for something that can help you with this. Read the example code and documentation to help you learn how to use it.

Part 3: Debugging 15 pts

Using the Visual debugger in VS Code may be a great tool throughout the semester, saving you time on tracking down bugs. Luckily, the Docker workflow allows it to come working with no extra steps on your end! Here, we’ll run through a quick example to get you up to speed with the interface.

Task First, open part3.py and hit the debugging symbol on the left side of the window.

Run & Debug window

Set a breakpoint on the line with s = secret() by hovering over the line number and clicking the red circle.

Breakpoint

You should now see that the circle stays lit and that the line appears in the bottom left, indicating that a breakpoint is set.

Breakpoint Menu

Confirm that the “Part 3” target is selected in the drop-down menu in the top left, then hit the ▶️ button to begin debugging.

Begin debugging

Here, VS Code may ask you to select a Python interpreter, like the following popup:

Interpreter selection

If this happens, select the recommended option of Python 3.9.2 in /usr/bin/python3.

Python 3.9.2 selection

You should see that the program stops on the breakpoint you just set. The line with the breakpoint will be highlighted.

Debugging GUI

You’ll see a small set of buttons on the top of the screen which looks like this:

Debugging buttons

Choose the second from the left button to step over one line of code, so that script finishes constructing s.

Stepping over

Examine the variables section on the left side of the window, which shows you the values of any variables in the program at this point. Under the “Locals” section, s now appears:

Debugger variables

The secret class has a special method, __repr__, that changes how objects of the class are displayed in the debugger (as well as in other places, such as when the object is evaluated in interactive Python shells). It’s hard to see what this __repr__ method does by looking at its code, but by viewing the value of s in the debugger, it becomes quite clear!

Edit the script to set the secret string that you found while debugging. This is how the Autograder will check that you got the debugger working. Note: you can double-click variables in the debugger to copy them to your clipboard!

Part 4: Bug Fixing 35 pts

Finally, you’ll be responsible for fixing a bug that can be perplexing to new Python users. We hope this will stop you from making the same mistake!

Examine the description of the square_list function according to its comment, then carefully consider the output you see when running the script using the command python3 part4.py. Is the function acting according to what it says it should be doing?

Task Your final task for this lab is to fix the bug in the square_list function. You might need to do a bit of research into what is happening here, along with possible ways to fix it. (There are many ways to go about this; there’s no one right answer!) While this may seem daunting if this is your first introduction to Python, we think that this type of self-directed exploration best helps you to remember what you’ve done here when you need it later (which, trust us, you probably will!). Happy hacking!

If you’re stuck, try running the code in Python Tutor to visualize what’s going on.

Submission

Submit the following files to the Autograder by the deadline: Wednesday, Sep. 18, 11:59 PM

  • gtusername.txt
  • openssl_output.txt
  • part1.py
  • part2.py
  • part3.py
  • part4.py