1;;;; -*- mode: lisp; indent-tabs-mode: nil -*-
2;;;; skein.lisp -- implementation of the Skein hash functions
3
4(in-package :crypto)
5(in-ironclad-readtable)
6
7
8;;; Parameter identifiers
9
10(defconstant +skein-key+ 0)
11(defconstant +skein-cfg+ 4)
12(defconstant +skein-prs+ 8)
13(defconstant +skein-pk+ 12)
14(defconstant +skein-kdf+ 16)
15(defconstant +skein-non+ 20)
16(defconstant +skein-msg+ 48)
17(defconstant +skein-out+ 63)
18
19
20;;; Initial values
21
22(declaim (type (simple-array (unsigned-byte 8) (32))
23               +skein256-iv-128+ +skein256-iv-160+ +skein256-iv-224+
24               +skein256-iv-256+))
25(declaim (type (simple-array (unsigned-byte 8) (64))
26               +skein512-iv-128+ +skein512-iv-160+ +skein512-iv-224+
27               +skein512-iv-256+ +skein512-iv-384+ +skein512-iv-512+))
28(declaim (type (simple-array (unsigned-byte 8) (128))
29               +skein1024-iv-384+ +skein1024-iv-512+ +skein1024-iv-1024+))
30
31(defconst +skein256-iv-128+ #8@(96 114 77 150 6 25 17 225
32                                28 129 141 124 167 170 61 136
33                                122 15 150 145 244 13 8 16
34                                194 193 91 180 229 221 247 204))
35(defconst +skein256-iv-160+ #8@(152 94 130 114 20 35 32 20
36                                144 229 119 90 162 233 196 42
37                                62 214 56 136 86 88 122 212
38                                125 171 134 133 150 228 210 45))
39(defconst +skein256-iv-224+ #8@(11 234 229 154 140 138 9 198
40                                28 25 197 8 134 86 109 135
41                                132 56 245 215 215 136 203 153
42                                222 181 221 174 177 221 75 56))
43(defconst +skein256-iv-256+ #8@(73 180 72 208 96 168 157 252
44                                51 216 167 159 71 102 202 47
45                                15 132 86 102 137 195 59 179
46                                105 218 232 253 32 233 84 106))
47
48(defconst +skein512-iv-128+ #8@(82 159 191 111 243 123 188 168
49                                170 240 26 189 206 114 152 30
50                                211 144 33 179 144 23 155 48
51                                92 128 148 63 84 184 251 188
52                                27 177 49 110 205 27 166 13
53                                227 50 106 212 234 235 24 26
54                                130 170 132 206 24 91 204 162
55                                45 152 70 157 40 171 130 105))
56(defconst +skein512-iv-160+ #8@(145 189 19 224 42 26 184 40
57                                143 247 189 181 104 22 241 194
58                                18 111 165 246 243 216 96 23
59                                79 144 57 130 88 71 183 79
60                                86 80 175 126 127 224 237 33
61                                184 112 237 99 46 146 8 217
62                                250 82 203 236 255 118 236 184
63                                110 122 242 163 184 123 164 1))
64(defconst +skein512-iv-224+ #8@(36 114 103 72 98 97 208 204
65                                239 57 35 169 243 92 166 203
66                                100 75 255 82 214 105 205 140
67                                180 144 184 58 123 237 138 57
68                                208 43 125 69 177 209 89 15
69                                61 235 212 117 101 254 118 103
70                                233 19 116 153 14 199 251 153
71                                247 30 196 225 207 252 44 158))
72(defconst +skein512-iv-256+ #8@(19 62 219 47 161 68 208 204
73                                235 169 121 26 48 144 53 232
74                                111 110 129 79 97 160 174 85
75                                219 148 155 174 164 103 39 42
76                                131 118 221 116 94 2 6 236
77                                81 98 116 196 205 54 164 231
78                                133 209 58 57 249 186 111 195
79                                19 252 237 51 24 186 237 62))
80(defconst +skein512-iv-384+ #8@(95 239 117 58 191 198 246 163
81                                164 250 132 253 204 249 254 176
82                                254 12 119 61 102 221 119 157
83                                218 253 104 180 243 203 152 215
84                                101 68 14 138 102 166 196 27
85                                7 116 128 229 52 212 215 126
86                                214 68 236 212 172 193 143 84
87                                248 143 161 106 84 23 110 38))
88(defconst +skein512-iv-512+ #8@(206 81 156 116 255 173 3 73
89                                3 223 70 151 57 222 149 13
90                                206 155 199 39 65 147 209 143
91                                177 44 53 255 41 86 37 154
92                                176 167 108 223 153 37 182 93
93                                244 195 213 169 76 57 190 234
94                                35 181 117 26 199 18 17 153
95                                51 204 15 102 11 164 24 174))
96
97(defconst +skein1024-iv-384+ #8@(53 74 137 193 184 182 2 81
98                                 26 241 138 254 227 201 235 254
99                                 113 237 43 227 6 127 128 12
100                                 246 145 26 180 82 58 193 96
101                                 56 124 145 212 93 211 22 151
102                                 58 29 211 111 18 223 128 231
103                                 58 48 152 200 182 70 120 121
104                                 59 42 87 179 168 194 114 177
105                                 108 74 16 166 3 130 188 201
106                                 244 36 86 215 56 147 144 101
107                                 160 129 63 75 104 197 188 148
108                                 70 253 236 16 30 245 187 62
109                                 66 133 176 238 11 15 245 45
110                                 22 101 188 13 48 101 90 59
111                                 225 188 123 22 210 156 75 72
112                                 234 175 203 212 71 105 19 45))
113(defconst +skein1024-iv-512+ #8@(24 27 27 124 93 14 236 202
114                                 2 232 3 95 4 14 27 160
115                                 133 40 145 237 81 4 132 51
116                                 28 46 236 234 4 251 74 55
117                                 247 129 53 129 226 160 37 223
118                                 210 249 18 139 147 64 0 228
119                                 182 57 237 194 57 213 98 166
120                                 90 199 216 69 207 133 139 250
121                                 150 231 237 41 142 237 22 131
122                                 184 145 159 46 192 137 50 5
123                                 115 139 81 109 29 239 248 195
124                                 46 51 239 213 196 195 206 189
125                                 135 68 151 34 82 126 154 84
126                                 22 152 116 91 114 8 7 103
127                                 209 27 88 240 251 40 205 185
128                                 116 73 128 21 184 64 41 14))
129(defconst +skein1024-iv-1024+ #8@(85 35 231 65 7 218 147 213
130                                  12 224 115 172 17 229 181 21
131                                  240 196 242 186 174 229 128 81
132                                  175 175 188 252 211 65 189 3
133                                  152 168 131 25 253 198 174 28
134                                  159 88 208 205 139 11 81 110
135                                  218 74 57 198 253 189 226 119
136                                  163 176 220 36 181 29 30 193
137                                  181 154 50 198 249 74 209 214
138                                  13 126 182 110 252 11 155 106
139                                  50 19 255 204 13 198 67 146
140                                  212 2 63 116 222 29 31 26
141                                  184 11 237 16 60 117 150 9
142                                  154 150 180 242 34 221 114 101
143                                  154 87 10 208 98 48 253 97
144                                  57 229 130 134 110 83 224 29))
145
146(defun skein-get-iv (block-bits digest-bits)
147  (ecase block-bits
148    (256 (ecase digest-bits
149           (128 +skein256-iv-128+)
150           (160 +skein256-iv-160+)
151           (224 +skein256-iv-224+)
152           (256 +skein256-iv-256+)))
153    (512 (ecase digest-bits
154           (128 +skein512-iv-128+)
155           (160 +skein512-iv-160+)
156           (224 +skein512-iv-224+)
157           (256 +skein512-iv-256+)
158           (384 +skein512-iv-384+)
159           (512 +skein512-iv-512+)))
160    (1024 (ecase digest-bits
161            (384 +skein1024-iv-384+)
162            (512 +skein1024-iv-512+)
163            (1024 +skein1024-iv-1024+)))))
164
165
166;;; Functions to generate and update the tweak
167
168;;; This function is called a lot by skein-ubi,
169;;; so we try to optimize it for speed.
170(declaim (inline skein-increment-counter))
171(defun skein-increment-counter (tweak n)
172  (declare (type (simple-array (unsigned-byte 64) (2)) tweak)
173           (type (unsigned-byte 32) n)
174           #.(burn-baby-burn))
175  (let* ((x (mod64+ (aref tweak 0) n))
176         (y (mod32+ (logand (aref tweak 1) #xffffffff) (if (< x n) 1 0))))
177    (declare (type (unsigned-byte 64) x)
178             (type (unsigned-byte 32) y))
179    (setf (aref tweak 0) x
180          (ldb (byte 32 0) (aref tweak 1)) y)
181    (values)))
182
183(defun skein-update-tweak (tweak &key
184                                   (first nil first-p)
185                                   (final nil final-p)
186                                   (type nil type-p)
187                                   (position nil position-p)
188                                   (position-increment nil position-increment-p))
189  (when first-p
190    (setf (ldb (byte 1 62) (aref tweak 1)) (if first 1 0)))
191  (when final-p
192    (setf (ldb (byte 1 63) (aref tweak 1)) (if final 1 0)))
193  (when type-p
194    (setf (ldb (byte 6 56) (aref tweak 1)) type))
195  (when position-p
196    (setf (aref tweak 0) (ldb (byte 64 0) position))
197    (setf (ldb (byte 32 0) (aref tweak 1)) (ldb (byte 32 64) position)))
198  (when position-increment-p
199    (skein-increment-counter tweak position-increment))
200  (values))
201
202(defun skein-make-tweak (first final type position)
203  (let ((tweak (make-array 2
204                           :element-type '(unsigned-byte 64)
205                           :initial-element 0)))
206    (skein-update-tweak tweak
207                        :first first
208                        :final final
209                        :type type
210                        :position position)
211    tweak))
212
213(defun skein-make-configuration-string (output-length)
214  (let ((cfg (make-array 32
215                         :element-type '(unsigned-byte 8)
216                         :initial-element 0)))
217    (setf (subseq cfg 0 4) #(83 72 65 51))
218    (setf (subseq cfg 4 6)
219          (integer-to-octets 1 :n-bits 16 :big-endian nil))
220    (setf (subseq cfg 8 16)
221          (integer-to-octets output-length :n-bits 64 :big-endian nil))
222    cfg))
223
224
225;;; UBI (unique block iteration chaining)
226
227(defgeneric skein-value (state))
228(defgeneric skein-tweak (state))
229(defgeneric skein-cfg (state))
230(defgeneric skein-buffer (state))
231(defgeneric skein-buffer-length (state))
232(defgeneric skein-cipher (state))
233
234;;; This function is called a lot by skein-ubi,
235;;; so we try to optimize it for speed.
236(declaim (inline skein-update-cipher))
237(defun skein-update-cipher (block-length cipher-key cipher-tweak key tweak)
238  (declare (type fixnum block-length)
239           (type (simple-array (unsigned-byte 64) (*)) cipher-key)
240           (type (simple-array (unsigned-byte 64) (3)) cipher-tweak)
241           (type (simple-array (unsigned-byte 8) (*)) key)
242           (type (simple-array (unsigned-byte 64) (2)) tweak)
243           #.(burn-baby-burn))
244  (let ((key-words (ash block-length -3))
245        (parity +threefish-key-schedule-constant+)
246        (n 0))
247    (declare (type (unsigned-byte 64) parity n key-words))
248
249    ;; Update key
250    (loop for i of-type fixnum from 0 below key-words do
251      (setf n (ub64ref/le key (ash i 3))
252            (aref cipher-key i) n
253            parity (logxor parity n)))
254    (setf (aref cipher-key key-words) parity)
255
256    ;; Update tweak
257    (setf (aref cipher-tweak 0) (aref tweak 0)
258          (aref cipher-tweak 1) (aref tweak 1)
259          (aref cipher-tweak 2) (logxor (aref tweak 0) (aref tweak 1)))
260    (values)))
261
262(defun skein-ubi (state message start end &optional final)
263  (declare (type (simple-array (unsigned-byte 8) (*)) message)
264           (type index start end)
265           #.(burn-baby-burn))
266  (let* ((cipher (skein-cipher state))
267         (encryption-function (encrypt-function cipher))
268         (cipher-key (threefish-key cipher))
269         (cipher-tweak (threefish-tweak cipher))
270         (block-length (block-length state))
271         (value (skein-value state))
272         (tweak (skein-tweak state))
273         (buffer (skein-buffer state))
274         (buffer-length (skein-buffer-length state))
275         (message-start start)
276         (message-length (- end start))
277         (ciphertext (make-array 128
278                                 :element-type '(unsigned-byte 8)
279                                 :initial-element 0))
280         (n 0))
281    (declare (type (simple-array (unsigned-byte 64) (*)) cipher-key)
282             (type (simple-array (unsigned-byte 64) (3)) cipher-tweak)
283             (type (simple-array (unsigned-byte 8) (*)) value buffer)
284             (type (simple-array (unsigned-byte 8) (128)) ciphertext)
285             (dynamic-extent ciphertext)
286             (type (simple-array (unsigned-byte 64) (2)) tweak)
287             (type (integer 0 128) block-length buffer-length n)
288             (type index message-start message-length))
289
290    ;; Try to fill the buffer with the new data
291    (setf n (min message-length (- block-length buffer-length)))
292    (replace buffer message
293             :start1 buffer-length
294             :start2 message-start
295             :end2 (+ message-start n))
296    (incf buffer-length n)
297    (incf message-start n)
298    (decf message-length n)
299
300    ;; Process as many blocks as we can, but unless we are in the
301    ;; final call, keep some data in the buffer (so that it can be
302    ;; processed with the 'final' tweak flag in the final call)
303
304    ;; Process data in buffer
305    (when (and (= buffer-length block-length)
306               (or final (plusp message-length)))
307      (unless final
308        (skein-increment-counter tweak block-length))
309      (skein-update-cipher block-length cipher-key cipher-tweak value tweak)
310      (funcall encryption-function cipher buffer 0 ciphertext 0)
311      (skein-update-tweak tweak :first nil)
312      (xor-block block-length ciphertext 0 buffer 0 value 0)
313      (setf buffer-length 0))
314
315    ;; Process data in message
316    (unless final
317      (loop until (<= message-length block-length) do
318        (skein-increment-counter tweak block-length)
319        (skein-update-cipher block-length cipher-key cipher-tweak value tweak)
320        (funcall encryption-function cipher message message-start ciphertext 0)
321        (xor-block block-length ciphertext 0 message message-start value 0)
322        (incf message-start block-length)
323        (decf message-length block-length)))
324
325    ;; Put remaining message data in buffer
326    (when (plusp message-length)
327      (replace buffer message :end1 message-length :start2 message-start)
328      (incf buffer-length message-length))
329
330    ;; Save the new state
331    (setf (skein-buffer-length state) buffer-length)
332    (values)))
333
334(defun skein-finalize (state digest digest-start)
335  (let* ((block-length (block-length state))
336         (digest-length (digest-length state))
337         (tweak (skein-tweak state))
338         (buffer-length (skein-buffer-length state))
339         (padding-length (- block-length buffer-length))
340         (padding (make-array padding-length
341                              :element-type '(unsigned-byte 8)
342                              :initial-element 0)))
343    ;; Process remaining data after padding it
344    (skein-update-tweak tweak :final t :position-increment buffer-length)
345    (skein-ubi state padding 0 padding-length t)
346
347    ;; Generate output
348    (do* ((value (copy-seq (skein-value state)))
349          (noutputs (ceiling digest-length block-length))
350          (output (make-array (* noutputs block-length)
351                              :element-type '(unsigned-byte 8)))
352          (i 0 (1+ i))
353          (msg (make-array block-length
354                           :element-type '(unsigned-byte 8)
355                           :initial-element 0)))
356         ((= i noutputs)
357          (progn
358            (replace digest output :start1 digest-start :end2 digest-length)
359            digest))
360      (replace msg (integer-to-octets i :n-bits 64 :big-endian nil) :end2 8)
361      (replace (skein-value state) value)
362      (skein-update-tweak tweak :first t :final t :type +skein-out+ :position 8)
363      (skein-ubi state msg 0 block-length t)
364      (replace output (skein-value state) :start1 (* i block-length) :end2 block-length))))
365
366(defun skein-copy-cipher (cipher &optional copy)
367  (let* ((tmp-key (make-array (block-length cipher)
368                              :element-type '(unsigned-byte 8)))
369         (cipher-name (ecase (block-length cipher)
370                        (32 :threefish256)
371                        (64 :threefish512)
372                        (128 :threefish1024)))
373         (copy (if copy copy (make-cipher cipher-name
374                                          :key tmp-key
375                                          :mode :ecb))))
376    (setf (threefish-key copy) (copy-seq (threefish-key cipher)))
377    (setf (threefish-tweak copy) (copy-seq (threefish-tweak cipher)))
378    copy))
379
380
381;;; Implementation for blocks of 256 bits
382
383(defstruct (skein256
384             (:constructor %make-skein256-digest nil)
385             (:copier nil))
386  (value (copy-seq (skein-get-iv 256 256))
387         :type (simple-array (unsigned-byte 8) (32)))
388  (tweak (skein-make-tweak t nil +skein-msg+ 0)
389         :type (simple-array (unsigned-byte 64) (2)))
390  (cfg (skein-make-configuration-string 256)
391       :type (simple-array (unsigned-byte 8) (32)))
392  (buffer (make-array 32 :element-type '(unsigned-byte 8))
393          :type (simple-array (unsigned-byte 8) (32)))
394  (buffer-length 0 :type integer)
395  (cipher (make-cipher :threefish256
396                       :key (skein-get-iv 256 256)
397                       :mode :ecb)))
398
399(defstruct (skein256/128
400             (:include skein256)
401             (:constructor %make-skein256/128-digest
402                           (&aux (value (copy-seq (skein-get-iv 256 128)))
403                                 (cfg (skein-make-configuration-string 128))
404                                 (cipher (make-cipher :threefish256
405                                                      :key (skein-get-iv 256 128)
406                                                      :mode :ecb))))
407             (:copier nil)))
408
409(defstruct (skein256/160
410             (:include skein256)
411             (:constructor %make-skein256/160-digest
412                           (&aux (value (copy-seq (skein-get-iv 256 160)))
413                                 (cfg (skein-make-configuration-string 160))
414                                 (cipher (make-cipher :threefish256
415                                                      :key (skein-get-iv 256 160)
416                                                      :mode :ecb))))
417             (:copier nil)))
418
419(defstruct (skein256/224
420             (:include skein256)
421             (:constructor %make-skein256/224-digest
422                           (&aux (value (copy-seq (skein-get-iv 256 224)))
423                                 (cfg (skein-make-configuration-string 224))
424                                 (cipher (make-cipher :threefish256
425                                                      :key (skein-get-iv 256 224)
426                                                      :mode :ecb))))
427             (:copier nil)))
428
429(defmethod skein-value ((state skein256))
430  (skein256-value state))
431
432(defmethod skein-tweak ((state skein256))
433  (skein256-tweak state))
434
435(defmethod skein-cfg ((state skein256))
436  (skein256-cfg state))
437
438(defmethod skein-buffer ((state skein256))
439  (skein256-buffer state))
440
441(defmethod skein-buffer-length ((state skein256))
442  (skein256-buffer-length state))
443
444(defmethod (setf skein-buffer-length) (n (state skein256))
445  (setf (skein256-buffer-length state) n))
446
447(defmethod skein-cipher ((state skein256))
448  (skein256-cipher state))
449
450(defmethod (setf skein-cipher) (cipher (state skein256))
451  (setf (skein256-cipher state) cipher))
452
453(defun %reinitialize-skein256 (state digest-bits)
454  (declare (type skein256 state))
455  (replace (skein256-value state) (skein-get-iv 256 digest-bits))
456  (replace (skein256-tweak state) (skein-make-tweak t nil +skein-msg+ 0))
457  (replace (skein256-cfg state) (skein-make-configuration-string digest-bits))
458  (setf (skein256-buffer-length state) 0)
459  (setf (skein256-cipher state) (make-cipher :threefish256
460                                             :key (skein-get-iv 256 digest-bits)
461                                             :mode :ecb))
462  state)
463
464(defmethod reinitialize-instance ((state skein256) &rest initargs)
465  (declare (ignore initargs))
466  (%reinitialize-skein256 state 256))
467
468(defmethod reinitialize-instance ((state skein256/128) &rest initargs)
469  (declare (ignore initargs))
470  (%reinitialize-skein256 state 128))
471
472(defmethod reinitialize-instance ((state skein256/160) &rest initargs)
473  (declare (ignore initargs))
474  (%reinitialize-skein256 state 160))
475
476(defmethod reinitialize-instance ((state skein256/224) &rest initargs)
477  (declare (ignore initargs))
478  (%reinitialize-skein256 state 224))
479
480(defmethod copy-digest ((state skein256) &optional copy)
481  (check-type copy (or null skein256))
482  (let ((copy (if copy
483                  copy
484                  (etypecase state
485                    (skein256/128 (%make-skein256/128-digest))
486                    (skein256/160 (%make-skein256/160-digest))
487                    (skein256/224 (%make-skein256/224-digest))
488                    (skein256 (%make-skein256-digest))))))
489    (declare (type skein256 copy))
490    (replace (skein256-value copy) (skein256-value state))
491    (replace (skein256-tweak copy) (skein256-tweak state))
492    (replace (skein256-cfg copy) (skein256-cfg state))
493    (replace (skein256-buffer copy) (skein256-buffer state))
494    (setf (skein256-buffer-length copy) (skein256-buffer-length state))
495    (setf (skein256-cipher copy) (skein-copy-cipher (skein256-cipher state)))
496    copy))
497
498(define-digest-updater skein256
499  (skein-ubi state sequence start end))
500
501(define-digest-finalizer ((skein256 32)
502                          (skein256/224 28)
503                          (skein256/160 20)
504                          (skein256/128 16))
505  (skein-finalize state digest digest-start))
506
507(defdigest skein256 :digest-length 32 :block-length 32)
508(defdigest skein256/128 :digest-length 16 :block-length 32)
509(defdigest skein256/160 :digest-length 20 :block-length 32)
510(defdigest skein256/224 :digest-length 28 :block-length 32)
511
512
513;;; Implementation for blocks of 512 bits
514
515(defstruct (skein512
516             (:constructor %make-skein512-digest nil)
517             (:copier nil))
518  (value (copy-seq (skein-get-iv 512 512))
519         :type (simple-array (unsigned-byte 8) (64)))
520  (tweak (skein-make-tweak t nil +skein-msg+ 0)
521         :type (simple-array (unsigned-byte 64) (2)))
522  (cfg (skein-make-configuration-string 512)
523       :type (simple-array (unsigned-byte 8) (32)))
524  (buffer (make-array 64 :element-type '(unsigned-byte 8))
525          :type (simple-array (unsigned-byte 8) (64)))
526  (buffer-length 0 :type integer)
527  (cipher (make-cipher :threefish512
528                       :key (skein-get-iv 512 512)
529                       :mode :ecb)))
530
531(defstruct (skein512/128
532             (:include skein512)
533             (:constructor %make-skein512/128-digest
534                           (&aux (value (copy-seq (skein-get-iv 512 128)))
535                                 (cfg (skein-make-configuration-string 128))
536                                 (cipher (make-cipher :threefish512
537                                                      :key (skein-get-iv 512 128)
538                                                      :mode :ecb))))
539             (:copier nil)))
540
541(defstruct (skein512/160
542             (:include skein512)
543             (:constructor %make-skein512/160-digest
544                           (&aux (value (copy-seq (skein-get-iv 512 160)))
545                                 (cfg (skein-make-configuration-string 160))
546                                 (cipher (make-cipher :threefish512
547                                                      :key (skein-get-iv 512 160)
548                                                      :mode :ecb))))
549             (:copier nil)))
550
551(defstruct (skein512/224
552             (:include skein512)
553             (:constructor %make-skein512/224-digest
554                           (&aux (value (copy-seq (skein-get-iv 512 224)))
555                                 (cfg (skein-make-configuration-string 224))
556                                 (cipher (make-cipher :threefish512
557                                                      :key (skein-get-iv 512 224)
558                                                      :mode :ecb))))
559             (:copier nil)))
560
561(defstruct (skein512/256
562             (:include skein512)
563             (:constructor %make-skein512/256-digest
564                           (&aux (value (copy-seq (skein-get-iv 512 256)))
565                                 (cfg (skein-make-configuration-string 256))
566                                 (cipher (make-cipher :threefish512
567                                                      :key (skein-get-iv 512 256)
568                                                      :mode :ecb))))
569             (:copier nil)))
570
571(defstruct (skein512/384
572             (:include skein512)
573             (:constructor %make-skein512/384-digest
574                           (&aux (value (copy-seq (skein-get-iv 512 384)))
575                                 (cfg (skein-make-configuration-string 384))
576                                 (cipher (make-cipher :threefish512
577                                                      :key (skein-get-iv 512 384)
578                                                      :mode :ecb))))
579             (:copier nil)))
580
581(defmethod skein-value ((state skein512))
582  (skein512-value state))
583
584(defmethod skein-tweak ((state skein512))
585  (skein512-tweak state))
586
587(defmethod skein-cfg ((state skein512))
588  (skein512-cfg state))
589
590(defmethod skein-buffer ((state skein512))
591  (skein512-buffer state))
592
593(defmethod skein-buffer-length ((state skein512))
594  (skein512-buffer-length state))
595
596(defmethod (setf skein-buffer-length) (n (state skein512))
597  (setf (skein512-buffer-length state) n))
598
599(defmethod skein-cipher ((state skein512))
600  (skein512-cipher state))
601
602(defmethod (setf skein-cipher) (cipher (state skein512))
603  (setf (skein512-cipher state) cipher))
604
605(defun %reinitialize-skein512 (state digest-bits)
606  (declare (type skein512 state))
607  (replace (skein512-value state) (skein-get-iv 512 digest-bits))
608  (replace (skein512-tweak state) (skein-make-tweak t nil +skein-msg+ 0))
609  (replace (skein512-cfg state) (skein-make-configuration-string digest-bits))
610  (setf (skein512-buffer-length state) 0)
611  (setf (skein512-cipher state) (make-cipher :threefish512
612                                             :key (skein-get-iv 512 digest-bits)
613                                             :mode :ecb))
614  state)
615
616(defmethod reinitialize-instance ((state skein512) &rest initargs)
617  (declare (ignore initargs))
618  (%reinitialize-skein512 state 512))
619
620(defmethod reinitialize-instance ((state skein512/128) &rest initargs)
621  (declare (ignore initargs))
622  (%reinitialize-skein512 state 128))
623
624(defmethod reinitialize-instance ((state skein512/160) &rest initargs)
625  (declare (ignore initargs))
626  (%reinitialize-skein512 state 160))
627
628(defmethod reinitialize-instance ((state skein512/224) &rest initargs)
629  (declare (ignore initargs))
630  (%reinitialize-skein512 state 224))
631
632(defmethod reinitialize-instance ((state skein512/256) &rest initargs)
633  (declare (ignore initargs))
634  (%reinitialize-skein512 state 256))
635
636(defmethod reinitialize-instance ((state skein512/384) &rest initargs)
637  (declare (ignore initargs))
638  (%reinitialize-skein512 state 384))
639
640(defmethod copy-digest ((state skein512) &optional copy)
641  (declare (type (or null skein512) copy))
642  (let ((copy (if copy
643                  copy
644                  (etypecase state
645                    (skein512/128 (%make-skein512/128-digest))
646                    (skein512/160 (%make-skein512/160-digest))
647                    (skein512/224 (%make-skein512/224-digest))
648                    (skein512/256 (%make-skein512/256-digest))
649                    (skein512/384 (%make-skein512/384-digest))
650                    (skein512 (%make-skein512-digest))))))
651    (declare (type skein512 copy))
652    (replace (skein512-value copy) (skein512-value state))
653    (replace (skein512-tweak copy) (skein512-tweak state))
654    (replace (skein512-cfg copy) (skein512-cfg state))
655    (replace (skein512-buffer copy) (skein512-buffer state))
656    (setf (skein512-buffer-length copy) (skein512-buffer-length state))
657    (setf (skein512-cipher copy) (skein-copy-cipher (skein512-cipher state)))
658    copy))
659
660(define-digest-updater skein512
661  (skein-ubi state sequence start end))
662
663(define-digest-finalizer ((skein512 64)
664                          (skein512/128 16)
665                          (skein512/160 20)
666                          (skein512/224 28)
667                          (skein512/256 32)
668                          (skein512/384 48))
669  (skein-finalize state digest digest-start))
670
671(defdigest skein512 :digest-length 64 :block-length 64)
672(defdigest skein512/128 :digest-length 16 :block-length 64)
673(defdigest skein512/160 :digest-length 20 :block-length 64)
674(defdigest skein512/224 :digest-length 28 :block-length 64)
675(defdigest skein512/256 :digest-length 32 :block-length 64)
676(defdigest skein512/384 :digest-length 48 :block-length 64)
677
678
679;;; Implementation for blocks of 1024 bits
680
681(defstruct (skein1024
682             (:constructor %make-skein1024-digest nil)
683             (:copier nil))
684  (value (copy-seq (skein-get-iv 1024 1024))
685         :type (simple-array (unsigned-byte 8) (128)))
686  (tweak (skein-make-tweak t nil +skein-msg+ 0)
687         :type (simple-array (unsigned-byte 64) (2)))
688  (cfg (skein-make-configuration-string 1024)
689       :type (simple-array (unsigned-byte 8) (32)))
690  (buffer (make-array 128 :element-type '(unsigned-byte 8))
691          :type (simple-array (unsigned-byte 8) (128)))
692  (buffer-length 0 :type integer)
693  (cipher (make-cipher :threefish1024
694                       :key (skein-get-iv 1024 1024)
695                       :mode :ecb)))
696
697(defstruct (skein1024/384
698             (:include skein1024)
699             (:constructor %make-skein1024/384-digest
700                           (&aux (value (copy-seq (skein-get-iv 1024 384)))
701                                 (cfg (skein-make-configuration-string 384))
702                                 (cipher (make-cipher :threefish1024
703                                                      :key (skein-get-iv 1024 384)
704                                                      :mode :ecb))))
705             (:copier nil)))
706
707(defstruct (skein1024/512
708             (:include skein1024)
709             (:constructor %make-skein1024/512-digest
710                           (&aux (value (copy-seq (skein-get-iv 1024 512)))
711                                 (cfg (skein-make-configuration-string 512))
712                                 (cipher (make-cipher :threefish1024
713                                                      :key (skein-get-iv 1024 512)
714                                                      :mode :ecb))))
715             (:copier nil)))
716
717(defmethod skein-value ((state skein1024))
718  (skein1024-value state))
719
720(defmethod skein-tweak ((state skein1024))
721  (skein1024-tweak state))
722
723(defmethod skein-cfg ((state skein1024))
724  (skein1024-cfg state))
725
726(defmethod skein-buffer ((state skein1024))
727  (skein1024-buffer state))
728
729(defmethod skein-buffer-length ((state skein1024))
730  (skein1024-buffer-length state))
731
732(defmethod (setf skein-buffer-length) (n (state skein1024))
733  (setf (skein1024-buffer-length state) n))
734
735(defmethod skein-cipher ((state skein1024))
736  (skein1024-cipher state))
737
738(defmethod (setf skein-cipher) (cipher (state skein1024))
739  (setf (skein1024-cipher state) cipher))
740
741(defun %reinitialize-skein1024 (state digest-bits)
742  (declare (type skein1024 state))
743  (replace (skein1024-value state) (skein-get-iv 1024 digest-bits))
744  (replace (skein1024-tweak state) (skein-make-tweak t nil +skein-msg+ 0))
745  (replace (skein1024-cfg state) (skein-make-configuration-string digest-bits))
746  (setf (skein1024-buffer-length state) 0)
747  (setf (skein1024-cipher state) (make-cipher :threefish1024
748                                              :key (skein-get-iv 1024 digest-bits)
749                                              :mode :ecb))
750  state)
751
752(defmethod reinitialize-instance ((state skein1024) &rest initargs)
753  (declare (ignore initargs))
754  (%reinitialize-skein1024 state 1024))
755
756(defmethod reinitialize-instance ((state skein1024/384) &rest initargs)
757  (declare (ignore initargs))
758  (%reinitialize-skein1024 state 384))
759
760(defmethod reinitialize-instance ((state skein1024/512) &rest initargs)
761  (declare (ignore initargs))
762  (%reinitialize-skein1024 state 512))
763
764(defmethod copy-digest ((state skein1024) &optional copy)
765  (declare (type (or null skein1024) copy))
766  (let ((copy (if copy
767                  copy
768                  (etypecase state
769                    (skein1024/384 (%make-skein1024/384-digest))
770                    (skein1024/512 (%make-skein1024/512-digest))
771                    (skein1024 (%make-skein1024-digest))))))
772    (declare (type skein1024 copy))
773    (replace (skein1024-value copy) (skein1024-value state))
774    (replace (skein1024-tweak copy) (skein1024-tweak state))
775    (replace (skein1024-cfg copy) (skein1024-cfg state))
776    (replace (skein1024-buffer copy) (skein1024-buffer state))
777    (setf (skein1024-buffer-length copy) (skein1024-buffer-length state))
778    (setf (skein1024-cipher copy) (skein-copy-cipher (skein1024-cipher state)))
779    copy))
780
781(define-digest-updater skein1024
782  (skein-ubi state sequence start end))
783
784(define-digest-finalizer ((skein1024 128)
785                          (skein1024/384 48)
786                          (skein1024/512 64))
787  (skein-finalize state digest digest-start))
788
789(defdigest skein1024 :digest-length 128 :block-length 128)
790(defdigest skein1024/384 :digest-length 48 :block-length 128)
791(defdigest skein1024/512 :digest-length 64 :block-length 128)
792