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.

Pages: 1 2

Leave a comment