Post Category: Miscellaneous

These are miscellaneous, possibly personal, topics that don’t fit into a specific category.

Implementation of SHA-1 in C

This algorithm implementation is a part of my cryptography implementations project. The full project, along with licensing information and more detail, is hosted on GitHub.

Algorithm

This is an implementation of the SHA-1 hash algorithm.

Documentation

  • SHA1_CTX
    A MD5 structure that will hold all hash-related data and calculations as the hash is calculated.

  • SHA1_init(SHA1_CTX *ctx)
    Initializes the SHA1_CTX object.

  • SHA1_update(SHA1_CTX *ctx, unsigned char data[], int len)
    Once an object has been created and initialized, the data to be hashed must be added. Due to practical limitations, it may not be optimal (or possible) to add all the data to the SHA1 hash in one data chunk, so the function inputs, stores, and calculates data as it is received, allowing the data to be added in as many chunks as necessary.

    • unsigned char data[] -- This is the data to be added to the hash.
    • int len -- This is the length, in bytes, of the data in the "data" array.
  • SHA1_final(SHA1_CTX *ctx, unsigned char hash[])
    Finalize and output the hash.
    • unsigned char hash[] -- This is the array to store the output hash. It must be at least 16 bytes in size.

Code Usage

  1. Create an SHA1_CTX object.
  2. Initialize it with sha1_init().
  3. Read some/all of the data to hash into an array, calculate the size of the data, and add it to the hash with sha1_update().
  4. Repeat the previous step for all the data you want to hash.
  5. Finalize and output the hash with sha1_final().

Repeat steps (2) to (5) for as many hashes as you want to calculate.

Code

Notes

The 32-bit words (which in this case are unsigned integers) used in the code use little endian byte ordering. The SHA-1 specification uses the big endian byte order, so some byte-reversals are made when copying data into and out of integers in this code.

This algorithm has not been well optimized, although some general attempts have been made to that effect. This algorithm has passed numerous test vectors (including all official ones) successfully.

This algorithm can hash data up to 264 bits (2,147,483,648 gigabytes) in length.

It is worth noting that SHA-1 is no longer considered a perfectly secure hash algorithm. It is recommended that a hash algorithm such as Whirlpool or RIPE-MD, or even SHA-1 with double the number of standard rounds, be used in when security is critical.

Implementation of MD5 in C

This algorithm implementation is a part of my cryptography implementations project. The full project, along with licensing information and more detail, is hosted on GitHub.

Algorithm

This is an implementation of the MD5 hash algorithm.

Documentation

  • MD5_CTX
    A MD5 structure that will hold all hash-related data and calculations as the hash is calculated.
  • md5_init(MD5_CTX *ctx)
    Initializes the MD5_CTX object.
  • md5_update(MD5_CTX *ctx, unsigned char data[], int len)
    Once an object has been created and initialized, the data to be hashed must be added. Due to practical limitations, it may not be optimal (or possible) to add all the data to the MD5 hash in one data chunk, so the function inputs, stores, and calculates data as it is received, allowing the data to be added in as many chunks as necessary.

    • unsigned char data[] -- This is the data to be added to the hash.
    • int len -- This is the length, in bytes, of the data in the "data" array.
  • md5_final(MD5_CTX *ctx, unsigned char hash[])
    Finalize and output the hash.
    • unsigned char hash[] -- This is the array to store the output hash. It must be at least 16 bytes in size.

Usage

  1. Create an MD5_CTX object.
  2. Initialize it with md5_init().
  3. Read some/all of the data to hash into an array, calculate the size of the data, and add it to the hash with md5_update().
  4. Repeat the previous step for all the data you want to hash.
  5. Finalize and output the hash with md5_final().

Repeat steps (2) to (5) for as many hashes as you want to calculate.

Code

Notes

The 32-bit words (which in this case are unsigned integers) used in the code assume little endian byte ordering. The MD5 specification uses the big endian byte order, so some byte-reversals are made when copying data into and out of integers in this code.

This algorithm has not been well optimized, although some general attempts have been made to that effect. This algorithm has passed numerous test vectors (including all official ones) accurately.

This algorithm can hash data of lengths up to 264 bits (2,147,483,648 gigabytes).

Note, that MD5 is no longer considered a reasonably secure hash algorithm. It is recommended that a hash algorithm such as SHA-1 or SHA-2 be used instead for cryptographic applications.

Implementation of MD2 in C

This algorithm implementation is a part of my cryptography implementations project. The full project, along with licensing information and more detail, is hosted on GitHub.

Algorithm

This is an implementation of the MD2 hash algorithm. This algorithm can hash data of any given length.

