Coverage report: /home/ellis/comp/ext/ironclad/src/ciphers/idea.lisp
Kind | Covered | All | % |
expression | 0 | 360 | 0.0 |
branch | 0 | 20 | 0.0 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;;; idea.lisp -- implementation of the IDEA block cipher
3
;;; converted mostly from the C code appearing in _Applied Cryptography_
4
;;; by Bruce Schneier to Common Lisp. Beware the C-isms.
8
(declare (type (unsigned-byte 16) a b))
10
((zerop a) (ldb (byte 16 0) (- 1 b)))
11
((zerop b) (ldb (byte 16 0) (- 1 a)))
13
(let* ((product (ldb (byte 32 0) (* a b)))
14
(x (ldb (byte 16 16) product))
15
(y (ldb (byte 16 0) product)))
16
(ldb (byte 16 0) (+ (- y x) (if (< y x) 1 0)))))))
18
(defun idea-mul-inv (x)
19
(declare (type (unsigned-byte 16) x))
21
(declare (type (unsigned-byte 16) t1))
23
(return-from idea-mul-inv x))
24
(multiple-value-bind (t0 y) (truncate 65537 x)
25
(declare (type (unsigned-byte 16) t0 y))
27
do (let ((q (truncate x y)))
28
(declare (type (unsigned-byte 16) q))
30
(incf t1 (ldb (byte 16 0) (* q t0)))
32
(return-from idea-mul-inv t1))
33
(setf q (truncate y x))
35
(incf t0 (ldb (byte 16 0) (* q t1))))
36
finally (return (ldb (byte 16 0) (- 1 t0)))))))
38
(deftype idea-round-keys () '(simple-array (unsigned-byte 16) (52)))
40
(defun idea-munge-block (input input-start output output-start keys)
41
(declare (type (simple-array (unsigned-byte 8) (*)) input output))
42
(declare (type (integer 0 #.(- array-dimension-limit 8))
43
input-start output-start))
44
(declare (type idea-round-keys keys))
45
(with-words ((x1 x2 x3 x4) input input-start :size 2)
49
(setf x1 (idea-mul x1 (aref keys 48))
50
x2 (ldb (byte 16 0) (+ x2 (aref keys 50)))
51
x3 (ldb (byte 16 0) (+ x3 (aref keys 49)))
52
x4 (idea-mul x4 (aref keys 51)))
53
(store-words output output-start x1 x3 x2 x4))
54
(setf x1 (idea-mul x1 (aref keys i))
55
x2 (ldb (byte 16 0) (+ x2 (aref keys (+ i 1))))
56
x3 (ldb (byte 16 0) (+ x3 (aref keys (+ i 2))))
57
x4 (idea-mul x4 (aref keys (+ i 3))))
60
(setf x3 (idea-mul (logxor x3 x1) (aref keys (+ i 4)))
61
x2 (idea-mul (ldb (byte 16 0)
62
(+ (logxor x2 x4) x3))
64
(setf x3 (ldb (byte 16 0) (+ x3 x2))
68
x3 (logxor x3 t0))))))
70
(defclass idea (cipher 8-byte-block-mixin)
71
((encryption-keys :accessor encryption-keys)
72
(decryption-keys :accessor decryption-keys)))
74
(define-block-encryptor idea 8
75
(idea-munge-block plaintext plaintext-start ciphertext ciphertext-start
76
(encryption-keys context)))
78
(define-block-decryptor idea 8
79
(idea-munge-block ciphertext ciphertext-start plaintext plaintext-start
80
(decryption-keys context)))
82
(defun idea-invert-key (encryption-keys decryption-keys)
83
(declare (type idea-round-keys encryption-keys decryption-keys))
84
(setf (aref decryption-keys 51) (idea-mul-inv (aref encryption-keys 3))
85
(aref decryption-keys 50) (ldb (byte 16 0) (- (aref encryption-keys 2)))
86
(aref decryption-keys 49) (ldb (byte 16 0) (- (aref encryption-keys 1)))
87
(aref decryption-keys 48) (idea-mul-inv (aref encryption-keys 0)))
92
(setf (aref decryption-keys 5) (aref encryption-keys 47)
93
(aref decryption-keys 4) (aref encryption-keys 46)
94
(aref decryption-keys 3) (idea-mul-inv (aref encryption-keys 51))
95
(aref decryption-keys 2) (ldb (byte 16 0) (- (aref encryption-keys 50)))
96
(aref decryption-keys 1) (ldb (byte 16 0) (- (aref encryption-keys 49)))
97
(aref decryption-keys 0) (idea-mul-inv (aref encryption-keys 48)))
99
(flet ((set-decryption-key (x)
100
(setf (aref decryption-keys counter) x)
102
(declare (inline set-decryption-key))
103
(set-decryption-key (aref encryption-keys (+ k 1)))
104
(set-decryption-key (aref encryption-keys k))
105
(set-decryption-key (idea-mul-inv (aref encryption-keys (+ k 5))))
106
(set-decryption-key (ldb (byte 16 0) (- (aref encryption-keys (+ k 3)))))
107
(set-decryption-key (ldb (byte 16 0) (- (aref encryption-keys (+ k 4)))))
108
(set-decryption-key (idea-mul-inv (aref encryption-keys (+ k 2)))))))
110
(defun idea-key-schedule (key)
111
(declare (type (simple-array (unsigned-byte 8) (16)) key))
112
(let ((encryption-keys (make-array 52 :element-type '(unsigned-byte 16)))
113
(decryption-keys (make-array 52 :element-type '(unsigned-byte 16))))
114
(declare (type idea-round-keys encryption-keys decryption-keys))
116
(setf (aref encryption-keys i) (ub16ref/be key (* i 2))))
117
(do ((j 1 (1+ (mod j 8)))
120
((>= k 52) (values encryption-keys (idea-invert-key encryption-keys
122
(setf (aref encryption-keys (+ j 7 offset))
124
(logior (ash (aref encryption-keys (+ (mod j 8) offset)) 9)
125
(ash (aref encryption-keys (+ (mod (1+ j) 8) offset)) -7))))
126
(incf offset (if (= j 8) 8 0)))))
128
(defmethod schedule-key ((cipher idea) key)
129
(declare (type (simple-array (unsigned-byte 8) (16)) key))
130
(multiple-value-bind (encryption-keys decryption-keys)
131
(idea-key-schedule key)
132
(setf (encryption-keys cipher) encryption-keys
133
(decryption-keys cipher) decryption-keys)
137
(:encrypt-function idea-encrypt-block)
138
(:decrypt-function idea-decrypt-block)
140
(:key-length (:fixed 16)))