Coverage report: /home/ellis/comp/ext/ironclad/src/kdf/scrypt.lisp
Kind | Covered | All | % |
expression | 0 | 222 | 0.0 |
branch | 0 | 0 | nil |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
4
;;; scrypt from Colin Percival's
5
;;; "Stronger Key Derivation via Sequential Memory-Hard Functions"
6
;;; presented at BSDCan'09, May 2009.
7
;;; http://www.tarsnap.com/scrypt.html
8
(defclass scrypt-kdf ()
9
((n :initarg :n :reader scrypt-kdf-N)
10
(r :initarg :r :reader scrypt-kdf-r)
11
(p :initarg :p :reader scrypt-kdf-p)))
13
(defun scrypt-vector-salsa (b)
14
(declare (type (simple-octet-vector 64) b))
15
(let ((x (make-array 16 :element-type '(unsigned-byte 32))))
16
(declare (type (simple-array (unsigned-byte 32) (16)) x))
17
(declare (dynamic-extent x))
18
(fill-block-ub8-le x b 0)
19
(salsa20/8-core b x)))
21
(defun block-mix (b xy xy-start r)
22
(declare (type (simple-array (unsigned-byte 8) (*)) b xy))
23
;; The derivation of the bound here is that (* I 64) in the first loop below
24
;; must be a legitimate array index. That loop runs to (* 2 R), hence the
25
;; truncation by 128. The subtraction of 64 comes from loops further down.
26
(declare (type (integer 0 (#.(truncate (- array-dimension-limit 64) 128))) r))
27
(let ((xs (make-array 64 :element-type '(unsigned-byte 8))))
28
(declare (type (simple-array (unsigned-byte 8) (64)) xs))
29
(declare (dynamic-extent xs))
30
(replace xs b :start2 (* 64 (1- (* 2 r))) :end1 64)
32
(xor-block 64 xs 0 b (* i 64) xs 0)
33
(scrypt-vector-salsa xs)
34
(replace xy xs :start1 (+ xy-start (* i 64)) :end2 64))
36
(replace b xy :start1 (* i 64) :end1 (+ 64 (* i 64)) :start2 (+ xy-start (* 64 2 i))))
38
(replace b xy :start1 (* 64 (+ i r)) :end1 (+ (* 64 (+ i r)) 64) :start2 (+ xy-start (* 64 (1+ (* i 2))))))))
40
(defun smix (b b-start r N v xy)
41
(declare (type (simple-array (unsigned-byte 8) (*)) b v xy))
42
(declare (type (integer 0 (#.(truncate array-dimension-limit 128))) r))
45
(smix-length (* 128 r)))
46
(replace x b :end1 smix-length :start2 b-start)
48
(replace v x :start1 (* i smix-length) :end2 smix-length)
49
(block-mix x xy xy-start r))
51
(let ((j (ldb (byte 32 0) (logand (ub64ref/le x (* (1- (* 2 r)) 64)) (1- N)))))
52
(xor-block smix-length x 0 v (* j smix-length) x 0)
53
(block-mix x xy xy-start r)))
54
(replace b x :start1 b-start :end1 (+ b-start smix-length))))
56
(defmethod derive-key ((kdf scrypt-kdf) passphrase salt iteration-count key-length)
57
(declare (ignore iteration-count))
58
(let* ((pb-kdf (make-kdf 'pbkdf2 :digest 'sha256))
59
(xy (make-array (* 256 (scrypt-kdf-r kdf)) :element-type '(unsigned-byte 8)))
60
(v (make-array (* 128 (scrypt-kdf-r kdf) (scrypt-kdf-N kdf)) :element-type '(unsigned-byte 8)))
61
(b (derive-key pb-kdf passphrase salt 1 (* (scrypt-kdf-p kdf) 128 (scrypt-kdf-r kdf)))))
62
(dotimes (i (scrypt-kdf-p kdf))
63
(smix b (* i 128 (scrypt-kdf-r kdf)) (scrypt-kdf-r kdf) (scrypt-kdf-N kdf) v xy))
64
(reinitialize-instance pb-kdf :digest 'sha256)
65
(derive-key pb-kdf passphrase b 1 key-length)))