Suggestions of standards added to openpgp/Gnupg/LibrePgp
Hakun_the_eril via Gnupg-users <[email protected]> Tue, 31 Mar 2026 15:36:14 +0200
| Newsgroups | gmane.comp.encryption.gpg.user |
|---|---|
| Message-ID | <CACnSDUtfHY2SRa2XqEXBZD+k+WAG29otEATJVSOKjJQRXahPyQ@mail.gmail.com> |
Hi! As the Baochip-x1 has the hardware to do a lot of cryptographic functions like active zeroisation, Ed25519 signed boot, Glitch sensors, security mesh, PV sensor, ECC-protected RAM,Algorithm-agnostic engine etc I think that these could be added to standards. . I suggest: # Authenticated Ephemeral ECDH Session Protocol and Cipher Profile Encoding ## Abstract This document specifies a **binary authenticated ephemeral ECDH handshake** (InitMessage and ResponseMessage), **HKDF-SHA256** key derivation with fixed UTF-8 labels, and a **compact binary encoding** for **named cipher profiles** (ECDHE curve, ordered AEAD layers, Shamir threshold metadata). The handshake provides **forward secrecy** for session keys: long-term keys authenticate ephemeral keys; ECDH uses ephemeral key pairs only. The format is intended for submission to the OpenPGP working group as an extension compatible in spirit with [RFC 9580](https://www.rfc-editor.org/rfc/rfc9580) algorithm and notation registries, without reusing OpenPGP packet syntax for the handshake octets themselves. --- ## 1. Introduction OpenPGP ([RFC 9580](https://www.rfc-editor.org/rfc/rfc9580)) specifies message formats, public-key encryption, signatures, and AEAD payloads. It does **not** define a standalone **ephemeral-ephemeral ECDH** session establishment with **mutual** authentication of ephemeral keys via **long-term** Brainpool signing keys. This document fills that gap for toolchains that require **forward secrecy** at the session layer while binding identity to existing long-term OpenPGP-compatible key material (fingerprint binding). **Cipher profiles** name a policy: **ECDHE curve**, **ordered list of symmetric AEAD layers** (encrypt order; decrypt reverse), and **Shamir (k, n)** metadata for long-term key handling. Profiles serialise to a **deterministic octet string** for storage and negotiation. This specification is written for **interoperability** among independent implementations that adopt the same octet layouts and labels. --- ## 2. Terminology The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHALL NOT**, **SHOULD**, **SHOULD NOT**, **RECOMMENDED**, **NOT RECOMMENDED**, **MAY**, and **OPTIONAL** are to be interpreted as described in BCP 14 ([RFC 2119](https://www.rfc-editor.org/rfc/rfc2119)) ([RFC 8174]( https://www.rfc-editor.org/rfc/rfc8174)) when, and only when, they appear in all capitals, as shown here. **Initiator:** The party that sends `InitMessage`. **Responder:** The party that sends `ResponseMessage`. **Long-term fingerprint:** SHA-256 digest (32 octets) over the uncompressed SEC1 encoding of the long-term **verifying** public key, represented on the wire as 64 ASCII hexadecimal digits. --- ## 3. Conventions - All multi-octet integers are **big-endian** unless stated otherwise. - **Curve public keys** are **uncompressed SEC1** points ([SEC 1]( https://www.secg.org/sec1-v2.pdf)). - **ECDSA** signatures on the wire are **DER**-encoded ([RFC 5480]( https://www.rfc-editor.org/rfc/rfc5480)-style ECDSA-Sig-Value). - **HKDF** follows [RFC 5869](https://www.rfc-editor.org/rfc/rfc5869) with **HMAC-SHA256**. --- ## 4. Protocol and encodings ### 4.1 Protocol version Implementations MUST support protocol version byte `0x01` for both `InitMessage` and `ResponseMessage`. Parsers MUST reject other version values unless a later specification defines them. ### 4.2 Curve identifiers (`curve_id`) | `curve_id` | Curve | SEC1 uncompressed length (octets) | |------------|--------|-----------------------------------| | `0x01` | brainpoolP256r1 [RFC 5639](https://www.rfc-editor.org/rfc/rfc5639) | 65 | | `0x02` | brainpoolP384r1 | 97 | | `0x03` | brainpoolP512r1 | 129 | Senders MUST set `curve_id` to one of these values. Receivers MUST verify that the ephemeral public key length field matches this table for the received `curve_id`. ### 4.3 InitMessage (normative layout) Serialisation order (concatenation): | Field | Size | Description | |-------|------|-------------| | `version` | 1 | MUST be `0x01`. | | `curve_id` | 1 | As in Section 4.2. | | `epk_len` | 1 | Length of initiator ephemeral public key; MUST equal SEC1 length for `curve_id`. | | `epk` | `epk_len` | Uncompressed SEC1 initiator ephemeral public key. | | `fp_len` | 1 | Length of fingerprint field; MUST be `64` when fingerprint is hex-encoded SHA-256. | | `fingerprint` | `fp_len` | 64 ASCII hex digits (`0-9`, `a-f` preferred; parsers MUST accept `A-F`). | | `sig_len` | 2 | Big-endian; length of DER signature. | | `signature` | `sig_len` | ECDSA-SHA256 over initiator **preimage** (Section 4.5). | The total serialised size MUST NOT exceed **512** octets. ### 4.4 ResponseMessage (normative layout) Fields 1–8 are identical in structure to InitMessage for `version`, `curve_id`, responder `epk_len`, responder `epk`, `fp_len`, responder long-term `fingerprint`, and `sig_len` / `signature` for the **responder** preimage. Additional fields: | Field | Size | Description | |-------|------|-------------| | (same as Init through responder signature) | | | | `iepk_len` | 1 | MUST equal initiator ephemeral length for `curve_id`. | | `initiator_epk_copy` | `iepk_len` | **Copy** of initiator ephemeral public key from InitMessage. | | `sig_len_r` | 2 | Big-endian; length of responder DER signature. | | `signature_r` | `sig_len_r` | ECDSA-SHA256 over responder **preimage** (Section 4.5). | The initiator MUST compare `initiator_epk_copy` to its own sent ephemeral key using a **constant-time** equality check. ### 4.5 Signature preimages (ECDSA-SHA256) Hash input is **raw concatenation** (no length prefixes except where lengths are fixed by `curve_id`): - **Initiator preimage:** `version || curve_id || initiator_ephemeral_sec1_uncompressed` - **Responder preimage:** `version || curve_id || responder_ephemeral_sec1 || initiator_ephemeral_sec1` The hash function is **SHA-256**; ECDSA is Brainpool with the long-term signing key associated with the fingerprint. ### 4.6 ECDH shared secret and HKDF 1. **ECDH** is performed on the agreed curve; the shared secret is the **x**-coordinate of the resulting point, packed to a fixed width per curve; **interoperating peers MUST use identical packing** (see Appendix A for conformance vectors). 2. **HKDF-Extract** salt: lexicographic ordering of the two ephemeral public key byte strings: if `epk_initiator <= epk_responder` (lexicographic octet compare), salt = `epk_initiator || epk_responder`; else salt = `epk_responder || epk_initiator`. If the salt is empty in a helper, implementations MUST use 32 zero octets as HMAC key per [RFC 5869]( https://www.rfc-editor.org/rfc/rfc5869) empty-salt handling where applicable. 3. **HKDF-Expand** with **SHA-256**; output length **32** octets per derived key unless a profile specifies otherwise. **HKDF `info` labels (UTF-8, exact octets):** | Label (exact) | Derived key role | |---------------|------------------| | `openpgp-ephemeral-session/payload-i2r/v1` | Payload AEAD, initiator to responder | | `openpgp-ephemeral-session/payload-r2i/v1` | Payload AEAD, responder to initiator | | `openpgp-ephemeral-session/gdss-mask/v1` | Optional GDSS masking stream | | `openpgp-ephemeral-session/gdss-sync/v1` | Optional GDSS sync | | `openpgp-ephemeral-session/gdss-timing/v1` | Optional GDSS timing | | `openpgp-ephemeral-session/mac/v1` | Optional HMAC key | Implementations MUST NOT reuse labels for distinct key roles. Changing any label octet breaks interoperability. ### 4.7 Cipher profile compact encoding A **cipher profile** serialises as: | Field | Size | Description | |-------|------|-------------| | `name_len` | 1 | Length of `name`; MUST be ≤ 64. | | `name` | `name_len` | UTF-8 profile identifier (e.g. `standard`, `conservative-shamir`). | | `desc_len` | 1 | Length of description; MUST be ≤ 128. | | `description` | `desc_len` | UTF-8 human-readable text. | | `curve_id` | 1 | Same as Section 4.2 (ECDHE curve for session). | | `layer_count` | 1 | Number of AEAD layers; MUST be 1–4. | | `layer_id` × `layer_count` | each 1 | Symmetric layer type (see below). | | `shamir_k` | 1 | Shamir threshold **k** (1–255). | | `shamir_n` | 1 | Shamir total **n** (1–255); MUST satisfy `k ≤ n`. | **Layer type IDs (`layer_id`):** | `layer_id` | Algorithm | |------------|-----------| | `0x01` | AES-256-GCM | | `0x02` | ChaCha20-Poly1305 [RFC 8439]( https://www.rfc-editor.org/rfc/rfc8439) | | `0x03` | Twofish-256 (EtM construction as in implementation) | | `0x04` | Serpent-256 (EtM construction as in implementation) | **Encryption order:** layers are applied **in array order** (first layer = innermost plaintext); **decryption** applies **reverse** order. **Authentication** MUST be verified at each layer; failure MUST abort decryption. --- ## 5. Security Considerations **Threat model:** The handshake aims for **confidentiality** and **integrity** of session keys against passive and active network attackers, under the assumption that long-term signing keys remain uncompromised during the handshake. **Forward secrecy** holds for past sessions if ephemeral private keys are destroyed after use. **Limitations:** - This document does **not** specify transport binding to TLS or OpenPGP; bindings are application-defined. - **Side-channel** resistance of ECDH and ECDSA depends on the cryptographic library and hardware. - **Downgrade** of `curve_id` or profile MUST be prevented by policy at a higher layer if multiple options are offered. - **GDSS** optional keys are product-specific; implementations MAY omit derivation of those labels. **Guidance:** Implementations SHOULD use constant-time comparison for `initiator_epk_copy`. Implementations MUST zeroise ephemeral private keys after ECDH. --- ## 6. IANA Considerations This document requests IANA to create or extend registries under the **OpenPGP** umbrella (exact registry names subject to IESG and IANA review): | Registry | Request | |----------|---------| | **Ephemeral ECDH extension `curve_id`** (or sub-registry of Experimental / Private Use) | Reserve `0x01`–`0x03` as in Section 4.2; future values via IETF Review or Specification Required. | | **Cipher profile `layer_id`** | Reserve `0x01`–`0x04` as in Section 4.7. | | **HKDF info labels** | Register the six UTF-8 strings in Section 4.6 as **well-known** `info` labels for this protocol (reference: this document). | | **Notation names** (optional OpenPGP binding) | Register ` [email protected]` (example) for embedding profile fingerprints in signature notations if WG desires OpenPGP message binding. | Until IANA assigns numbers, private experimentation MAY use implementation-defined prefixes with **no** guarantee of global uniqueness. --- ## 7. References ### 7.1 Normative References | ID | Reference | |----|-----------| | RFC2119 | Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. | | RFC5639 | Lochter, M. and Merkle, J., "Elliptic Curve Cryptography (ECC) Brainpool Standard Curves and Curve Generation", RFC 5639, March 2010. | | RFC5869 | Krawczyk, H. and Eronen, P., "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)", RFC 5869, May 2010. | | RFC8174 | Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, May 2017. | | RFC8439 | Nir, Y. and Langley, A., "ChaCha20 and Poly1305 for IETF Protocols", RFC 8439, June 2018. | | SEC1 | SECG, "Elliptic Curve Cryptography", SEC 1, Version 2.0. | ### 7.2 Informative References | ID | Reference | |----|-----------| | RFC9580 | Wussler, S., et al., "OpenPGP", RFC 9580, July 2024. | --- ## Appendix A. Interoperability test anchors Implementations MUST demonstrate interoperability using **fixed test vectors** (to be published in a future revision of this document or a companion **Implementation Techniques** note). Until those vectors are published, conformance tests SHOULD cover: - Handshake serialisation round-trip for `InitMessage` and `ResponseMessage` per Sections 4.3–4.4. - HKDF label distinctness (no two roles share the same `info` string). - Brainpool ECDH and ECDSA with [RFC 5639]( https://www.rfc-editor.org/rfc/rfc5639) test vectors where applicable. - Side-channel review of comparison and scalar paths (implementation-dependent). # Shamir Secret Sharing for OpenPGP-Adjacent Key Material: Share Format and Field Arithmetic ## Abstract This document specifies **Shamir’s Secret Sharing** over **GF(256)** for secrets of **16 to 64 octets**, including **share index** and **share value** layout, **K-of-N** metadata, a **textual armour** format (**OPENPGP SHAMIR SHARE**), and **HKDF** labelling for post-recovery key derivation. It is intended for interoperability with hardware tokens and host tools that split or recover OpenPGP-relevant signing material. The format complements [RFC 9580](https://www.rfc-editor.org/rfc/rfc9580) OpenPGP messages by defining a **container** for shares that MAY be transported inside experimental packets or as standalone files. --- ## 1. Introduction Shamir’s method (1979) splits a secret into **N** shares such that any **K** shares suffice for reconstruction. This document **normatively** defines the **field**, **byte-wise sharing** construction, **wire formats**, and **armour** using **GF(256)** arithmetic compatible with the **AES** field (see `vsss_rs::Gf256` or equivalent **bit-identical** implementation). OpenPGP ([RFC 9580](https://www.rfc-editor.org/rfc/rfc9580)) does not define threshold splits of long-term private key material. This specification provides a **concrete** format implementors can adopt pending WG adoption of OpenPGP-native packet types. --- ## 2. Terminology The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHALL NOT**, **SHOULD**, **SHOULD NOT**, **RECOMMENDED**, **NOT RECOMMENDED**, **MAY**, and **OPTIONAL** are to be interpreted as described in BCP 14 ([RFC 2119](https://www.rfc-editor.org/rfc/rfc2119)) ([RFC 8174]( https://www.rfc-editor.org/rfc/rfc8174)) when, and only when, they appear in all capitals. **K:** Threshold number of shares required to reconstruct. **N:** Total number of shares generated. **Share index:** Non-zero octet in `1..=255` identifying the polynomial evaluation point. --- ## 3. Conventions - **Field:** GF(256) with the **same** reduction polynomial as the AES block field; implementations MUST produce **bit-identical** results to a **reference** `vsss_rs::Gf256` (or equivalent) definition across all split and recover operations. - **Secret length:** `L` octets where **16 ≤ L ≤ 64**. All shares for one split MUST use the same `L`. - **Threshold:** Integers **K** and **N** MUST satisfy **1 ≤ K ≤ N ≤ 255**. --- ## 4. Mathematical construction (normative) For each byte position **j** in `0..L` independently: 1. Let **s[j]** be the secret byte at position **j** (treated as an element of GF(256)). 2. Construct a polynomial **P** of degree **K − 1** with coefficients in GF(256): the constant term is **s[j]**; coefficients **1..K−1** MUST be sampled uniformly at random using a cryptographically secure RNG. 3. For share index **i** (1 ≤ **i** ≤ **N**), the share byte at position **j** is **P(i)** evaluated in GF(256) with **i** mapped to the field element **i**. **Recovery:** Given **K** distinct shares with indices **i_1…i_K** and matching value vectors, the secret byte **s[j]** is **P(0)** computed via Lagrange interpolation in GF(256). Implementations MUST reject duplicate share indices during recovery. Implementations MUST NOT infer **K** solely from the number of shares without explicit parameter matching. --- ## 5. Binary share payload (normative minimum) A **share value** in memory or binary transport is: | Field | Size (octets) | Description | |-------|----------------|-------------| | `index` | 1 | Share index **i**, MUST be in `1..=255`. | | `value` | `L` | **16 ≤ L ≤ 64**; polynomial evaluation bytes aligned with Section 4. | The tuple `(index, value)` together with known **K**, **N**, and secret length **L** are REQUIRED for recovery. --- ## 6. OPENPGP SHAMIR SHARE armour (normative text format) Armour is **ASCII** and MUST use the following structure: 1. Line: `-----BEGIN OPENPGP SHAMIR SHARE-----` 2. Line: `Version: 1` 3. Line: `Profile: ` + UTF-8 profile name (policy label). 4. Line: `Threshold: ` + decimal **K**. 5. Line: `Total: ` + decimal **N**. 6. Line: `Index: ` + decimal share index **i**. 7. Line: `Fingerprint: ` + hexadecimal fingerprint of associated long-term key (implementation-defined encoding). 8. Line: `Created: ` + RFC 3339 timestamp. 9. Empty line. 10. Base64 ([RFC 4648](https://www.rfc-editor.org/rfc/rfc4648)) body encoding **only** the **`value`** octets (not the index). 11. Line: `-----END OPENPGP SHAMIR SHARE-----` Parsers MUST verify Base64 and length constraints. The **index** in the header MUST match the share; implementations MUST treat mismatch as fatal. **Note:** The index appears in the header; the **value** is Base64-only. Implementations MAY alternatively encode `index || value` in Base64 in a future version—**Version: 1** as specified ties index to header fields. --- ## 7. HKDF after recovery When expanding recovered material into operational keys, implementations **MUST** use [RFC 5869](https://www.rfc-editor.org/rfc/rfc5869) with **SHA-512** and `info` exactly: `openpgp-shamir/vault-recovery/v1` (UTF-8 octets) This label MUST NOT be reused for unrelated derivations. --- ## 8. Mapping to OpenPGP (informative operations) Implementations MAY: - Wrap armour in a **MIME** part or **file** attachment. - Place a **notation** on a signature: e.g. name `[email protected]` with a SHA-256 digest of the armour body (policy-specific). - Encapsulate binary payloads in **Private/Experimental** OpenPGP packets ([RFC 9580](https://www.rfc-editor.org/rfc/rfc9580) private packet conventions) once IANA assigns packet tags (Section 10). This document **does not** require OpenPGP implementations to parse shares inside literal data packets; it defines the **share format** independent of OpenPGP framing. --- ## 9. Security Considerations **Threat model:** Shares protect against single-point loss of the full secret only if **K** shares are required and **custody** is separated. An attacker with **K** shares reconstructs the secret. **Limitations:** - **GF(256)** Shamir is **not** post-quantum for the share reconstruction math; long-term risk is the same class as symmetric key recovery. - **RNG** quality for polynomial coefficients MUST be CSPRNG-backed. - **Armour** is **not encrypted**; implementations SHOULD encrypt shares at rest (e.g. OpenPGP-encrypted file) when distributed. - **Fingerprint** binding does not prevent substitution unless the fingerprint is verified out-of-band. **Guidance:** Implementations MUST zeroise recovered secrets after use. Implementations SHOULD use **constant-time** comparison where comparing share metadata to secrets. --- ## 10. IANA Considerations This document requests: | Item | Action | |------|--------| | **OpenPGP Packet Tag** | Assign an **Experimental** or **Private** packet tag for **OPENPGP-SHAMIR-SHARE** binary blob (optional encapsulation of Sections 5–6), or reserve from private-use range per [RFC 9580]( https://www.rfc-editor.org/rfc/rfc9580) IANA procedures. | | **Notation name** | Register `[email protected]` (example) for signature notations pointing to external share custody. | | **HKDF info registry** | Register `openpgp-shamir/vault-recovery/v1` as a well-known `info` label for Shamir recovery KDF. | | **Media type** (optional) | `application/vnd.openpgp.shamir-share` for armour files. | Exact numbers are **TBD** pending IESG and IANA review. --- ## 11. References ### 11.1 Normative References | ID | Reference | |----|-----------| | RFC2119 | Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119. | | RFC4648 | Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648. | | RFC5869 | Krawczyk, H. and Eronen, P., "HKDF", RFC 5869. | | RFC8174 | Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174. | | SHAMIR79 | Shamir, A., "How to share a secret", Communications of the ACM, 1979. | ### 11.2 Informative References | ID | Reference | |----|-----------| | RFC9580 | "OpenPGP", RFC 9580. | --- ## Appendix A. Interoperability test anchors Implementations MUST validate split/recover using **published test vectors** (to be added in a future revision). Conformance tests SHOULD include: - Round-trip split and recover for fixed K, N, L. - Rejection of duplicate `index` values. - Boundary checks for L in {16, 64}. - **Fuzz** and timing-hardening (implementation-dependent). --- ## Document history | Version | Notes | |---------|--------| | 00 | Initial proposal: GF(256) Shamir, binary share payload, OPENPGP SHAMIR SHARE armour Version 1. | The baochips specs can be found here: https://www.baochip.com/ Or here: https://github.com/Supermagnum/Baochip-1x-firmware _______________________________________________ Gnupg-users mailing list [email protected] https://lists.gnupg.org/mailman/listinfo/gnupg-users