Data Encryption Standard: Part 4
September 10, 2010
Here’s our version:
(let-values (((opts files)
(getopt "d:e:h:p:i:k:1:2:3:"
"usage: {-dmode|-emode|-hn|-ppasswd} [-isalt] {-kkey|-1key1 -2key2 [-3key3]} [filename]"
(cdr (command-line)))))
(let* ((opt (lambda (o) (let ((o (assoc o opts))) (if o (cdr o) o))))
(encode (lambda (block)
(if (assoc #\k opts)
(encipher (key-schedule (hex->bits (opt #\k))) block)
(encipher (key-schedule (hex->bits (opt #\1)))
(key-schedule (hex->bits (opt #\2)))
(key-schedule (hex->bits (if (opt #\3) (opt #\3) (opt #\1))))
block))))
(decode (lambda (block)
(if (assoc #\k opts)
(decipher (key-schedule (hex->bits (opt #\k))) block)
(decipher (key-schedule (hex->bits (opt #\1)))
(key-schedule (hex->bits (opt #\2)))
(key-schedule (hex->bits (if (opt #\3) (opt #\3) (opt #\1))))
block))))
(port (if (null? files) (current-input-port) (open-input-file (car files))))
(salt (lambda () (if (opt #\i) (hex->bits (opt #\i)) (ascii->bits (read8 port))))))
(cond
((opt #\d)
(cond ((string-ci=? (opt #\d) "ECB") (ecb-decipher decode port))
((string-ci=? (opt #\d) "CBC") (cbc-decipher decode (salt) port))
((string-ci=? (opt #\d) "CFB") (cfb-decipher encode (salt) port))
((string-ci=? (opt #\d) "OFB") (ofb-decipher encode (salt) port))))
((opt #\e)
(cond ((string-ci=? (opt #\e) "ECB") (ecb-encipher encode port))
((string-ci=? (opt #\e) "CBC") (cbc-encipher encode (salt) port))
((string-ci=? (opt #\e) "CFB") (cfb-encipher encode (salt) port))
((string-ci=? (opt #\e) "OFB") (cfb-encipher encode (salt) port))))
((opt #\h)
(display (hash encode (string->number (opt #\h)) port)))
((opt #\p)
(display (password->key
(lambda (block)
(encipher (key-schedule (hex->bits "0123456789ABCDEF")) block))
(opt #\p)))))
(if (null? files) (close-input-port port))))
We reuse getopt
from a prior exercise, and all the cryptographic code from the previous three exercises. You can see the code assembled at http://programmingpraxis.codepad.org/naNZtKeh.