Coverage report: /home/ellis/comp/ext/ironclad/src/public-key/dsa.lisp
Kind | Covered | All | % |
expression | 0 | 488 | 0.0 |
branch | 0 | 32 | 0.0 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;;; dsa.lisp -- implementation of the Digital Signature Algorithm
6
((group :initarg :group :reader group)))
8
(defclass dsa-public-key (dsa-key)
9
((y :initarg :y :reader dsa-key-y :type integer)))
11
(defclass dsa-private-key (dsa-key)
12
((y :initarg :y :reader dsa-key-y :type integer)
13
(x :initarg :x :reader dsa-key-x :type integer)))
15
(defun dsa-key-p (dsa-key)
16
(group-pval (group dsa-key)))
17
(defun dsa-key-q (dsa-key)
18
(group-qval (group dsa-key)))
19
(defun dsa-key-g (dsa-key)
20
(group-gval (group dsa-key)))
22
;;; function definitions
23
(defmethod make-public-key ((kind (eql :dsa))
24
&key p q g y &allow-other-keys)
26
(error 'missing-key-parameter
29
:description "modulus"))
31
(error 'missing-key-parameter
34
:description "subgroup modulus"))
36
(error 'missing-key-parameter
39
:description "generator"))
41
(error 'missing-key-parameter
44
:description "public key"))
45
(let ((group (make-instance 'discrete-logarithm-group :p p :q q :g g)))
46
(make-instance 'dsa-public-key :group group :y y)))
48
(defmethod destructure-public-key ((public-key dsa-public-key))
49
(list :p (dsa-key-p public-key)
50
:q (dsa-key-q public-key)
51
:g (dsa-key-g public-key)
52
:y (dsa-key-y public-key)))
54
(defmethod make-private-key ((kind (eql :dsa))
55
&key p q g y x &allow-other-keys)
57
(error 'missing-key-parameter
60
:description "modulus"))
62
(error 'missing-key-parameter
65
:description "subgroup modulus"))
67
(error 'missing-key-parameter
70
:description "generator"))
72
(error 'missing-key-parameter
75
:description "private key"))
76
(let ((group (make-instance 'discrete-logarithm-group :p p :q q :g g)))
77
(make-instance 'dsa-private-key :group group :x x :y (or y (expt-mod g x p)))))
79
(defmethod destructure-private-key ((private-key dsa-private-key))
80
(list :p (dsa-key-p private-key)
81
:q (dsa-key-q private-key)
82
:g (dsa-key-g private-key)
83
:x (dsa-key-x private-key)
84
:y (dsa-key-y private-key)))
86
(defmethod generate-key-pair ((kind (eql :dsa)) &key num-bits &allow-other-keys)
88
(error 'missing-key-parameter
91
:description "modulus size"))
92
(let* ((n (cond ((< num-bits 512) (error 'ironclad-error
93
:format-control "NUM-BITS is too small for a DSA key."))
94
((<= num-bits 1024) 160)
95
((<= num-bits 2048) 224)
96
((<= num-bits 3072) 256)
97
((<= num-bits 7680) 384)
98
((<= num-bits 15360) 512)
99
(t (error 'ironclad-error
100
:format-control "NUM-BITS is too big for a DSA key."))))
101
(q (generate-prime n))
102
(p (loop for z = (logior (ash 1 (- num-bits n 1))
103
(dpb 0 (byte 1 0) (random-bits (- num-bits n))))
105
until (and (= num-bits (integer-length p))
108
(g (find-subgroup-generator p q))
109
(x (+ 2 (strong-random (- q 2))))
110
(y (expt-mod g x p)))
111
(values (make-private-key :dsa :p p :q q :g g :y y :x x)
112
(make-public-key :dsa :p p :q q :g g :y y))))
114
(defmethod generate-signature-nonce ((key dsa-private-key) message &optional q)
115
(declare (ignore key message))
116
(or *signature-nonce-for-test*
117
(1+ (strong-random (1- q)))))
119
(defmethod make-signature ((kind (eql :dsa)) &key r s n-bits &allow-other-keys)
121
(error 'missing-signature-parameter
124
:description "first signature element"))
126
(error 'missing-signature-parameter
129
:description "second signature element"))
131
(error 'missing-signature-parameter
134
:description "subgroup modulus size"))
135
(concatenate '(simple-array (unsigned-byte 8) (*))
136
(integer-to-octets r :n-bits n-bits)
137
(integer-to-octets s :n-bits n-bits)))
139
(defmethod destructure-signature ((kind (eql :dsa)) signature)
140
(let ((length (length signature)))
142
(error 'invalid-signature-length :kind 'dsa)
143
(let* ((middle (/ length 2))
144
(n-bits (* middle 8))
145
(r (octets-to-integer signature :start 0 :end middle))
146
(s (octets-to-integer signature :start middle)))
147
(list :r r :s s :n-bits n-bits)))))
149
;;; Note that hashing is not performed here.
150
(defmethod sign-message ((key dsa-private-key) message &key (start 0) end &allow-other-keys)
151
(let* ((end (or end (length message)))
153
(qbits (integer-length q)))
154
(when (> (* 8 (- end start)) qbits)
155
;; Only keep the required number of bits of message
156
(setf end (+ start (/ qbits 8))))
157
(let* ((m (octets-to-integer message :start start :end end))
161
(k (generate-signature-nonce key message q))
162
(r (mod (expt-mod g k p) q))
163
(k-inverse (modular-inverse-with-blinding k q))
164
(s (mod (* k-inverse (+ (* x r) m)) q)))
165
(assert (= (mod (* k k-inverse) q) 1))
166
(if (not (or (zerop r) (zerop s)))
167
(make-signature :dsa :r r :s s :n-bits qbits)
168
(sign-message key message :start start :end end)))))
170
(defmethod verify-signature ((key dsa-public-key) message signature &key (start 0) end &allow-other-keys)
171
(let* ((end (or end (length message)))
173
(qbits (integer-length q)))
174
(unless (= (* 4 (length signature)) qbits)
175
(error 'invalid-signature-length :kind 'dsa))
176
(when (> (* 8 (- end start)) qbits)
177
;; Only keep the required number of bits of message
178
(setf end (+ start (/ qbits 8))))
179
(let* ((m (octets-to-integer message :start start :end end))
183
(signature-elements (destructure-signature :dsa signature))
184
(r (getf signature-elements :r))
185
(s (getf signature-elements :s)))
186
(unless (and (< 0 r q) (< 0 s q))
187
(return-from verify-signature nil))
188
(let* ((w (modular-inverse s q))
191
(v (mod (mod (* (expt-mod g u1 p) (expt-mod y u2 p)) p) q)))