(ql:quickload :cl-base64) (ql:quickload :iterate) (ql:quickload :fiveam) (use-package :iterate) (use-package :fiveam) (def-suite cryptopals) (in-suite cryptopals) (defun hex-to-dec (hex-chr) (cond ((char<= #\0 hex-chr #\9) (- (char-code hex-chr) (char-code #\0))) ((char<= #\a hex-chr #\f) (+ (- (char-code hex-chr) (char-code #\a)) 10)) ((char<= #\A hex-chr #\F) (+ (- (char-code hex-chr) (char-code #\A)) 10)))) (defun dec-to-hex (dec-chr) (cond ((<= 0 dec-chr 9) (code-char (+ (char-code #\0) dec-chr))) ((<= 10 dec-chr 15) (code-char (+ (char-code #\a) (- dec-chr 10)))))) (defun hex-to-bytes (hex-str) (iter (for i below (length hex-str) by 2) (let ((c1 (hex-to-dec (aref hex-str i))) (c2 (hex-to-dec (aref hex-str (1+ i))))) (collect (+ (* 16 c1) c2) result-type (vector (unsigned-byte 8)))))) (defun bytes-to-hex (bytes) (iter (for i in-vector bytes) (collect (dec-to-hex (ash (logand i #xff) -4)) result-type string) (collect (dec-to-hex (logand i #xf)) result-type string))) ;; set 1 challenge 1 (defun hex-to-base64 (hex-str) (cl-base64:usb8-array-to-base64-string (hex-to-bytes hex-str))) (test s1c1 (let ((in "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d") (out "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t")) (is (string= (hex-to-base64 in) out)))) ;; set 1 challenge 2 (defun fixed-xor (s1 s2) (bytes-to-hex (iter (for x in-vector (hex-to-bytes s1)) (for y in-vector (hex-to-bytes s2)) (collect (logxor x y) result-type (vector (unsigned-byte 8)))))) (test s1c2 (let ((in1 "1c0111001f010100061a024b53535009181c") (in2 "686974207468652062756c6c277320657965") (out "746865206b696420646f6e277420706c6179")) (is (string= (fixed-xor in1 in2) out)))) (run! 'cryptopals)