DES in Haskell

August 25, 2009

I implemented the Data Encryption Standard (DES) encryption algorithm for a Cryptography class I took in college.

I decided to use Haskell since I was learning it at the time. To run (under Windows, and assuming you have GHC installed) double-click DES.hs and you can then use the following functions:

encrypt “plaintext” “key”

decrypt “plaintext” “key”

Both plaintext and key are hexadecimal strings of 16 characters each, equivalent to 64-bit binary blocks.

Sample usage:

*DES> encrypt “675A69675E5A6B5A” “5B5A57676A56676E”
*DES> decrypt “974affbf86022d1f” “5B5A57676A56676E”

Most of the constant data like the S-boxes and shift schedule was taken verbatim from the post Feistel Ciphers and DES inĀ Haskell at codeland. However there was a problem with some of the constant data in the post (I think it was one of the permutations) that led me to the DES specification for the proper data.

Keep in mind that the code isn’t optimized at all, for example, look at the following line:

— drop first bit and last bit
c = binToDec (reverse (drop 1 (reverse (drop 1 input))))

That is obviously a foolish way to chop of the first and the last bit, but hey, I was a beginner at the time.

You can download the code here.

Merge sort (in Haskell)

March 24, 2009

-- Merge sort
-- Date: Tuesday, March 24, 2009

-- sort a list using merge sort
mergesort [s] =
mergesort a =
		mid = ceiling ((fromIntegral (length a))/2)
		(f,s) = splitAt mid a
		merge (mergesort f) (mergesort s)

-- merge two lists
merge :: (Ord t) => [t] -> [t] -> [t]
merge a@(ah:at) b@(bh:bt)
	| ah < bh =
		[ah] ++ merge at b
	| otherwise =
		[bh] ++ merge a bt
-- base case 1: second list empty so we just add everything in a to the end
-- Note: Case [] [] is handled here as well
merge a [] =
-- base case 2: same as above except it is for first list empty
merge [] b =
# Insertion sort
# Date: Tuesday, March 24, 2009

print 'Insertion sort\n'
print 'How many numbers would you like to enter: '
num = input()

print 'Please enter ' + str(num) + ' numbers'

numbers = []
for i in range(num):
    numbers += [input()]

for j in range(1, num):
    key = numbers[j]
    i = j-1
    # Keep shifting elements to the right until the right position is found
    while numbers[i] > key and i >= 0:
        numbers[i+1] = numbers[i]
        i = i - 1
    numbers[i+1] = key