|
1 | 1 | (defpackage #:prototype
|
2 |
| - (:export #:KEM-Encaps |
3 |
| - #:HDK #:*ID* |
| 2 | + (:export #:KEM-Encap |
| 3 | + #:HDK |
4 | 4 | #:make-unit #:activate #:prove-possession #:request #:accept
|
5 | 5 | #:make-reader #:pk #:verify
|
6 | 6 | #:make-document)
|
|
66 | 66 | do (loop for j across ti do (vector-push j tb))
|
67 | 67 | finally (return (coerce tb '(vector (unsigned-byte 8))))))
|
68 | 68 |
|
69 |
| -(defun ECP2OS (point) |
70 |
| - (|| (I2OSP (getf (crypto:ec-destructure-point point) :x) 32) |
71 |
| - (I2OSP (getf (crypto:ec-destructure-point point) :y) 32))) |
72 |
| -(defun OS2ECP (b) |
73 |
| - (crypto:ec-make-point |
74 |
| - *EC* :x (OS2IP (subseq b 0 32)) :y (OS2IP (subseq b 32)))) |
75 |
| - |
76 |
| -(defun KEM-Derive-Key-Pair (msg ctx) ; TODO #80 |
77 |
| - (let* ((*DST* (|| *ID* '(#x01) ctx)) |
78 |
| - (*q* (EC-Order)) |
79 |
| - (sk (hash_to_field msg))) |
80 |
| - (values (EC-Scalar-Base-Mult sk) sk))) |
81 |
| -(defun KEM-Encaps (pk ctx) |
82 |
| - (let* ((sk-prime (EC-Random)) |
83 |
| - (pk-prime (EC-Scalar-Base-Mult sk-prime)) |
84 |
| - (k-prime (ECDH-Create-Shared-Secret sk-prime pk)) |
85 |
| - (prk (HKDF-Extract (I2OSP 0 32) k-prime))) |
86 |
| - (values (HKDF-Expand prk (|| (ASCII "TMPKEM") ctx) 32) (ECP2OS pk-prime)))) |
87 |
| -(defun KEM-Decaps (sk c ctx) |
88 |
| - (let* ((pk-prime (OS2ECP c)) |
89 |
| - (k-prime (ECDH-Create-Shared-Secret sk pk-prime)) |
90 |
| - (prk (HKDF-Extract (I2OSP 0 32) k-prime))) |
91 |
| - (HKDF-Expand prk (|| (ASCII "TMPKEM") ctx) 32))) |
| 69 | +;; RFC 9180 |
| 70 | +(defparameter *Nsecret* 32) |
| 71 | +(defparameter *Nsk* 32) |
| 72 | +(defparameter *suite_id* (I2OSP #x0010 2)) ;; DHKEM(P-256, HKDF-SHA256) |
| 73 | +(defparameter *bitmask* #xff) |
| 74 | +(labels ((LabeledExtract (salt label ikm) |
| 75 | + (HKDF-Extract salt (|| (ASCII "HPKE-v1") *suite_id* label ikm))) |
| 76 | + (LabeledExpand (prk label info L) |
| 77 | + (HKDF-Expand |
| 78 | + prk (|| (I2OSP L 2) (ASCII "HPKE-v1") *suite_id* label info) |
| 79 | + L)) |
| 80 | + (ExtractAndExpand (dh kem_context) |
| 81 | + (let* ((eae_prk (LabeledExtract (ASCII "") (ASCII "eae_prk") dh)) |
| 82 | + (shared_secret |
| 83 | + (LabeledExpand |
| 84 | + eae_prk (ASCII "shared_secret") kem_context *Nsecret*))) |
| 85 | + shared_secret)) |
| 86 | + (GenerateKeyPair () |
| 87 | + (let ((sk (EC-Random))) (values sk (EC-Scalar-Base-Mult sk)))) |
| 88 | + (SerializePublicKey (pk) |
| 89 | + (|| (I2OSP (getf (crypto:ec-destructure-point pk) :x) 32) |
| 90 | + (I2OSP (getf (crypto:ec-destructure-point pk) :y) 32))) |
| 91 | + (DeserializePublicKey (b) |
| 92 | + (crypto:ec-make-point |
| 93 | + *EC* :x (OS2IP (subseq b 0 32)) :y (OS2IP (subseq b 32))))) |
| 94 | + (defun KEM-Derive-Key-Pair (ikm) ;; todo test vectors |
| 95 | + (loop with dkp_prk = (LabeledExtract (ASCII "") (ASCII "dkp_prk") ikm) |
| 96 | + for counter from 0 upto 254 |
| 97 | + for bytes = (LabeledExpand dkp_prk (ASCII "candidate") |
| 98 | + (I2OSP counter 1) *Nsk*) |
| 99 | + for sk = (progn |
| 100 | + (setf (aref bytes 0) (logand (aref bytes 0) *bitmask*)) |
| 101 | + (OS2IP bytes)) |
| 102 | + when (not (= sk 0)) return (values sk (EC-Scalar-Base-Mult sk)))) |
| 103 | + (defun KEM-Encap (pkR) |
| 104 | + (multiple-value-bind (skE pkE) (GenerateKeyPair) |
| 105 | + (let* ((dh (ECDH-Create-Shared-Secret skE pkR)) |
| 106 | + (enc (SerializePublicKey pkE)) |
| 107 | + (pkRm (SerializePublicKey pkR)) |
| 108 | + (kem_context (|| enc pkRm)) |
| 109 | + (shared_secret (ExtractAndExpand dh kem_context))) |
| 110 | + (values shared_secret enc)))) |
| 111 | + (defun KEM-Decap (enc skR) |
| 112 | + (let* ((pkE (DeserializePublicKey enc)) |
| 113 | + (dh (ECDH-Create-Shared-Secret skR pkE)) |
| 114 | + (pkRm (SerializePublicKey (EC-Scalar-Base-Mult skR))) |
| 115 | + (kem_context (|| enc pkRm)) |
| 116 | + (shared_secret (ExtractAndExpand dh kem_context))) |
| 117 | + shared_secret))) |
92 | 118 |
|
93 | 119 | (defun Authenticate (sk_device reader_data bf)
|
94 | 120 | (ECDH-Create-Shared-Secret sk_device (EC-Scalar-Mult reader_data bf)))
|
|
106 | 132 | (if (null bf) (fold salt (cdr path) bf-prime)
|
107 | 133 | (fold salt (cdr path)
|
108 | 134 | (BL-Combine-Blinding-Factors bf bf-prime)))))
|
109 |
| - (t (multiple-value-bind (pk sk) (KEM-Derive-Key-Pair salt *ID*) |
| 135 | + (t (multiple-value-bind (pk sk) (KEM-Derive-Key-Pair salt) |
110 | 136 | (declare (ignore pk))
|
111 |
| - (fold (KEM-Decaps sk (car path) *ID*) (cdr path) bf))))) |
| 137 | + (fold (KEM-Decap (car path) sk) (cdr path) bf))))) |
112 | 138 |
|
113 | 139 | (defclass document () ((pk :reader pk :initarg :pk)))
|
114 | 140 | (defun make-document (doc salt index)
|
|
127 | 153 | (defun create-shared-secret (app hdk reader-pk)
|
128 | 154 | (Authenticate (cadr (device app)) reader-pk (fold (seed app) hdk)))
|
129 | 155 | (defun delegate-key-creation (app hdk)
|
130 |
| - (KEM-Derive-Key-Pair (nth-value 1 (fold (seed app) hdk)) *ID*)) |
| 156 | + (KEM-Derive-Key-Pair (nth-value 1 (fold (seed app) hdk)))) |
131 | 157 | (defun accept-key (app hdk kh index pk-expected)
|
132 | 158 | (multiple-value-bind (pk sk) (delegate-key-creation app hdk)
|
133 | 159 | (declare (ignore pk))
|
134 |
| - (let ((salt (KEM-Decaps sk kh *ID*)) |
| 160 | + (let ((salt (KEM-Decap kh sk)) |
135 | 161 | (pk-bl (get-key-info app hdk)))
|
136 | 162 | (assert (EC-Point-Equal
|
137 | 163 | pk-expected
|
|
200 | 226 | "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34"
|
201 | 227 | "007208d5b887185865")))))
|
202 | 228 |
|
203 |
| -(assert (multiple-value-bind (pk sk) (KEM-Derive-Key-Pair |
204 |
| - (I2OSP #x01 4) |
205 |
| - (I2OSP #x02 4)) |
206 |
| - (multiple-value-bind (k c) (KEM-Encaps pk (ASCII "info")) |
207 |
| - (= (OS2IP k) (OS2IP (KEM-Decaps sk c (ASCII "info"))))))) |
| 229 | +(assert (multiple-value-bind (sk pk) (KEM-Derive-Key-Pair (I2OSP #x01 4)) |
| 230 | + (multiple-value-bind (k c) (KEM-Encap pk) |
| 231 | + (= (OS2IP k) (OS2IP (KEM-Decap c sk)))))) |
208 | 232 |
|
209 | 233 | (let* ((app (make-app))
|
210 | 234 | (pk-bl (get-key-info app +hdk-root+))
|
211 | 235 | (pk-kem (delegate-key-creation app +hdk-root+)))
|
212 |
| - (multiple-value-bind (salt kh) (KEM-Encaps pk-kem *ID*) |
| 236 | + (multiple-value-bind (salt kh) (KEM-Encap pk-kem) |
213 | 237 | (let ((pk-expected (BL-Blind-Public-Key pk-bl (HDK salt 0))))
|
214 | 238 | (accept-key app +hdk-root+ kh 0 pk-expected))))
|
215 | 239 |
|
|
219 | 243 | (device-data (prove-possession unit doc (pk reader))))
|
220 | 244 | (assert (verify reader doc device-data)))
|
221 | 245 | (let ((pk-kem (request unit doc)))
|
222 |
| - (multiple-value-bind (salt kh) (KEM-Encaps pk-kem *ID*) |
| 246 | + (multiple-value-bind (salt kh) (KEM-Encap pk-kem) |
223 | 247 | (let* ((range '(0 1 2 3 4 5 6 7 8))
|
224 | 248 | (docs (loop for i in range collect (make-document doc salt i))))
|
225 | 249 | (loop for i in range for d in docs do (accept unit doc kh i d))
|
|
0 commit comments