\[ \begin{align}\begin{aligned}\newcommand\blank{~\underline{\hspace{1.2cm}}~}\\% Bold symbols (vectors) \newcommand\bs[1]{\mathbf{#1}}\\% Differential \newcommand\dd[2][]{\mathrm{d}^{#1}{#2}} % use as \dd, \dd{x}, or \dd[2]{x}\\% Poor man's siunitx \newcommand\unit[1]{\mathrm{#1}} \newcommand\num[1]{#1} \newcommand\qty[2]{#1~\unit{#2}}\\\newcommand\per{/} \newcommand\squared{{}^2} \newcommand\cubed{{}^3} % % Scale \newcommand\milli{\unit{m}} \newcommand\centi{\unit{c}} \newcommand\kilo{\unit{k}} \newcommand\mega{\unit{M}} % % Percent \newcommand\percent{\unit{\%}} % % Angle \newcommand\radian{\unit{rad}} \newcommand\degree{\unit{{}^\circ}} % % Time \newcommand\second{\unit{s}} \newcommand\s{\second} \newcommand\minute{\unit{min}} \newcommand\hour{\unit{h}} % % Distance \newcommand\meter{\unit{m}} \newcommand\m{\meter} \newcommand\inch{\unit{in}} \newcommand\foot{\unit{ft}} % % Force \newcommand\newton{\unit{N}} \newcommand\kip{\unit{kip}} % kilopound in "freedom" units - edit made by Sri % % Mass \newcommand\gram{\unit{g}} \newcommand\g{\gram} \newcommand\kilogram{\unit{kg}} \newcommand\kg{\kilogram} \newcommand\grain{\unit{grain}} \newcommand\ounce{\unit{oz}} % % Temperature \newcommand\kelvin{\unit{K}} \newcommand\K{\kelvin} \newcommand\celsius{\unit{{}^\circ C}} \newcommand\C{\celsius} \newcommand\fahrenheit{\unit{{}^\circ F}} \newcommand\F{\fahrenheit} % % Area \newcommand\sqft{\unit{sq\,\foot}} % square foot % % Volume \newcommand\liter{\unit{L}} \newcommand\gallon{\unit{gal}} % % Frequency \newcommand\hertz{\unit{Hz}} \newcommand\rpm{\unit{rpm}} % % Voltage \newcommand\volt{\unit{V}} \newcommand\V{\volt} \newcommand\millivolt{\milli\volt} \newcommand\mV{\milli\volt} \newcommand\kilovolt{\kilo\volt} \newcommand\kV{\kilo\volt} % % Current \newcommand\ampere{\unit{A}} \newcommand\A{\ampere} \newcommand\milliampereA{\milli\ampere} \newcommand\mA{\milli\ampere} \newcommand\kiloampereA{\kilo\ampere} \newcommand\kA{\kilo\ampere} % % Resistance \newcommand\ohm{\Omega} \newcommand\milliohm{\milli\ohm} \newcommand\kiloohm{\kilo\ohm} % correct SI spelling \newcommand\kilohm{\kilo\ohm} % "American" spelling used in siunitx \newcommand\megaohm{\mega\ohm} % correct SI spelling \newcommand\megohm{\mega\ohm} % "American" spelling used in siunitx % % Inductance \newcommand\henry{\unit{H}} \newcommand\H{\henry} \newcommand\millihenry{\milli\henry} \newcommand\mH{\milli\henry} % % Power \newcommand\watt{\unit{W}} \newcommand\W{\watt} \newcommand\milliwatt{\milli\watt} \newcommand\mW{\milli\watt} \newcommand\kilowatt{\kilo\watt} \newcommand\kW{\kilo\watt} % % Energy \newcommand\joule{\unit{J}} \newcommand\J{\joule} % % Composite units % % Torque \newcommand\ozin{\unit{\ounce}\,\unit{in}} \newcommand\newtonmeter{\unit{\newton\,\meter}} % % Pressure \newcommand\psf{\unit{psf}} % pounds per square foot \newcommand\pcf{\unit{pcf}} % pounds per cubic foot \newcommand\pascal{\unit{Pa}} \newcommand\Pa{\pascal} \newcommand\ksi{\unit{ksi}} % kilopound per square inch \newcommand\bar{\unit{bar}} \end{aligned}\end{align} \]

Mar 14, 2025 | 1248 words | 12 min read

11.1.1. Materials#

Project Description#

In this project, you will explore hiding and recovering secret messages in images. We will use a combination of encryption and steganography to achieve this. Encryption is the process of converting a message into a secret form so that only the intended recipient can read it. Steganography is the practice of concealing a message within another message or medium to hide the fact that a message is being sent.

Your work will be evaluated through in-class demonstrations for Checkpoint 1 Task 1, while the remaining tasks will be assessed via the autograder on Gradescope. Additionally, the instructor team will conduct team visits to evaluate your understanding of the code you have written. Details of the requirements for each checkpoint are outlined below.

By working on this project, you will gain hands-on experience with encryption, working with binary data, and processing images. You will learn how data can be hidden inside images and then safely extracted. These skills are very useful in areas like cybersecurity, digital communications, and computer engineering.

Understanding Bytes, Pixels, and LSB Encoding#

In this project, you’re tasked with hiding an encrypted message inside an image and then retrieving it. To do this effectively, it’s important to understand some key concepts: bytes, pixels, and how we can use the Least Significant Bit (LSB) technique to encode binary data into an image.

Bytes and Binary Data#

Everything stored on a computer is ultimately represented in binary form, which means it’s made up of bits–zeros and ones. A group of 8 bits makes up a byte. A single byte can represent 256 different values. We often use integers from 0 to 255 to represent these values starting with “0” for “00000000” and ending with “255” for “11111111”.

Text characters are also stored in binary form. For example, the letter “H” in ASCII, is represented with a single byte as “01001000”. This is equivalent to the integer 72. So we say that the letter “H” has ASCII code point 72. Converting each character in a longer message, such as “Hello World”, to binary form gives us “01001000 01100101 01101100 01101100 01101111 00100000 01010111 01101111 01110010 01101100 01100100”.

Binary

Integer

00000000

0

00000001

1

00000010

2

11111110

254

11111111

255

Pixels and Images#

An image is made up of tiny dots called pixels. Each pixel represents a small portion of the image and has its own color. In digital images, colors are often represented using three values: Red, Green, and Blue (RGB). The intensity of each of these color values is typically stored as a byte, so that one pixel can be represented by three bytes.

For example, a pure red pixel might have the RGB values (255, 0, 0), where 255 is the maximum value for the red channel, and 0 is the minimum for green and blue.

Least Significant Bit (LSB) Encoding#

The Least Significant Bit is the rightmost bit in a binary number. For example, in the byte 01000001, the least significant bit is the last ‘1’. Changes to the least significant bit are often imperceptible to the human eye. The idea behind LSB encoding is to use this bit in each pixel’s color value to hide information unrelated to the image without significantly altering the image’s appearance.

Checkpoint 1 overview: Decoding an Encoded Image#

In this first checkpoint, your objective is to open an image and extract the plain text message that has been embedded in it. To assist you, two reference images (ref_col_p and ref_gry_p) will be provided. These images contain a hidden plain text message that you will need to extract using the instructions given.

During this checkpoint, your team will need to:

  1. Display an Encoded Image [In-class Demo]:

    Your code should be able to load and display either the color or grayscale image (instructor’s choice) that contains the encoded message.

  2. Extract the binary message [Autograder]:

    Recover the binary message embedded within the image using the appropriate decoding technique as explained in later instructions.

  3. Recover the plaintext message [Autograder]:

    Convert the binary message back into text to reveal the hidden plaintext message.

Checkpoint 2 overview: Encryption and Encoding into an Image#

In the second checkpoint, you will encrypt a given secret message and encode it into an image. To test your code, you will be provided with four reference images:

  1. ref_col_e and ref_gry_e: These images have messages encoded in them. You can use these for pixel-comparison functions to demonstrate differences between the original and encoded images.

  2. ref_col_b and ref_gry_b: These are reference images that include messages encrypted using the Beaufort cipher, available in both color and grayscale formats. These images will allow you to verify your encryption and encoding processes in various formats and compare your results against known references.

During this checkpoint, your team will need to:

  1. Display Image Differences [In-class Demo]:

    Show the difference between the original images and the provided encoded images.

  2. Encrypt the secret message [Autograder]:

    Your team will implement Beaufort cipher to encrypt the provided secret message and produce the ciphertext. The autograder will check if the message was properly encrypted.

  3. Encode the message into an image [Autograder]:

    Embed the encrypted binary message into the provided reference image. After you’ve created your encoded image, the autograder will compare it to our encoded image. The two should be identical for successful completion of this task.

Final Demo overview: Complete Encryption and Decryption Process#

For the final demo, you will perform both encryption and encoding at a randomized location, as well as decoding and decryption from a random location. To test your code, you will be provided with eight reference images:

  1. ref_col and ref_gry: These are original grayscale and colored images.

  2. ref_col_b and ref_gry_b: These are reference images that include messages encrypted using the Beaufort cipher, available in both color and grayscale formats.

  3. ref_col_c and ref_gry_c: These are reference images that include messages encrypted using the Caesar cipher, available in both color and grayscale formats.

  4. ref_col_r and ref_gry_r: These are reference images that include messages encrypted using the Rail Fence cipher, available in both color and grayscale formats.

The autograder will test your code using messages encoded at random locations, employing different ciphers, and varying in image size.

During the final demo, your team will need to:

  1. Encrypt a message and encode it into an image [Autograder]:

    Use an instructor specified cipher, key or shift, and bit offset to encrypt the secret message, and embed the binary message into the image. Then compare your encoded image with the provided encoded image.

  2. Decode and decrypt a message hidden in an image [Autograder]:

    Use a different instructor specified cipher and key or shift, to recover, decrypt, and display the secret message hidden in the image.

Team Size Adjustment for Cipher Choices#

  • Teams of 4 or more Members: Implement all three ciphers–Caesar, Rail Fence and Beaufort.

  • Teams of 3 Members: Implement Rail Fence and Beaufort ciphers.

  • Teams of 2 Members: Implement one cipher (other than Caesar).

Important Notes#

For this project, you are only permitted to use the Python standard library and the third party modules numpy and matplotlib. You may not use PIL or OpenCV for image processing. You are also not allowed to use any external libraries for encryption or decryption. You must implement the Caesar, Rail Fence, and Beaufort ciphers from scratch.

The image filenames use the following convention.

  • Suffixes _p, _e, _c, _r, or _b, denote the type of cipher used—Plaintext, Encoded (with text), Caesar, Rail Fence, or Beaufort, respectively.

  • The characters _col or _gry in the filename indicates whether the image is colored or grayscale.

To ensure your code is organized and easy to understand, structure your program using functions. Modular code allows for better collaboration within your team, making it easier to discuss ideas, debug issues, and integrate different parts of the project seamlessly. Working together, you can design and implement user-defined functions that perform specific tasks, accept necessary inputs, and return desired outputs. Avoid dividing the tasks to work individually; instead, engage in collective problem-solving to enhance your learning experience.