Coverage report: /home/ellis/comp/ext/ironclad/src/ciphers/square.lisp
Kind | Covered | All | % |
expression | 0 | 353 | 0.0 |
branch | 0 | 8 | 0.0 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;;; square.lisp -- implementation of the Square block cipher
3
;; based on a public domain implementation by Paulo Baretto (FIXME!)
5
(in-ironclad-readtable)
7
(declaim (type (simple-array (unsigned-byte 8) (256))
9
(eval-when (:compile-toplevel :load-toplevel :execute)
11
#.(let ((table (make-array 256 :element-type '(unsigned-byte 8)
15
(let ((j (ash (aref table (1- i)) 1)))
17
(setf j (logxor j #x1f5)))
18
(setf (aref table i) (logand j #xff))))))
22
#.(let ((table (make-array 256 :element-type '(unsigned-byte 8)
25
((>= i 256) (setf (aref table 1) 0) table)
26
(setf (aref table (aref alogtable i)) i))))
28
(declaim (type (simple-array (unsigned-byte 8) (4 4))
29
g-matrix inverse-g-matrix))
30
(defconst g-matrix (make-array (list 4 4) :element-type '(unsigned-byte 8)
36
(defconst inverse-g-matrix (make-array (list 4 4) :element-type '(unsigned-byte 8)
38
(list (list #xe #x9 #xd #xb)
39
(list #xb #xe #x9 #xd)
40
(list #xd #xb #xe #x9)
41
(list #x9 #xd #xb #xe))))
43
(declaim (type (simple-array (unsigned-byte 8) (256))
44
s-encryption-table s-decryption-table))
45
(defconst s-encryption-table
46
#8@(177 206 195 149 90 173 231 2 77 68 251 145 12 135 161 80
47
203 103 84 221 70 143 225 78 240 253 252 235 249 196 26 110
48
94 245 204 141 28 86 67 254 7 97 248 117 89 255 3 34
49
138 209 19 238 136 0 14 52 21 128 148 227 237 181 83 35
50
75 71 23 167 144 53 171 216 184 223 79 87 154 146 219 27
51
60 200 153 4 142 224 215 125 133 187 64 44 58 69 241 66
52
101 32 65 24 114 37 147 112 54 5 242 11 163 121 236 8
53
39 49 50 182 124 176 10 115 91 123 183 129 210 13 106 38
54
158 88 156 131 116 179 172 48 122 105 119 15 174 33 222 208
55
46 151 16 164 152 168 212 104 45 98 41 109 22 73 118 199
56
232 193 150 55 229 202 244 233 99 18 194 166 20 188 211 40
57
175 47 230 36 82 198 160 9 189 140 207 93 17 95 1 197
58
159 61 162 155 201 59 190 81 25 31 63 92 178 239 74 205
59
191 186 111 100 217 243 62 180 170 220 213 6 192 126 246 102
60
108 132 113 56 185 29 127 157 72 139 42 218 165 51 130 57
61
214 120 134 250 228 43 169 30 137 96 107 234 85 76 247 226))
63
(defconst s-decryption-table
64
#8@(53 190 7 46 83 105 219 40 111 183 118 107 12 125 54 139
65
146 188 169 50 172 56 156 66 99 200 30 79 36 229 247 201
66
97 141 47 63 179 101 127 112 175 154 234 245 91 152 144 177
67
135 113 114 237 55 69 104 163 227 239 92 197 80 193 214 202
68
90 98 95 38 9 93 20 65 232 157 206 64 253 8 23 74
69
15 199 180 62 18 252 37 75 129 44 4 120 203 187 32 189
70
249 41 153 168 211 96 223 17 151 137 126 250 224 155 31 210
71
103 226 100 119 132 43 158 138 241 109 136 121 116 87 221 230
72
57 123 238 131 225 88 242 13 52 248 48 233 185 35 84 21
73
68 11 77 102 58 3 162 145 148 82 76 195 130 231 128 192
74
182 14 194 108 147 236 171 67 149 246 216 70 134 5 140 176
75
117 0 204 133 215 61 115 122 72 228 209 89 173 184 198 208
76
220 161 170 2 29 191 181 159 81 196 165 16 34 207 1 186
77
143 49 124 174 150 218 240 86 71 212 235 78 217 19 142 73
78
85 22 255 59 244 164 178 6 160 167 251 27 110 60 51 205
79
24 94 106 213 166 33 222 254 42 28 243 10 26 25 39 45))
81
(declaim (type (simple-array (unsigned-byte 32) (256))
82
t-encryption-table t-decryption-table))
83
(defconst t-encryption-table
84
#32@(#x97b1b126 #x69cecea7 #x73c3c3b0 #xdf95954a
85
#xb45a5aee #xafadad02 #x3be7e7dc #x04020206
86
#x9a4d4dd7 #x884444cc #x03fbfbf8 #xd7919146
87
#x180c0c14 #xfb87877c #xb7a1a116 #xa05050f0
88
#x63cbcba8 #xce6767a9 #xa85454fc #x4fdddd92
89
#x8c4646ca #xeb8f8f64 #x37e1e1d6 #x9c4e4ed2
90
#x15f0f0e5 #x0ffdfdf2 #x0dfcfcf1 #x23ebebc8
91
#x07f9f9fe #x7dc4c4b9 #x341a1a2e #xdc6e6eb2
92
#xbc5e5ee2 #x1ff5f5ea #x6dcccca1 #xef8d8d62
93
#x381c1c24 #xac5656fa #x864343c5 #x09fefef7
94
#x0e070709 #xc26161a3 #x05f8f8fd #xea75759f
95
#xb25959eb #x0bfffff4 #x06030305 #x44222266
96
#xe18a8a6b #x57d1d186 #x26131335 #x29eeeec7
97
#xe588886d #x00000000 #x1c0e0e12 #x6834345c
98
#x2a15153f #xf5808075 #xdd949449 #x33e3e3d0
99
#x2fededc2 #x9fb5b52a #xa65353f5 #x46232365
100
#x964b4bdd #x8e4747c9 #x2e171739 #xbba7a71c
101
#xd5909045 #x6a35355f #xa3abab08 #x45d8d89d
102
#x85b8b83d #x4bdfdf94 #x9e4f4fd1 #xae5757f9
103
#xc19a9a5b #xd1929243 #x43dbdb98 #x361b1b2d
104
#x783c3c44 #x65c8c8ad #xc799995e #x0804040c
105
#xe98e8e67 #x35e0e0d5 #x5bd7d78c #xfa7d7d87
106
#xff85857a #x83bbbb38 #x804040c0 #x582c2c74
107
#x743a3a4e #x8a4545cf #x17f1f1e6 #x844242c6
108
#xca6565af #x40202060 #x824141c3 #x30181828
109
#xe4727296 #x4a25256f #xd3939340 #xe0707090
110
#x6c36365a #x0a05050f #x11f2f2e3 #x160b0b1d
111
#xb3a3a310 #xf279798b #x2dececc1 #x10080818
112
#x4e272769 #x62313153 #x64323256 #x99b6b62f
113
#xf87c7c84 #x95b0b025 #x140a0a1e #xe6737395
114
#xb65b5bed #xf67b7b8d #x9bb7b72c #xf7818176
115
#x51d2d283 #x1a0d0d17 #xd46a6abe #x4c26266a
116
#xc99e9e57 #xb05858e8 #xcd9c9c51 #xf3838370
117
#xe874749c #x93b3b320 #xadacac01 #x60303050
118
#xf47a7a8e #xd26969bb #xee777799 #x1e0f0f11
119
#xa9aeae07 #x42212163 #x49dede97 #x55d0d085
120
#x5c2e2e72 #xdb97974c #x20101030 #xbda4a419
121
#xc598985d #xa5a8a80d #x5dd4d489 #xd06868b8
122
#x5a2d2d77 #xc46262a6 #x5229297b #xda6d6db7
123
#x2c16163a #x924949db #xec76769a #x7bc7c7bc
124
#x25e8e8cd #x77c1c1b6 #xd996964f #x6e373759
125
#x3fe5e5da #x61cacaab #x1df4f4e9 #x27e9e9ce
126
#xc66363a5 #x24121236 #x71c2c2b3 #xb9a6a61f
127
#x2814143c #x8dbcbc31 #x53d3d380 #x50282878
128
#xabafaf04 #x5e2f2f71 #x39e6e6df #x4824246c
129
#xa45252f6 #x79c6c6bf #xb5a0a015 #x1209091b
130
#x8fbdbd32 #xed8c8c61 #x6bcfcfa4 #xba5d5de7
131
#x22111133 #xbe5f5fe1 #x02010103 #x7fc5c5ba
132
#xcb9f9f54 #x7a3d3d47 #xb1a2a213 #xc39b9b58
133
#x67c9c9ae #x763b3b4d #x89bebe37 #xa25151f3
134
#x3219192b #x3e1f1f21 #x7e3f3f41 #xb85c5ce4
135
#x91b2b223 #x2befefc4 #x944a4ade #x6fcdcda2
136
#x8bbfbf34 #x81baba3b #xde6f6fb1 #xc86464ac
137
#x47d9d99e #x13f3f3e0 #x7c3e3e42 #x9db4b429
138
#xa1aaaa0b #x4ddcdc91 #x5fd5d58a #x0c06060a
139
#x75c0c0b5 #xfc7e7e82 #x19f6f6ef #xcc6666aa
140
#xd86c6cb4 #xfd848479 #xe2717193 #x70383848
141
#x87b9b93e #x3a1d1d27 #xfe7f7f81 #xcf9d9d52
142
#x904848d8 #xe38b8b68 #x542a2a7e #x41dada9b
143
#xbfa5a51a #x66333355 #xf1828273 #x7239394b
144
#x59d6d68f #xf0787888 #xf986867f #x01fafafb
145
#x3de4e4d9 #x562b2b7d #xa7a9a90e #x3c1e1e22
146
#xe789896e #xc06060a0 #xd66b6bbd #x21eaeacb
147
#xaa5555ff #x984c4cd4 #x1bf7f7ec #x31e2e2d3))
149
(defconst t-decryption-table
150
#32@(#xe368bc02 #x5585620c #x2a3f2331 #x61ab13f7
151
#x98d46d72 #x21cb9a19 #x3c22a461 #x459d3dcd
152
#x05fdb423 #x2bc4075f #x9b2c01c0 #x3dd9800f
153
#x486c5c74 #xf97f7e85 #xf173ab1f #xb6edde0e
154
#x283c6bed #x4997781a #x9f2a918d #xc9579f33
155
#xa907a8aa #xa50ded7d #x7c422d8f #x764db0c9
156
#x4d91e857 #xcea963cc #xb4ee96d2 #x3028e1b6
157
#x0df161b9 #xbd196726 #x419bad80 #xc0a06ec7
158
#x5183f241 #x92dbf034 #x6fa21efc #x8f32ce4c
159
#x13e03373 #x69a7c66d #xe56d6493 #xbf1a2ffa
160
#xbb1cbfb7 #x587403b5 #xe76e2c4f #x5d89b796
161
#xe89c052a #x446619a3 #x342e71fb #x0ff22965
162
#xfe81827a #xb11322f1 #xa30835ec #xcd510f7e
163
#xff7aa614 #x5c7293f8 #x2fc29712 #xf370e3c3
164
#x992f491c #xd1431568 #xc2a3261b #x88cc32b3
165
#x8acf7a6f #xb0e8069f #x7a47f51e #xd2bb79da
166
#xe6950821 #x4398e55c #xd0b83106 #x11e37baf
167
#x7e416553 #xccaa2b10 #xd8b4e49c #x6456a7d4
168
#xfb7c3659 #x724b2084 #xea9f4df6 #x6a5faadf
169
#x2dc1dfce #x70486858 #xcaaff381 #x0605d891
170
#x5a774b69 #x94de28a5 #x39df1042 #x813bc347
171
#xfc82caa6 #x23c8d2c5 #x03f86cb2 #x080cd59a
172
#xdab7ac40 #x7db909e1 #x3824342c #xcf5247a2
173
#xdcb274d1 #x63a85b2b #x35d55595 #x479e7511
174
#x15e5ebe2 #x4b9430c6 #x4a6f14a8 #x91239c86
175
#x4c6acc39 #x5f8aff4a #x0406904d #xee99ddbb
176
#x1e1152ca #xaaffc418 #xeb646998 #x07fefcff
177
#x8b345e01 #x567d0ebe #xbae79bd9 #x4263c132
178
#x75b5dc7b #x97264417 #x67aecb66 #x95250ccb
179
#xec9a9567 #x57862ad0 #x60503799 #xb8e4d305
180
#x65ad83ba #x19efae35 #xa4f6c913 #xc15b4aa9
181
#x873e1bd6 #xa0f0595e #x18148a5b #xaf02703b
182
#xab04e076 #xdd4950bf #xdf4a1863 #xc6a5b656
183
#x853d530a #xfa871237 #x77b694a7 #x4665517f
184
#xed61b109 #x1bece6e9 #xd5458525 #xf5753b52
185
#x7fba413d #x27ce4288 #xb2eb4e43 #xd6bde997
186
#x527b9ef3 #x62537f45 #x2c3afba0 #x7bbcd170
187
#xb91ff76b #x121b171d #xfd79eec8 #x3a277cf0
188
#x0c0a45d7 #x96dd6079 #x2233f6ab #xacfa1c89
189
#xc8acbb5d #xa10b7d30 #xd4bea14b #xbee10b94
190
#x25cd0a54 #x547e4662 #xa2f31182 #x17e6a33e
191
#x263566e6 #xc3580275 #x83388b9b #x7844bdc2
192
#x020348dc #x4f92a08b #x2e39b37c #x4e6984e5
193
#xf0888f71 #x362d3927 #x9cd2fd3f #x01fb246e
194
#x893716dd #x00000000 #xf68d57e0 #xe293986c
195
#x744ef815 #x9320d45a #xad0138e7 #xd3405db4
196
#x1a17c287 #xb3106a2d #x5078d62f #xf48e1f3c
197
#xa70ea5a1 #x71b34c36 #x9ad725ae #x5e71db24
198
#x161d8750 #xef62f9d5 #x8d318690 #x1c121a16
199
#xa6f581cf #x5b8c6f07 #x37d61d49 #x6e593a92
200
#x84c67764 #x86c53fb8 #xd746cdf9 #xe090d0b0
201
#x29c74f83 #xe49640fd #x0e090d0b #x6da15620
202
#x8ec9ea22 #xdb4c882e #xf776738e #xb515b2bc
203
#x10185fc1 #x322ba96a #x6ba48eb1 #xaef95455
204
#x406089ee #x6655ef08 #xe9672144 #x3e21ecbd
205
#x2030be77 #xf28bc7ad #x80c0e729 #x141ecf8c
206
#xbce24348 #xc4a6fe8a #x31d3c5d8 #xb716fa60
207
#x5380ba9d #xd94fc0f2 #x1de93e78 #x24362e3a
208
#xe16bf4de #xcb54d7ef #x09f7f1f4 #x82c3aff5
209
#x0bf4b928 #x9d29d951 #xc75e9238 #xf8845aeb
210
#x90d8b8e8 #xdeb13c0d #x33d08d04 #x685ce203
211
#xc55ddae4 #x3bdc589e #x0a0f9d46 #x3fdac8d3
212
#x598f27db #xa8fc8cc4 #x79bf99ac #x6c5a724e
213
#x8ccaa2fe #x9ed1b5e3 #x1fea76a4 #x73b004ea))
215
(declaim (inline mul8))
217
(declare (type (unsigned-byte 8) a b))
218
(if (or (zerop a) (zerop b))
220
(aref alogtable (mod (+ (aref logtable a) (aref logtable b)) 255))))
222
;;; this function only runs during the key generation process, so consing
224
(defun transform (in in-offset out out-offset)
225
(declare (type (simple-array (unsigned-byte 32) (*)) in out))
226
(let ((a-matrix (make-array (list 4 4) :element-type '(unsigned-byte 8)))
227
(b-matrix (make-array (list 4 4) :element-type '(unsigned-byte 8)
228
:initial-element 0)))
229
(macrolet ((inref (index)
230
`(aref in (+ ,index in-offset)))
232
`(aref out (+ ,index out-offset))))
235
(setf (aref a-matrix i j)
236
(logand (ash (inref i) (- (- 24 (* j 8)))) #xff))))
240
(setf (aref b-matrix i j)
242
(logxor (mul8 (aref a-matrix i k) (aref g-matrix k j))
250
(ash (aref b-matrix i j) (- 24 (* j 8))))))))))
252
(defun generate-round-keys (key n-rounds encrypt-roundkeys decrypt-roundkeys)
253
(declare (type (simple-array (unsigned-byte 32) (*))
254
encrypt-roundkeys decrypt-roundkeys)
255
(type (simple-array (unsigned-byte 8) (16)) key))
256
(let ((offset (make-array n-rounds :element-type '(unsigned-byte 8)
258
(tempkeys (make-array (* (1+ n-rounds) 4) :element-type '(unsigned-byte 32))))
259
(declare (type (simple-array (unsigned-byte 8) (*)) offset)
260
(type (simple-array (unsigned-byte 32) (*)) tempkeys))
261
;; hack for stupid C array punning
262
(macrolet ((mdref (array i j)
263
`(aref ,array (+ (* ,i 4) ,j))))
266
(setf (aref offset i) (mul8 2 (aref offset (1- i)))))
268
(setf (mdref tempkeys 0 i) (ub32ref/be key (* 4 i))))
270
((>= i (1+ n-rounds)))
271
(setf (mdref tempkeys i 0)
272
(logxor (mdref tempkeys (1- i) 0)
273
(rol32 (mdref tempkeys (1- i) 3) 8)
274
(ash (aref offset (1- i)) 24))
276
(logxor (mdref tempkeys (1- i) 1) (mdref tempkeys i 0))
278
(logxor (mdref tempkeys (1- i) 2) (mdref tempkeys i 1))
280
(logxor (mdref tempkeys (1- i) 3) (mdref tempkeys i 2))))
281
(dotimes (i n-rounds)
282
(transform tempkeys (* i 4) encrypt-roundkeys (* i 4)))
284
(setf (mdref encrypt-roundkeys n-rounds i)
285
(mdref tempkeys n-rounds i)))
286
(dotimes (i n-rounds)
288
(setf (mdref decrypt-roundkeys i j)
289
(mdref tempkeys (- n-rounds i) j))))
291
(setf (mdref decrypt-roundkeys n-rounds i)
292
(mdref encrypt-roundkeys 0 i))))))
294
(declaim (inline square-munge-block))
295
(defun square-munge-block (round-keys n-rounds t-array s-array
296
plaintext plaintext-start
297
ciphertext ciphertext-start)
298
(declare (type (simple-array (unsigned-byte 8) (*)) plaintext ciphertext)
299
(type (simple-array (unsigned-byte 8) (256)) s-array)
300
(type (simple-array (unsigned-byte 32) (*)) round-keys)
301
(type (simple-array (unsigned-byte 32) (256)) t-array))
302
(declare (type (integer 0 #.(- array-dimension-limit 16))
303
plaintext-start ciphertext-start))
304
(with-words ((b0 b1 b2 b3) plaintext plaintext-start)
305
(let ((a0 0) (a1 0) (a2 0) (a3 0))
306
(declare (type (unsigned-byte 32) a0 a1 a2 a3))
307
;; initial key addition
308
(setf b0 (logxor b0 (aref round-keys 0))
309
b1 (logxor b1 (aref round-keys 1))
310
b2 (logxor b2 (aref round-keys 2))
311
b3 (logxor b3 (aref round-keys 3)))
314
(rk-offset 4 (+ rk-offset 4)))
315
((>= i (1- n-rounds)))
316
(macrolet ((mix (tmpvar bytefun)
318
(logxor (aref t-array (,bytefun b0))
319
(mod32+ (mod32ash (aref t-array (,bytefun b1)) -8)
320
(mod32ash (aref t-array (,bytefun b1)) 24))
321
(mod32+ (mod32ash (aref t-array (,bytefun b2)) -16)
322
(mod32ash (aref t-array (,bytefun b2)) 16))
323
(mod32+ (mod32ash (aref t-array (,bytefun b3)) -24)
324
(mod32ash (aref t-array (,bytefun b3)) 8))))))
329
(setf b0 (logxor a0 (aref round-keys (+ rk-offset 0)))
330
b1 (logxor a1 (aref round-keys (+ rk-offset 1)))
331
b2 (logxor a2 (aref round-keys (+ rk-offset 2)))
332
b3 (logxor a3 (aref round-keys (+ rk-offset 3)))))))
334
(macrolet ((last-round (bytefun)
335
`(mod32+ (mod32ash (aref s-array (,bytefun b0)) 24)
336
(mod32+ (mod32ash (aref s-array (,bytefun b1)) 16)
337
(mod32+ (mod32ash (aref s-array (,bytefun b2)) 8)
338
(mod32ash (aref s-array (,bytefun b3)) 0)))))
340
`(aref round-keys (+ ,index (* n-rounds 4)))))
341
(let ((t0 (last-round fourth-byte))
342
(t1 (last-round third-byte))
343
(t2 (last-round second-byte))
344
(t3 (last-round first-byte)))
345
(declare (type (unsigned-byte 32) t0 t1 t2 t3))
346
(flet ((apply-rk (temp round-key)
347
(declare (type (unsigned-byte 32) temp round-key))
348
(logxor temp round-key)))
349
(declare (inline apply-rk))
350
(store-words ciphertext ciphertext-start
351
(apply-rk t0 (rkref 0))
352
(apply-rk t1 (rkref 1))
353
(apply-rk t2 (rkref 2))
354
(apply-rk t3 (rkref 3))))))))
356
(defclass square (cipher 16-byte-block-mixin)
357
((encryption-round-keys :accessor encryption-round-keys
358
:type (simple-array (unsigned-byte 32) (*)))
359
(decryption-round-keys :accessor decryption-round-keys
360
:type (simple-array (unsigned-byte 32) (*)))
361
(n-rounds :initarg :n-rounds :reader n-rounds))
362
(:default-initargs :n-rounds 8))
364
(define-block-encryptor square 16
365
(let ((n-rounds (n-rounds context))
366
(round-keys (encryption-round-keys context)))
367
(square-munge-block round-keys n-rounds t-encryption-table s-encryption-table
368
plaintext plaintext-start ciphertext ciphertext-start)))
370
(define-block-decryptor square 16
371
(let ((n-rounds (n-rounds context))
372
(round-keys (decryption-round-keys context)))
373
(square-munge-block round-keys n-rounds t-decryption-table s-decryption-table
374
ciphertext ciphertext-start plaintext plaintext-start)))
376
(defmethod schedule-key ((cipher square) key)
377
(let ((encryption-schedule (make-array (* 4 (1+ (n-rounds cipher)))
378
:element-type '(unsigned-byte 32)))
379
(decryption-schedule (make-array (* 4 (1+ (n-rounds cipher)))
380
:element-type '(unsigned-byte 32))))
381
(generate-round-keys key (n-rounds cipher)
382
encryption-schedule decryption-schedule)
383
(setf (encryption-round-keys cipher) encryption-schedule
384
(decryption-round-keys cipher) decryption-schedule)
388
(:encrypt-function square-encrypt-block)
389
(:decrypt-function square-decrypt-block)
391
(:key-length (:fixed 16)))