Data Encryption Standard: Part 3

September 7, 2010

All of the hard work has been done in previous exercises, making this simple. Here is Triple DES:

(define (triple-encipher ks1 ks2 ks3 block)
  (encipher ks3 (decipher ks2 (encipher ks1 block))))

(define (triple-decipher ks1 ks2 ks3 block)
  (decipher ks1 (encipher ks2 (decipher ks3 block))))

Hashing is a simple variant of cbc-encipher, in which the intermediate calculations are performed but the encrypted output isn’t written. When the last block is computed, the requested number of leading bits is output:

(define (hash encipher n port)
  (define (encode prev txt) (encipher (vector-xor (ascii->bits txt) prev)))
  (let loop ((prev (make-vector 64 0)) (txt (read8 port)))
    (cond ((eof-object? txt)
            (bits->hex (vector-slice (encode prev (pad "")) 0 n)))
          ((hex (vector-slice (encode prev (pad txt)) 0 n)))
          (else (let ((next (encode prev txt)))
                  (loop next (read8 port)))))))

Converting a password to a key is a simple application of hashing:

(define (password->key encipher passwd)
  (define (make-odd bits)
    (let ((bs (vector->list bits)))
      (append bs (list (if (even? (apply + bs)) 1 0)))))
  (let ((p (with-input-from-string passwd (lambda ()
           (hex->bits (hash encipher 56 (current-input-port)))))))
    (bits->hex (list->vector (apply append (map make-odd (vector-slice-by 7 p)))))))

You can see the code at http://programmingpraxis.codepad.org/hI295Aff, including all the contributions from previous exercises.

Pages: 1 2

Leave a comment