Code Documentation

  • MD2_CTX
    A MD2 object that will hold all hash-related data and calculations as the hash is calculated.
  • md2_init(MD2_CTX *ctx)
    Initialize the MD2_CTX object.
  • md2_update(MD2_CTX *ctx, unsigned char data[], int len)
    Once an object has been created and initialized, the data to be hashed must be added. Due to practical limitations, it may not be optimal (or possible) to add all the data to the MD2 hash in one data chunk, so the function inputs, stores, and calculates data as it is received, allowing the data to be added in as many chunks as necessary.
    • unsigned char data[] -- This is the data to be added to the running hash context.
    • int len -- This is the length, in bytes, of the data in the "data" array.
  • md2_final(MD2_CTX *ctx, unsigned char hash[])
    Finalize and output the hash.
    • unsigned char hash[] -- This is the array to store the output hash. It must be at least 16 bytes in size.

Code Usage

  1. Create an MD2_CTX object.
  2. Initialize it with md2_init().
  3. Read some/all of the data to hash into an array, calculate the size of the data, and add it to the hash with md2_update().
  4. Repeat the previous step for all the data you want to hash.
  5. Finalize and output the hash with md2_final().

Repeat steps (2) to (5) for as many hashes as you want to calculate.

Code

Notes

This implementation assumes little endian byte ordering (as the MD2 standard states it should). This algorithm not only has not been optimized, although some general attempts have been made to that effect. This implementation of MD2 has been tested against numerous test vectors (including all official ones) and has proved to be accurate.

Note that MD2 is not considered a secure hash algorithm. It is recommended that a hash algorithm such as SHA-1 or SHA-2 be used, as MD2 is grossly outdated.

How Not to Design a Campaign Billboard

I currently live in a rural California setting, situated in Congressional District #4. We are currently represented in the House of Representatives by Congressman John Doolittle, a guy who's made a very solid political career for himself despite having one of the worst last names imaginable for a politician.

It's five days (as of writing this) until the California primary elections are held, and, as always, campaign billboards and banners are out in full swing, offering information such as, "Dave Johnson: Values we trust" and "Joe Clark: Professionalism, Integrity, Good Hair," and other vital voter information that the general public, come election day, will use to place an informed vote for the candidate who they have seen the most billboards for. (Pardon the snark, but I hate billboards.)

One such campaign banner caught my attention -- not because of what it said, but rather because of what it failed to say. I've spotted this banner, pictured below, in a lot of places, one of which is by the main street near my house.

Billboard image from road

