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
{{ message }}
Repository navigation
Commit 6ad5ac4
Browse filesBrowse the repository at this point in the historyBrowse files
Announce the LMS tree cache in HSS component keys with an HSS encoding version of 1 rather than inferring it from trailing stream data, which misread multi-level HSS private keys written before the cache existed - version 0 encodings now parse their component keys cache-free, relates to github #2365.
Copy file name to clipboardExpand all lines: docs/formats/lms-private-key.md
+37-3Lines changed: 37 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,7 +41,10 @@ first signature. Its properties:
41
41
master secret (a key written by 1.85 or earlier, which then rebuilds the tree on first use),
42
42
and a release predating the cache reads a 1.86+ encoding successfully because its decoder
43
43
returns at the end of the master secret and never examines the trailing bytes. This is why
44
-
the cache is appended rather than announced by a new version number.
44
+
the cache is appended rather than announced by a new version number. Note this
45
+
trailing-data inference only works for a key that owns its whole encoding: for the component
46
+
keys inside an HSS private key, which share one stream, the presence of the cache field is
47
+
dictated by the HSS encoding's version instead — see "HSS private keys" below.
45
48
-**It carries at most the top six levels** of the tree: nodes `1 .. min(2`<sup>`h+1`</sup>`, 64) - 1`.
46
49
For `h = 5` that is the entire tree (63 nodes); for `h = 10` and above it is the top 63
47
50
nodes, from which the remaining path nodes are recomputed on demand.
@@ -68,8 +71,39 @@ PrivateKeyInfo ::= SEQUENCE {
68
71
}
69
72
```
70
73
71
-
An HSS private key with `L > 1` uses the same OID and prefix convention but a different body
72
-
(the HSS key chain state); it is not covered here.
74
+
An HSS private key uses the same OID and prefix convention but carries the HSS structure
75
+
described in the next section as its body. (A PKCS#8 encoding produced from a standalone
76
+
`LMSPrivateKeyParameters`, as in the example below, carries the bare LMS key after the
77
+
`L = 1` prefix instead; the decoder accepts either.)
78
+
79
+
## HSS private keys
80
+
81
+
An HSS private key (`HSSPrivateKeyParameters.getEncoded()`) is the chain state for the RFC 8554
82
+
sec. 6 hierarchy: `L` component LMS private keys, one per level, plus the `L - 1` chaining
83
+
signatures by which each tree certifies the public key of the tree below it.
84
+
85
+
| offset | size | field | contents |
86
+
|---|---|---|---|
87
+
| 0 | 4 |`version`|`1`. The version 0 form written by earlier releases is read but no longer generated — see below. Anything else is rejected. |
88
+
| 4 | 4 |`L`| Number of levels. |
89
+
| 8 | 8 |`index`| Next signature index across the whole hierarchy (an unsigned 64-bit value). |
90
+
| 16 | 8 |`indexLimit`| Exclusive upper bound on `index`; the key is exhausted when they meet. |
91
+
| 24 | 1 |`limited`|`01` when the key is a shard produced by `extractKeyShard()`. |
92
+
| 25 | — |`keys`| The `L` component LMS private keys, concatenated, each in the LMS format above. |
93
+
| — | — |`signatures`| The `L - 1` chaining signatures, concatenated, each an RFC 8554 sec. 5.4 LMS signature: `sig[i]` is tree `i`'s signature over tree `i + 1`'s public key. |
94
+
95
+
The component keys share the stream with whatever follows them, so the standalone key's
96
+
"trailing data means a cache" inference is meaningless here — for every component but the last,
97
+
more data is *always* available. The HSS `version` field carries the distinction instead:
98
+
99
+
-**version 1** (written by current code): every component key carries the tree-cache field —
100
+
the `u32` node count (possibly 0) and its nodes — exactly as `LMSPrivateKeyParameters.getEncoded()`
101
+
emits it.
102
+
-**version 0** (written by every release before the tree cache): every component key ends at
103
+
its master secret and carries no cache field. Read-compatible, never generated.
104
+
105
+
A release predating the tree cache rejects a version 1 encoding cleanly at its version check
106
+
("unknown version for hss private key") rather than misparsing cache bytes as key material.
0 commit comments