Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

RC4 encryption in lisp

24 views
Skip to first unread message

corey...@charter.net

unread,
Nov 4, 2000, 3:00:00 AM11/4/00
to

Hi all,

I've been trying to teach myself lisp for a while now. Below is
some lisp code to encrypt a message using the RC4 algorithm. It
is basically a literal translation of the C code for RC4 encryption
available on the internet. It produces the same results as the
test vectors given with the C code, so I believe it is correct.

What I'd like to know is, is there a 'better' way to write this.
Something that looks less like C code.

I'm not trying to squeeze maximum performance out of this, it's just
an exercise.

(defun make-new-rc4-codebook (key)
"Return an RC4 codebook initialized with key.
Key is 1 to 256 8 bit integers"
(let
((codebook (make-array '(256) :initial-element 0))
(index1 0)
(index2 0)
(tmp 0)
(key-length (length key)))

(do ((n 0 (+ 1 n)))
((= n 256) nil)
(setf (aref codebook n) n))

(do ((n 0 (+ 1 n)))
((= n 256) codebook)
(setf index2 (mod (+ (aref key index1) (aref codebook n) index2) 256))

(setf tmp (aref codebook n))
(setf (aref codebook n) (aref codebook index2))
(setf (aref codebook index2) tmp)

(setf index1 (mod (+ 1 index1) key-length)))))

(defun rc4-crypt (key msg)
"Encrypt msg using rc4 algorithm with key given"
(let ((codebook (make-new-rc4-codebook key))
(x 0)
(y 0)
(tmp nil))
(do ((n 0 (+ 1 n)))
((= n (length msg)) msg)

(setf y (mod (+ (setf tmp (aref codebook (setf x (mod (+ x 1)
256))))
y)
256))

(setf (aref codebook x) (aref codebook y))
(setf (aref codebook y) tmp)

(setf (aref msg n) (mod (logxor (aref msg n)
(aref codebook (mod (+ (aref codebook x)
(aref codebook y))
256)))
256)))))

(defun run-tests ()
"Run the tests"
;; Test vector 0
;; Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef
;; Input: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef
;; 0 Output: 0x75 0xb7 0x87 0x80 0x99 0xe0 0xc5 0x96
(let ((key (make-array '(8)
:initial-contents '(#x1 #x23 #x45 #x67 #x89 #xab #xcd #xef)))
(msg (make-array '(8)
:initial-contents '(#x1 #x23 #x45 #x67 #x89 #xab #xcd #xef)))
(*print-base* 16))
(print "key")
(print key)
(print "Input msg")
(print msg)
(print "output msg")
(print (rc4-crypt key msg))
;; Test vector 1
;; Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef
;; Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
;; 0 Output: 0x74 0x94 0xc2 0xe7 0x10 0x4b 0x08 0x79
(setf key (make-array '(8)
:initial-contents '(#x1 #x23 #x45 #x67 #x89 #xab #xcd #xef)))
(setf msg (make-array '(8)
:initial-contents '(0 0 0 0 0 0 0 0)))
(print "key")
(print key)
(print "Input msg")
(print msg)
(print "output msg")
(print (rc4-crypt key msg))

;; Test vector 2
;; Key: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
;; Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
;; 0 Output: 0xde 0x18 0x89 0x41 0xa3 0x37 0x5d 0x3a
(setf key (make-array '(8) :initial-contents '(0 0 0 0 0 0 0 0)))
(setf msg (make-array '(8) :initial-contents '(0 0 0 0 0 0 0 0)))
(print "key")
(print key)
(print "Input msg")
(print msg)
(print "output msg")
(print (rc4-crypt key msg))))

Rainer Joswig

unread,
Nov 4, 2000, 6:57:47 PM11/4/00
to
In article <87em0ri...@bobo.spike.home>, corey...@charter.net
wrote:

> Hi all,
>
> I've been trying to teach myself lisp for a while now. Below is
> some lisp code to encrypt a message using the RC4 algorithm. It
> is basically a literal translation of the C code for RC4 encryption
> available on the internet. It produces the same results as the
> test vectors given with the C code, so I believe it is correct.
>
> What I'd like to know is, is there a 'better' way to write this.
> Something that looks less like C code.

Maybe there is. You could use some more built-in functionality
like DOTIMES, LOOP and ROTATEF. Example:

(defun make-new-rc4-codebook (key)
"Return an RC4 codebook initialized with key.
Key is 1 to 256 8 bit integers"
(let ((codebook (make-array '(256) :initial-element 0))

(key-length (length key)))
(dotimes (n 256)


(setf (aref codebook n) n))

(loop for n below 256
for index1 = 0 then (mod (1+ index1) key-length)
with index2 = 0
do (setf index2 (mod (+ (aref key index1)


(aref codebook n)
index2)
256))

do (rotatef (aref codebook n) (aref codebook index2)))
codebook))

But this really doesn't change that much.


> (defun run-tests ()
> "Run the tests"

For experimenting with algorithms it is sometimes
quite handy to use a regression tester.

; deftest NAME FORM &rest VALUES

(rt:deftest "test1"
(rc4-crypt (make-array '(8) :initial-contents '(#x1 #x23 #x45 #x67 #x89 #xab #xcd #xef))


(make-array '(8) :initial-contents '(#x1 #x23 #x45 #x67 #x89 #xab #xcd #xef)))

#(#x75 #xb7 #x87 #x80 #x99 #xe0 #xc5 #x96))

(rt:do-tests)

You would need to modify the "RT" regression tester from
the CMU Lisp archive for your purpose.

--
Rainer Joswig, Hamburg, Germany
Email: mailto:jos...@corporate-world.lisp.de
Web: http://corporate-world.lisp.de/

0 new messages