This photograph was taken from a car on the road, so that's basically exactly what it looks like to a driver. At first glance, it looks like just another billboard that serves no purpose other than to display the candidate's name (in this case, that of Congressman Doolittle's) in big, bold letters, in an effort to boost the candidate's name-recognition. It's pathetic that so much political campaign advertising is this shallow, but it works. As a political candidate, simply getting your name as recognizable as possible by the public is a huge part of winning an election, and it appears that Congressman Doolittle understands this idea.

Here's another picture of the same sign, this time a little bit closer and taken from the side of the road.

Billboard image from side of road

Again, it's Congressman Dolittle's name in big white letters contrasted against a solid black background. But this time the text above his name is more obvious. Let's take a closer look at what it says.

Billboard image close up

Surprise -- the banner is not for Congressman Dolittle after all. The text above his name reads, "How do you spell corruption?", and it's followed by "Congressman Doolittle".

The sheer level advertising fail being exhibited here leaves me in awe. Whoever sponsored this campaign banner intended to approve the design of a billboard intended deface someone, but actually managed to approve putting their name in big, bold letters and the message defaming him in smaller, harder to read, letters against a poor contrast background, creating an effect such that Doolittle's name glares out broadly and clearly but the message against him basically blurs out and gets lost.

Close up, all of the board's text is easily readable. But as you can see from the first two photographs, the most critical part of the text isn't so obvious to a driver. Scratch that, it isn't obvious at all. I drove past that sign several times a week for at least 3 weeks before I noticed what it actually said.

The average driver, judging from the driving habits I've seen, isn't necessarily watching the road, much less scrutinizing every bit of political propaganda that they see. Your average driver is coming home from a long day of work, rushing to the store before it closes, thinking about the term paper, or trying to remember whether or not they remembered to close the garage door when they left the house. Whatever their situation, they are not interested in scrutinizing a hard-to-read by the road.

When it comes to boring roadside banners, making it such that the reader has to exert effort to get the message will lose you 90% of your audience. You have to make the message obvious or it won't be read.

But even though the banner fails to get the desired message across, the true marvel of it is that it actually may do its sponsor more harm than good. The least effective job a poorly designed political billboard can do is not be comprehensible, and thus not result in any net gain for the candidate sponsoring it. But this billboard actually scores negatively, because it not only fails to make its real message readable, but it blatantly looks like a billboard supporting the opponent. Doolittle's name is in big letters, while the message against him is obscured. To the average passer-by, this looks like an ad for Doolittle.

So what lesson did we learn? Simple: If you have to create a visual advertisement, be sure to consider how and where your audience will see it. Make your message obvious, and, above all else, do not leave any room for misinterpretation. Readers are much more likely to remember a name than a concept, so ensure that any information you provide about a name you're trying to defame is more obvious than the name itself.

I wonder if Doolittle chuckles himself to sleep at night, thinking of the free advertising he got from his opponents (and this article).

Implementation of ROT13 in C

This algorithm implementation is a part of my cryptography implementations project (despite not really qualifying as a cryptographic algorithm). The full project, along with licensing information and more detail, is hosted on GitHub.

Algorithm

This is a implementation of the ROT-13 Ceaser Cipher.

To encrypt a string of alphabetic characters using ROT-13, take each character and move forward in the alphabet by 13 places, wrapping back to 'A' when 'Z' is encountered, ie: A becomes N, B becomes O, S becomes F, Z becomes M, etc.

Given that the alphabet has 26 letters, taking ROT-13 of a character and then taking ROT-13 of that character will yield the original character you started with. This means that the mapping between characters is two-way, so not only does A map to N, but N also maps to A. Because of this, ROT-13 is its own inverse function, meaning that it both encrypts and decrypts text.

Usage

ROT-13 is its own complement function, so the same function encrypts and decrypts. To en/decrypt a string, use the function rot13(), passing the string with the text to be rotated as the only argument.

Code

Code Structure

To encrypt/decrypt a string with ROT-13, we follow a simple algorithm:

  • For each character in the string, we first determine if it is in the ASCII alphabet range, if it isn't, then we skip it.
  • We then determine the character's case (upper/lower).
  • We increase the character's value by 13 and check to see if it went past the Z value.
  • If it did go past Z, then we take the amount that went over Z and we add to it the value of 'A' or 'a', depending on the character's case.

Notes

This implementation assumes the character string is in ASCII.

ROT-13 has a couple of special cases that need to be addressed, namely, how numbers and punctuation are treated, and whether or not character case is preserved. Different modifications of ROT-13 will sometimes apply "ROT-5" (in the same vain as to ROT-13) to the numbers, and ROT-X (depending on the number of accepted characters) to the punctuation. This implementation sticks to the simple bare-bones ROT-13 and ignores all non-alphabetic characters. It also preserves the original case of the characters.

Implementation of RC4 in C

This algorithm implementation is a part of my cryptography implementations project. The full project, along with licensing information and more detail, is hosted on GitHub.

The Algorithm

This is an implementation of the RC4 (also known as "ARCFOUR" for copyright reasons) stream cipher in C.

There are two steps to the cipher. First, the KSA function uses a user-supplied key to initialize the "state" matrix. Then, the PRGA function uses the state to generate pseudo-random output of any desired length, called the keystream. For encryption, this keystream is XOR'd by the plaintext to yield ciphertext. For decryption, the keystream is XOR'd by the ciphertext to yield plaintext.

Documentation

  • void ksa(unsigned char state[], unsigned char key[], int len)
    The KSA function takes a state and key and permutates the state with the key.

    • unsigned char state[] -- This is the state that will be initialized by the key. It must be 256 bytes in size.
    • unsigned char key[] --
      This is the key to use for encryption/decryption.
    • int len -- This is the length of the key in bytes.
  • void prga(unsigned char state[], unsigned char out[], int len)
    The PRGA function generates the keystream. The state is permutated to generate each byte of the keystream, and its original value is not saved. So generating 8 bytes of output in one function call followed by 8 more bytes of output in separate function call will yield the same keystream as generating all 16 bytes of output in one function call.

    • unsigned char state[] -- The state array initialized by ksa().
    • unsigned char out[] -- The array to store the output in. This is XOR'd by the plaintext/ciphertext. It must be the length of the "len" (below) value.
    • int len -- The number of bytes to generate.

Usage

  1. Create a state array of necessary size, generate a key, and determine it's size.
  2. Call the KSA() function.
  3. Call the PRGA() function.
  4. XOR the output from PRGA() against the plaintext/ciphertext to yield the desired ciphertext/plaintext.

Code

Notes

In this implementation, the state is an 256-byte unsigned character array. Due to its minimal nature RC4 allows for little by way of optimization.

Cryptanalysis of RC4 has been shown that weaknesses in the algorithm allow the first 256 bytes of the keystream to be used to extrapolate the original key. When generating a keystream, it is recommended that you always discard the first 256 bytes of output, or the first 1K of bytes, just to be safe.