Problem

Ready for some l33t h4x1ng? A collision attack is an exploit where a malicious string is substituted in place of another harmless string with an identical hash. The malicious string is often injected into an application in place of the harmless string to perform nefarious activities.

An example where this could be used is malicious code injection. Often on websites where programmers can download code will be listed the hash of the code as computed by the author of the code. Once the programmer downloads the code, he or she can compute the hash of the code locally to check that it matches what was listed on the website. This insures that malicious code was not injected via a man-in-the-middle attack or that no errors occurred while the code was downloading.

The exercise is very simple in its requirements: you must write two programs. The first executable, solution-a, must output the phrase

C++ is a wonderful language.

to stdout. In contrast, the second executable, solution-b, must output the phrase

C++ is an evil language.

to stdout. Sounds easy right? Here's the catch:

The MD5 hash of solution-a.cpp and solution-b.cpp must be identical. How is this possible? Recall that an MD5 Hash is a 16-byte value. (That's 128 bits.) Since there are an infinite number of possible programs one may write adhering to the C++ grammar, and only 2^128 distinct MD5 hashes, it must be true that for any given program, there must exist an infinite number of other valid C++ programs distinct from the original that have an identical hash.

It is your job to find two such programs with the different outputs as described above whose MD5 hash is identical.

Hint: it will probably not be possible to solve this problem by hand. Use metaprogramming techniques to modify one or both of solution-a.cpp and solution-b.cpp. It is reasonable to expect this task to take 2-10 hours of execution time to find colliding hashes.

Submission

To submit your solution, you must initiate a Merge Request in your private assignments repository and assign it to the appropriate TA from the Challenge 11 - TA assignment list.

Development Branch

To facility the Merge Request workflow, you must do your development in its own [branch]:

$ cd path/to/repo                   # Go to your repository
$ git checkout master               # Make sure we are on master branch
$ git pull                          # Make sure we have changes for GitLab
$ git pull upstream master          # Fetch and merge upstream changes
$ git checkout -b challenge11_ec    # Create challenge10_ec branch
...                                 # Do your work
$ git commit                        # Commit your work (can do this multiple times)
$ git push -u origin challenge11_ec # Push branch to GitLab