Coverage report: /home/ellis/comp/ext/ironclad/src/digests/blake2.lisp
Kind | Covered | All | % |
expression | 0 | 450 | 0.0 |
branch | 0 | 16 | 0.0 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;;; blake2.lisp -- implementation of the BLAKE2b hash function (RFC 7693)
5
(eval-when (:compile-toplevel :load-toplevel :execute)
6
(defconstant +blake2-rounds+ 12)
7
(defconstant +blake2-block-size+ 128)
8
(defconst +blake2-sigma+
10
:element-type '(integer 0 15)
11
:initial-contents '((0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
12
(14 10 4 8 9 15 13 6 1 12 0 2 11 7 5 3)
13
(11 8 12 0 5 2 15 13 10 14 3 6 7 1 9 4)
14
(7 9 3 1 13 12 11 14 2 6 5 10 4 0 15 8)
15
(9 0 5 7 2 4 10 15 14 1 11 12 6 8 3 13)
16
(2 12 6 10 0 11 8 3 4 13 7 5 15 14 1 9)
17
(12 5 1 15 14 13 4 10 0 7 6 3 9 2 8 11)
18
(13 11 7 14 12 1 3 9 5 0 15 4 8 6 2 10)
19
(6 15 14 9 11 3 0 8 12 2 13 7 1 4 10 5)
20
(10 2 8 4 7 6 1 5 15 11 9 14 3 12 13 0)
21
(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
22
(14 10 4 8 9 15 13 6 1 12 0 2 11 7 5 3))))
25
:element-type '(unsigned-byte 64)
26
:initial-contents '(#x6A09E667F3BCC908
33
#x5BE0CD19137E2179))))
35
(defun blake2-make-initial-state (output-length &optional (key-length 0))
36
(when (> output-length 64)
37
(error 'ironclad-error :format-control "The output length must be at most 64 bytes."))
38
(when (> key-length 64)
39
(error 'ironclad-error :format-control "The key length must be at most 64 bytes."))
40
(let ((state (copy-seq +blake2-iv+)))
41
(setf (aref state 0) (logxor (aref state 0)
48
(declaim (ftype (function ((simple-array (unsigned-byte 64) (8))
49
(simple-array (unsigned-byte 8) (*))
54
(defun blake2-rounds (state input start offset final)
55
(declare (type (simple-array (unsigned-byte 64) (8)) state)
56
(type (simple-array (unsigned-byte 8) (*)) input)
58
(type (unsigned-byte 128) offset)
60
(optimize (speed 3) (space 0) (safety 0) (debug 0)))
61
(macrolet ((blake2-mixing (va vb vc vd x y)
62
`(setf ,va (mod64+ (mod64+ ,va ,vb) ,x)
63
,vd (ror64 (logxor ,vd ,va) 32)
65
,vb (ror64 (logxor ,vb ,vc) 24)
66
,va (mod64+ (mod64+ ,va ,vb) ,y)
67
,vd (ror64 (logxor ,vd ,va) 16)
69
,vb (ror64 (logxor ,vb ,vc) 63))))
70
(let ((v0 (aref state 0))
78
(v8 (aref +blake2-iv+ 0))
79
(v9 (aref +blake2-iv+ 1))
80
(v10 (aref +blake2-iv+ 2))
81
(v11 (aref +blake2-iv+ 3))
82
(v12 (aref +blake2-iv+ 4))
83
(v13 (aref +blake2-iv+ 5))
84
(v14 (aref +blake2-iv+ 6))
85
(v15 (aref +blake2-iv+ 7))
86
(m (make-array 16 :element-type '(unsigned-byte 64) :initial-element 0)))
87
(declare (type (unsigned-byte 64) v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15)
88
(type (simple-array (unsigned-byte 64) (16)) m)
90
(setf v12 (logxor v12 (ldb (byte 64 0) offset))
91
v13 (logxor v13 (ldb (byte 64 64) offset)))
93
(setf v14 (logxor v14 #xFFFFFFFFFFFFFFFF)))
95
;; Get input data as 64-bit little-endian integers
96
(dotimes-unrolled (i 16)
97
(setf (aref m i) (ub64ref/le input (+ start (* i 8)))))
100
(dotimes-unrolled (i +blake2-rounds+)
101
(blake2-mixing v0 v4 v8 v12 (aref m (aref +blake2-sigma+ i 0)) (aref m (aref +blake2-sigma+ i 1)))
102
(blake2-mixing v1 v5 v9 v13 (aref m (aref +blake2-sigma+ i 2)) (aref m (aref +blake2-sigma+ i 3)))
103
(blake2-mixing v2 v6 v10 v14 (aref m (aref +blake2-sigma+ i 4)) (aref m (aref +blake2-sigma+ i 5)))
104
(blake2-mixing v3 v7 v11 v15 (aref m (aref +blake2-sigma+ i 6)) (aref m (aref +blake2-sigma+ i 7)))
105
(blake2-mixing v0 v5 v10 v15 (aref m (aref +blake2-sigma+ i 8)) (aref m (aref +blake2-sigma+ i 9)))
106
(blake2-mixing v1 v6 v11 v12 (aref m (aref +blake2-sigma+ i 10)) (aref m (aref +blake2-sigma+ i 11)))
107
(blake2-mixing v2 v7 v8 v13 (aref m (aref +blake2-sigma+ i 12)) (aref m (aref +blake2-sigma+ i 13)))
108
(blake2-mixing v3 v4 v9 v14 (aref m (aref +blake2-sigma+ i 14)) (aref m (aref +blake2-sigma+ i 15))))
111
(setf (aref state 0) (logxor (aref state 0) v0 v8)
112
(aref state 1) (logxor (aref state 1) v1 v9)
113
(aref state 2) (logxor (aref state 2) v2 v10)
114
(aref state 3) (logxor (aref state 3) v3 v11)
115
(aref state 4) (logxor (aref state 4) v4 v12)
116
(aref state 5) (logxor (aref state 5) v5 v13)
117
(aref state 6) (logxor (aref state 6) v6 v14)
118
(aref state 7) (logxor (aref state 7) v7 v15))))
122
;;; Digest structures and functions
124
(:constructor %make-blake2-digest nil)
126
(state (blake2-make-initial-state 64)
127
:type (simple-array (unsigned-byte 64) (8)))
128
(offset 0 :type (unsigned-byte 128))
129
(buffer (make-array 128 :element-type '(unsigned-byte 8) :initial-element 0)
130
:type (simple-array (unsigned-byte 8) (128)))
131
(buffer-index 0 :type (integer 0 128)))
133
(defstruct (blake2/384
135
(:constructor %make-blake2/384-digest
136
(&aux (state (blake2-make-initial-state 48))))
139
(defstruct (blake2/256
141
(:constructor %make-blake2/256-digest
142
(&aux (state (blake2-make-initial-state 32))))
145
(defstruct (blake2/160
147
(:constructor %make-blake2/160-digest
148
(&aux (state (blake2-make-initial-state 20))))
151
(defmethod reinitialize-instance ((state blake2) &rest initargs)
152
(declare (ignore initargs))
153
(setf (blake2-state state) (etypecase state
154
(blake2/160 (blake2-make-initial-state 20))
155
(blake2/256 (blake2-make-initial-state 32))
156
(blake2/384 (blake2-make-initial-state 48))
157
(blake2 (blake2-make-initial-state 64)))
158
(blake2-offset state) 0
159
(blake2-buffer-index state) 0)
162
(defmethod copy-digest ((state blake2) &optional copy)
163
(check-type copy (or null blake2))
167
(blake2/160 (%make-blake2/160-digest))
168
(blake2/256 (%make-blake2/256-digest))
169
(blake2/384 (%make-blake2/384-digest))
170
(blake2 (%make-blake2-digest))))))
171
(declare (type blake2 copy))
172
(replace (blake2-state copy) (blake2-state state))
173
(setf (blake2-offset copy) (blake2-offset state))
174
(replace (blake2-buffer copy) (blake2-buffer state))
175
(setf (blake2-buffer-index copy) (blake2-buffer-index state))
178
(defun blake2-update (state input start end final)
179
(declare (type blake2 state)
180
(type (simple-array (unsigned-byte 8) (*)) input)
181
(type fixnum start end)
183
(optimize (speed 3) (space 0) (safety 0) (debug 0)))
184
(let ((blake2-state (blake2-state state))
185
(offset (blake2-offset state))
186
(buffer (blake2-buffer state))
187
(buffer-index (blake2-buffer-index state))
188
(length (- end start))
190
(declare (type (simple-array (unsigned-byte 64) (8)) blake2-state)
191
(type (unsigned-byte 128) offset)
192
(type (simple-array (unsigned-byte 8) (128)) buffer)
193
(type (integer 0 128) buffer-index)
194
(type fixnum length n))
196
;; Try to fill the buffer with the new data
197
(setf n (min length (- +blake2-block-size+ buffer-index)))
198
(replace buffer input :start1 buffer-index :start2 start :end2 (+ start n))
201
(incf buffer-index n)
205
;; Process as many blocks as we can, but unless we are in the
206
;; final call, keep some data in the buffer (so that it can be
207
;; processed with the 'final' flag in the final call
209
;; Process data in buffer
210
(when (and (= buffer-index +blake2-block-size+)
211
(or final (plusp length)))
212
(blake2-rounds blake2-state buffer 0 offset final)
213
(setf buffer-index 0))
215
;; Process data in message
217
(loop until (<= length +blake2-block-size+) do
218
(incf offset +blake2-block-size+)
219
(blake2-rounds blake2-state input start offset nil)
220
(incf start +blake2-block-size+)
221
(decf length +blake2-block-size+)))
223
;; Put remaining message data in buffer
225
(replace buffer input :end1 length :start2 start)
227
(incf buffer-index length))
229
;; Save the new state
230
(setf (blake2-offset state) offset
231
(blake2-buffer-index state) buffer-index)
234
(defun blake2-finalize (state digest digest-start)
235
(let* ((digest-length (digest-length state))
236
(blake2-state (blake2-state state))
237
(buffer-index (blake2-buffer-index state))
238
(padding-length (- +blake2-block-size+ buffer-index))
239
(padding (make-array padding-length
240
:element-type '(unsigned-byte 8)
241
:initial-element 0)))
243
;; Process remaining data after padding it
244
(blake2-update state padding 0 padding-length t)
247
(let ((output (make-array +blake2-block-size+ :element-type '(unsigned-byte 8) :initial-element 0)))
249
(setf (ub64ref/le output (* i 8)) (aref blake2-state i)))
250
(replace digest output :start1 digest-start :end2 digest-length)
253
(define-digest-updater blake2
254
(blake2-update state sequence start end nil))
256
(define-digest-finalizer ((blake2 64)
260
(blake2-finalize state digest digest-start))
262
(defdigest blake2 :digest-length 64 :block-length 128)
263
(defdigest blake2/384 :digest-length 48 :block-length 128)
264
(defdigest blake2/256 :digest-length 32 :block-length 128)
265
(defdigest blake2/160 :digest-length 20 :block-length 128)