-
Notifications
You must be signed in to change notification settings - Fork 36
/
xtea.lisp
64 lines (58 loc) · 2.68 KB
/
xtea.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
(in-package :crypto)
(defconstant +xtea-n-rounds+ 32)
(defconstant +xtea-delta+ #x9e3779b9)
(defclass xtea (cipher 8-byte-block-mixin)
((key :accessor key)))
(define-block-encryptor xtea 8
(with-words ((y z) plaintext plaintext-start)
(let ((key (key context))
(sum 0))
(declare (type (simple-array (unsigned-byte 32) (4)) key))
(declare (type (unsigned-byte 32) sum))
;; could probably unroll this loop for reasonable performance gain
(dotimes (i +xtea-n-rounds+)
(setf y (mod32+ y (logxor (mod32+ z (logxor (mod32ash z 4)
(mod32ash z -5)))
(mod32+ sum
(aref key (logand sum #x3))))))
(setf sum (mod32+ sum +xtea-delta+))
(setf z (mod32+ z (logxor (mod32+ y (logxor (mod32ash y 4)
(mod32ash y -5)))
(mod32+ sum
(aref key (logand (mod32ash sum -11)
#x3))))))
)
(store-words ciphertext ciphertext-start y z))))
(define-block-decryptor xtea 8
(with-words ((y z) ciphertext ciphertext-start)
(let ((key (key context))
(sum (mod32ash +xtea-delta+ 5)))
(declare (type (simple-array (unsigned-byte 32) (4)) key))
(declare (type (unsigned-byte 32) sum))
;; could probably unroll this loop for reasonable performance gain
(dotimes (i +xtea-n-rounds+)
(setf z (mod32- z (logxor (mod32+ y (logxor (mod32ash y 4)
(mod32ash y -5)))
(mod32+ sum
(aref key (logand (mod32ash sum -11)
#x3))))))
(setf sum (mod32- sum +xtea-delta+))
(setf y (mod32- y (logxor (mod32+ z (logxor (mod32ash z 4)
(mod32ash z -5)))
(mod32+ sum
(aref key (logand sum #x3)))))))
(store-words plaintext plaintext-start y z))))
(defmethod schedule-key ((cipher xtea) key)
(let ((ub32key (make-array 4 :element-type '(unsigned-byte 32))))
(with-words ((a b c d) key 0)
(setf (aref ub32key 0) a
(aref ub32key 1) b
(aref ub32key 2) c
(aref ub32key 3) d)
(setf (key cipher) ub32key)
cipher)))
(defcipher xtea
(:encrypt-function xtea-encrypt-block)
(:decrypt-function xtea-decrypt-block)
(:block-length 8)
(:key-length (:fixed 16)))