You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: draft-dijkhuis-cfrg-hdkeys.md
+98-63
Original file line number
Diff line number
Diff line change
@@ -39,9 +39,7 @@ normative:
39
39
author:
40
40
- organization: ISO/IEC
41
41
date: 2019-09
42
-
RFC7800:
43
42
RFC8017:
44
-
RFC8235:
45
43
RFC9180:
46
44
RFC9380:
47
45
SEC2:
@@ -94,6 +92,9 @@ informative:
94
92
(EU): 2024/1183
95
93
date: 2024-04
96
94
I-D.draft-bradleylundberg-cfrg-arkg-02:
95
+
I-D.draft-irtf-cfrg-signature-key-blinding-07:
96
+
RFC7800:
97
+
RFC8235:
97
98
Verheul2024:
98
99
title: Attestation Proof of Association – provability that attestation keys are bound to the same hardware and person
99
100
target: https://eprint.iacr.org/2024/1444
@@ -145,9 +146,9 @@ Solutions MAY omit application of the remote functionality. In this case, a unit
145
146
The following example illustrates the use of local key derivation. An HDK tree is associated with a device key pair and initiated using confidential static data: a `seed` value, which is a byte array containing sufficient entropy. Now tree nodes are constructed as follows.
The unit computes a Level 0 HDK at the root node using a deterministic function: `(bf0, salt0) = hdk0 = HDK(seed, 0)`. The HDK consists of a first blinding factor `bf0` and a first byte string `salt0` to derive next-level keys. Using `bf0` and the device key pair, the unit can compute blinded public and private keys and proofs of possession.
166
+
The unit computes a Level 0 HDK at the root node using a deterministic function, taking the device public key `pk` and the `seed` as input: `(pk0, salt0, bf0) = hdk0 = HDK(0, pk, seed)`. The HDK consists of a first blinded public key `pk0`, a first byte string `salt0` to derive next-level keys, and a first blinding factor `bf0`. Using `bf0` and the device key pair, the unit can compute blinded private keys and proofs of possession.
166
167
167
-
The unit computes any Level `n > 0` HDK from any other HDK `(bf, salt)` using the same deterministic function: `(bf', salt') = hdk' = HDK(salt, index)`. The function takes the previous-level `salt` as input, and an `index` starting at 0. The function returns a new HDK as output, which can be used in the same way as the root HDK.
168
+
The unit computes any Level `n > 0` HDK from any other HDK `(pk, salt, bf)` using the same deterministic function: `(pk', salt', bf') = hdk' = HDK(index, pk, salt, bf)`. The function takes as input the `index` starting at 0, an the previous-level HDK. The function returns a new HDK as output, which can be used in the same way as the root HDK.
168
169
169
170
### Remote deterministic key derivation
170
171
171
172
Instead of local derivation, an HDK salt can also be derived using a key handle that is generated remotely. Using the derived salt, the local and remote parties can derive the same new HDKeys. The remote party can use these to derive public keys. The local party can use these to derive associated private keys for proof of possession.
172
173
173
-
This approach is similar to Asynchronous Remote Key Generation (ARKG) [I-D.draft-bradleylundberg-cfrg-arkg-02], but not the same since ARKG does not enable distributed proof of possession with deterministic hierarchies. This makes it difficult to implement with cryptographic devices that lack specific firmware support.
174
+
This approach is similar to Asynchronous Remote Key Generation (ARKG) [I-D.draft-bradleylundberg-cfrg-arkg-02], but not the same since ARKG does not enable distributed proof of possession with deterministic hierarchies. These hierarchies can be used for example to enable remote parties to derive keys from previously derived keys. Not supporting these makes it difficult to implement with cryptographic devices that lack specific firmware support.
174
175
175
176
To enable remote derivation of child HDKeys, the unit uses the parent HDKey to derive the parent public key and a second public key for key encapsulation. The issuer returns a key handle, using which both parties can derive a sequence of child HDKeys. Key encapsulation prevents other parties from discovering a link between the public keys of the parent and the children, even if the other party knows the parent HDK or can eavesdrop communications.
176
177
@@ -180,7 +181,7 @@ Locally derived parents can have remotely derived children. Remotely derived par
180
181
181
182
The next concept to illustrate is blinded proof of possession. This enables a unit to prove possession of a (device) private key without disclosing the directly associated public key. This way, solutions can avoid linkability across readers of a digital document that is released with proof of possession.
182
183
183
-
In this example, a document is issued with binding to a public key `pk'`, which is a blinding public key `pk` blinded with the blinding factor `bf` in some HDK `hdk = (bf, salt)`. The unit can present the document with a proof of possession of the corresponding blinded private key, which is the blinding private key `sk` blinded with `bf`. The unit applies some authentication function `device_data = authenticate(sk, reader_data, bf)` to the blinding private key, reader-provided data and the blinding factor. The unit can subsequently use the output `device_data` to prove possession to the reader using common algorithms.
184
+
In this example, a document is issued with binding to a public key `pk'`, which is a blinding public key `pk` blinded with the blinding factor `bf` in some HDK `hdk = (pk', salt, bf)`. The unit can present the document with a proof of possession of the corresponding blinded private key, which is the blinding private key `sk` blinded with `bf`. The unit applies some authentication function `device_data = authenticate(sk, reader_data, bf)` to the blinding private key, reader-provided data and the blinding factor. The unit can subsequently use the output `device_data` to prove possession to the reader using common algorithms.
184
185
185
186
~~~
186
187
+------------------+ +--------+
@@ -225,45 +226,98 @@ The parameters of an HDK instantiation are:
225
226
- `ID`: A domain separation tag, represented as a string of ASCII bytes.
226
227
- `Ns`: The amount of bytes of a salt value with sufficient entropy.
227
228
- `H`: A cryptographic hash function.
228
-
- H1(msg): Outputs `Ns` bytes.
229
-
- `BL`: An asymmetric key blinding scheme with opaque blinding factors and algebraic properties, consisting of the functions:
230
-
- BL-Generate-Blinding-Key-Pair(): Outputs a blinding key pair `(pk, sk)`.
231
-
- BL-Derive-Blinding-Factor(msg, ctx): Outputs a blinding factor `bf` based on two byte string inputs, message `msg` and domain separation parameter `ctx`.
232
-
- BL-Blind-Public-Key(pk, bf): Outputs the result `pk'` of blinding `pk` with `bf`. This again is a blinding public key.
233
-
- BL-Blind-Private-Key(sk, bf): Outputs the result `sk'` of blinding `sk` with `bf`. This again is a blinding private key.
234
-
- BL-Combine-Blinding-Factors(bf1, bf2): Outputs a blinding factor `bf` such that for all blinding key pairs `(pk, sk)`:
- `D`: An digital signature algorithm or shared secret creation algorithm based on public key cryptography, consisting of the functions:
231
+
- D-Generate-Key-Pair(): Outputs a key pair `(sk, pk)`.
232
+
- `BL`: An asymmetric key blinding scheme for `D` as defined in [I-D.draft-irtf-cfrg-signature-key-blinding-07], with opaque blinding factors and algebraic properties, consisting of the functions:
233
+
- BL-Derive-Blind-Key(ikm): Outputs a blind key `bk` based on input keying material `ikm`.
234
+
- BL-Derive-Blinding-Factor(bk, ctx): Outputs a blinding factor `bf` based on a blind key `bk` and an application context byte string `ctx`.
235
+
- BL-Blind-Public-Key(pk, bk, ctx): Outputs the result `pk'` of blinding public key `pk` with blind key `bk` and application context byte string `ctx`. This again is a public key in `D`.
236
+
- BL-Blind-Private-Key(sk, bf): Outputs the result `sk'` of blinding private key `sk` with blinding factor `bf`. This result is a private key in `D`, such that if `bf = BL-Derive-Blinding-Factor(bk, ctx)` for some `bk` and `ctx`, the associated public key in `D` equals `BL-Blind-Public-Key(pk, bk, ctx)`.
237
+
- BL-Combine(bf1, bf2): Outputs a blinding factor `bf` such that for all key pairs `(pk, sk)` in `D`:
- `Authenticate(sk_device, reader_data, bf)`: Outputs `device_data` for use in a protocol for proof of possession, taking a BL blinding private key `sk_device`, remotely received `reader_data`, and a BL blinding factor `bf`.
242
243
243
244
An HDK instantiation MUST specify the instantiation of each of the above functions and values.
244
245
245
-
An HDK instantiation MUST define Authenticate such that the `device_data` can be verified using the blinded public key `pk = BL-Blind-Public-Key(sk, bf)`. The reader does not need to know that HDK was applied: the public key will look like any other public key used for proofs of possession.
246
+
Note that by design of `BL`, when a document is issued using HDK, the reader does not need to know that HDK was applied: the public key will look like any other public key used for proofs of possession.
246
247
247
-
## The HDK function
248
+
An HDK implementation MAY leave BL-Blind-Private-Key implicit in cases where the blinding method is constructed in a distributed way. In those cases, the secure cryptographic device holding the private key does not need to support key blinding, and the value of the blinded private key is never available during computation.
249
+
250
+
## The HDK context
251
+
252
+
A local unit or remote party creates an HDK context from an index.
253
+
254
+
~~~
255
+
Inputs:
256
+
- index, an integer between 0 and 2^32-1 (inclusive).
257
+
258
+
Outputs:
259
+
- ctx, an application context byte string.
260
+
261
+
def HDK-Create-Context(index):
262
+
ctx = ID || I2OSP(index, 4)
263
+
return ctx
264
+
~~~
248
265
249
-
A local unit or a remote party deterministically computes an HDK from a salt and an index. The salt can be an initial seed value of `Ns` bytes or it can be taken from another parent HDK. The secure generation of the seed is out of scope for this specification.
266
+
## The HDK salt
267
+
268
+
A local unit or remote party derives a next-level HDK salt from within an HDK context.
250
269
251
270
~~~
252
271
Inputs:
253
272
- salt, a string of Ns bytes.
273
+
- ctx, an HDK context byte string.
274
+
275
+
Outputs:
276
+
- salt', the next salt for HDK derivation.
277
+
278
+
def HDK-Derive-Salt(salt, ctx):
279
+
salt' = H(ID || salt || ctx)
280
+
return salt'
281
+
~~~
282
+
283
+
## The HDK function
284
+
285
+
A local unit or a remote party deterministically computes an HDK from an index, a parent public key, a salt, and an optional parent blinding factor. The salt can be an initial seed value of `Ns` bytes or it can be taken from another parent HDK. The secure generation of the seed is out of scope for this specification.
286
+
287
+
~~~
288
+
Inputs:
254
289
- index, an integer between 0 and 2^32-1 (inclusive).
290
+
- pk, a public key to be blinded.
291
+
- salt, a string of Ns bytes.
292
+
- bf, a blinding factor to combine with, Nil otherwise.
255
293
256
294
Outputs:
257
-
- bf, the blinding factor at the provided index.
295
+
- pk', the blinded public key at the provided index.
258
296
- salt', the salt for HDK derivation at the provided index.
A unit MUST NOT persist a blinded private key. Instead, if persistence is needed, a unit can persist either the blinding factor of each HDK, or a path consisting of the seed salt, indices and key handles. In both cases, the application of BL-Combine in the HDK function enables reconstruction of the blinding factor with respect to the original private key, enabling application of for example BL-Blind-Private-Key.
314
+
315
+
If the unit uses the blinded private key directly, the unit MUST use it within the secure cryptographic device protecting the device private key.
316
+
317
+
If the unit uses the blinded private key directly, the unit MUST ensure the secure cryptographic device deletes it securely from memory after usage.
318
+
319
+
When presenting multiple documents, a reader can require a proof that multiple keys are associated to a single device. Several protocols for a cryptographic proof of association are possible, such as [Verheul2024]. For example, a unit could prove in a zero-knowledge protocol knowledge of the association between two elliptic curve keys `B1 = [bf1]D` and `B2 = [bf2]D`, where `bf1` and `bf2` are multiplicative blinding factors for a common blinding public key `D`. In this protocol, the association is known by the discrete logarithm of `B2 = [bf2/bf1]B1` with respect to generator `B1`. The unit can apply BL-Combine-Blinding-Factors to obtain values to compute this association.
320
+
267
321
## The local HDK procedure
268
322
269
323
This is a procedure executed locally by a unit.
@@ -272,38 +326,36 @@ To begin, the unit securely generates a `seed` salt of `Ns` bytes and a device k
272
326
273
327
~~~
274
328
seed = random(Ns) # specification of random out of scope
sk = BL-Blind-Private-Key(sk_device, bf) # optional
287
340
~~~
288
341
289
-
Now the unit can use the blinded key pair `(pk, sk)` or derive child HDKeys.
342
+
Now the unit can use the blinded key pair `(sk, pk)` or derive child HDKeys.
290
343
291
-
Whenever the unit requires the HDK with some `index` at level `n > 0` based on a parent HDK `hdk = (bf, salt)` with blinded key pair `(pk, sk)` at level `n`, the unit computes:
344
+
Whenever the unit requires the HDK with some `index` at level `n > 0` based on a parent HDK `hdk = (pk, salt, bf)` with blinded key pair `(sk, pk)` at level `n`, the unit computes:
292
345
293
346
~~~
294
-
(bf', salt') = HDK(salt, index)
347
+
(pk', salt', bf') = HDK(index, pk, salt)
295
348
296
-
pk' = BL-Blind-Public-Key( pk, bf') # optional
297
349
sk' = BL-Blind-Private-Key(sk, bf') # optional
298
350
~~~
299
351
300
-
Now the unit can use the blinded key pair `(pk', sk')` or derive child HDKeys.
352
+
Now the unit can use the blinded key pair `(sk', pk')` or derive child HDKeys.
301
353
302
354
## The remote HDK protocol
303
355
304
356
This is a protocol between a local unit and a remote issuer.
305
357
306
-
As a prerequisite, the unit possesses a `salt` of `Ns` bytes associated with a parent blinding key pair `(pk, sk)` generated using the local HDK procedure.
358
+
As a prerequisite, the unit possesses a `salt` of `Ns` bytes associated with a parent key pair `(sk, pk)` generated using the local HDK procedure.
307
359
308
360
~~~
309
361
# 1. Unit computes:
@@ -312,47 +364,30 @@ As a prerequisite, the unit possesses a `salt` of `Ns` bytes associated with a p
312
364
# 2. Unit shares with issuer: (pk, pk_kem)
313
365
314
366
# 3. Issuer computes:
315
-
(salt, kh) = KEM-Encap(pk_kem)
367
+
(salt_kem, kh) = KEM-Encap(pk_kem)
316
368
317
369
# 4. Issuer shares with unit: kh
318
370
319
371
# Subsequently, for any index known to both parties:
After step 7, the unit can use the value of `salt''` to derive next-level HDKeys.
387
+
After step 7, the unit can use the value of `salt'` to derive next-level HDKeys.
337
388
338
389
Step 4 MAY be postponed to be combined with step 6. Steps 5 to 8 MAY be combined in concurrent execution for multiple indices.
339
390
340
-
## Combining blinding factors
341
-
342
-
A unit MUST not persist a blinded private key. Instead, if persistence is needed, a unit can persist either the blinding factor of each HDK, or a path consisting of the seed salt, indices and key handles. In both cases, the unit needs to combine parent blinding factor `bf1` with child blinding factor `bf2` before blinding the parent private key `sk`:
343
-
344
-
~~~
345
-
bf = BL-Combine-Blinding-Factors(bf1, bf2)
346
-
~~~
347
-
348
-
Subsequently, the unit can apply the Authenticate function to the parent blinding key. The unit can combine multiple blinding factors in the HDK path.
349
-
350
-
If the unit uses the blinded private key directly, the unit MUST use it within the secure cryptographic device protecting the device private key.
351
-
352
-
If the unit uses the blinded private key directly, the unit MUST ensure the secure cryptographic device deletes it securely from memory after usage.
353
-
354
-
When presenting multiple documents, a reader can require a proof that multiple keys are associated to a single device. Several protocols for a cryptographic proof of association are possible, such as [Verheul2024]. For example, a unit could prove in a zero-knowledge protocol knowledge of the association between two elliptic curve keys `B1 = [bf1]D` and `B2 = [bf2]D`, where `bf1` and `bf2` are multiplicative blinding factors for a common blinding public key `D`. In this protocol, the association is known by the discrete logarithm of `B2 = [bf2/bf1]B1` with respect to generator `B1`. The unit can apply BL-Combine-Blinding-Factors to obtain values to compute this association.
355
-
356
391
# Generic HDK instantiations
357
392
358
393
## Using elliptic curves
@@ -370,12 +405,12 @@ Instantiations of HDK using elliptic curves require the following cryptographic
370
405
- hash_to_field(msg, count): Outputs `count` EC Elements based on the result of cryptographically hashing `msg` (see [RFC9380], Section 5.2).
371
406
372
407
~~~
373
-
def BL-Generate-Blinding-Key-Pair():
408
+
def D-Generate-Blinding-Key-Pair():
374
409
sk = EC-Random()
375
410
pk = EC-Scalar-Base-Mult(sk)
376
-
return (pk, sk)
411
+
return (sk, pk)
377
412
378
-
def BL-Derive-Blinding-Factor(msg, ctx):
413
+
def BL-Derive-Blind-Key(ikm, ctx):
379
414
bf = hash_to_field(msg, count) with the parameters:
0 commit comments