Skip to content
62 changes: 49 additions & 13 deletions bip-0085.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -360,31 +360,57 @@ OUTPUT
* DERIVED ENTROPY=f7cfe56f63dca2490f65fcbf9ee63dcd85d18f751b6b5e1c1b8733af6459c904a75e82b4a22efff9b9e69de2144b293aa8714319a054b6cb55826a8e51425209
* DERIVED PWD=_s`{TW89)i4`

===RSA===
===GPG Keys===
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely need test vectors and expected outputs for all applications and sub applications. I can also add it to the reference implementation but won't be able to get to that right away. PRs welcome. https://github.com/akarve/bipsea

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to work up some test vectors and a reference implementation once there is some agreement on a general direction :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a pretty simple app protocol in the ref. implementation now: https://github.com/akarve/bipsea/blob/main/src/bipsea/apps/README.md

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have actually got a working implementation of the draft spec (as per the last edit) here: https://github.com/3rdIteration/bipsea


Application number: 828365'

The derivation path format is: <code>m/83696968'/828365'/{key_bits}'/{key_index}'</code>
The derivation path format is: <code>m/83696968'/828365'/{key_type}'/{key_bits}'/{key_index}'</code>
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the GPG derivation path from the previously-specified RSA format (which did not include {key_type}) will change the derived material for existing paths and break interoperability with any current implementations/vectors. If backward compatibility is a goal, consider keeping the legacy RSA path intact and allocating new application numbers for ECC (or otherwise defining a legacy/compat mode) rather than inserting a new path level under the same application number.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a major issue. given that this BIP is widely implemented we have to preserve backward compatibility. we either need to extend and not break the existing paths (including what was sub_key) or we can do this in a clean GPG application.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was my original suggestion, basically just add additional application numbers for ECC (Or perhaps a separate application for ECC and child derivation as per this current draft), but folk seemed to want to go with a 3.0 change that wasn't backwards compatible earlier in the discussion thread.


The RSA key generator should use BIP85-DRNG as the input RNG function.
The key_type values are defined as follows:

===RSA GPG===
{|
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this can be one big table and will read better; there's already a common join key and both are small

!OpenPGP Key Type
!key_type value
|-
| RSA
| 0'
|-
| ECC(Curve25519)
| 1'
|-
Comment on lines +365 to +378
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The derivation path format already hardens the key_type component ("{key_type}'"), but the table also defines key_type values with a trailing apostrophe (e.g., "0'", "1'"). This is ambiguous and can lead to double-hardening / inconsistent interpretation across implementations. Define key_type as a plain integer (0..4) and state that the path component is always hardened, or remove the apostrophe from the path placeholder.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot code review[agent] Can you add a note for the ECC key_types that mentions which key_bits lengths are valid

| ECC(secp256k1)
| 2'
|-
| ECC(NIST)
| 3'
|-
| ECC(Brainpool)
| 4'
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec introduces ECC key types but does not define how {key_bits} selects a specific curve/algorithm for each key_type (e.g., which NIST curve corresponds to which key_bits, and similarly for Brainpool). For fixed-size curves like Curve25519 and secp256k1, it’s also unclear what {key_bits} is expected to be (and whether other values are invalid). Please add explicit, deterministic mappings/constraints so independent implementations derive identical keys for the same path.

Copilot uses AI. Check for mistakes.
|-
|}

The RSA key generator should use BIP85-DRNG as the input RNG function. Likewise, any ECC key types over 256 bits should use BIP85-DRNG.
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The guidance on when to use BIP85-DRNG for ECC ("over 256 bits") doesn’t align with the earlier definition of BIP85-DRNG being needed when more than 64 bytes of random input are required. Consider specifying DRNG usage based on the keygen’s required randomness/bytes (or explicitly justify why >256-bit ECC needs DRNG), otherwise implementers may diverge on whether to use DRNG for common curves like P-384.

Suggested change
The RSA key generator should use BIP85-DRNG as the input RNG function. Likewise, any ECC key types over 256 bits should use BIP85-DRNG.
The RSA key generator should use BIP85-DRNG as the input RNG function. Likewise, any ECC key types whose key generation requires more than 64 bytes of random input should use BIP85-DRNG.

Copilot uses AI. Check for mistakes.

Keys allocated for RSA-GPG purposes use the following scheme:
====Primary Keys and Subkeys====

- Main key <code>m/83696968'/828365'/{key_bits}'/{key_index}'</code>
- Sub keys: <code>m/83696968'/828365'/{key_bits}'/{key_index}'/{sub_key}'</code>
In OpenPGP, a key consists of a primary key used for certification and one or more subkeys for encryption, signing, and authentication. This structure separates long-term identity (the primary key) from operational keys (subkeys), allowing subkeys to expire or be revoked independently without affecting the primary key identity.

- key_index is the parent key for CERTIFY capability
- sub_key <code>0'</code> is used as the ENCRYPTION key
- sub_key <code>1'</code> is used as the AUTHENTICATION key
- sub_key <code>2'</code> is usually used as SIGNATURE key
Keys allocated for GPG purposes use the following scheme:

Note on timestamps:
* Primary key: <code>m/83696968'/828365'/{key_type}'/{key_bits}'/{key_index}'</code>
* Sub keys: <code>m/83696968'/828365'/{key_type}'/{key_bits}'/{key_index}'/{sub_key}'</code>
** key_index is the parent key for CERTIFY capability
** sub_key <code>0'</code> is used as the ENCRYPTION key
** sub_key <code>1'</code> is used as the AUTHENTICATION key
** sub_key <code>2'</code> is usually used as SIGNATURE key

All subkeys SHOULD use the same key_type as the primary key. Mixed key types across primary and subkeys are out of scope for this specification. Additional subkeys may be added following the same role pattern, incrementing the sub_key index.
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Curve25519, OpenPGP typically uses different algorithms for different capabilities (e.g., Ed25519 for certify/sign/auth vs X25519/Curve25519 ECDH for encryption). The current text says all subkeys SHOULD use the same key_type, but doesn’t specify the required per-capability algorithm mapping within that key_type. Please clarify the exact OpenPGP public-key algorithm/curve used for primary vs encryption/auth/sign subkeys under key_type=Curve25519 to avoid incompatible key material generation.

Suggested change
All subkeys SHOULD use the same key_type as the primary key. Mixed key types across primary and subkeys are out of scope for this specification. Additional subkeys may be added following the same role pattern, incrementing the sub_key index.
All subkeys SHOULD use the same key_type (i.e. the same underlying curve family) as the primary key. Mixed key types across primary and subkeys are out of scope for this specification. For <code>key_type = Curve25519</code>, implementations MUST generate OpenPGP keys as follows: the primary CERTIFY key and any SIGNATURE or AUTHENTICATION subkeys MUST use Ed25519 (OpenPGP EdDSA with curve Ed25519), while ENCRYPTION subkeys MUST use X25519/Curve25519 ECDH (OpenPGP ECDH with curve Curve25519). Additional subkeys may be added following the same role pattern, incrementing the sub_key index.

Copilot uses AI. Check for mistakes.

<b>Note on timestamps:</b>

The resulting RSA key can be used to create a GPG key where the creation date MUST be fixed to unix Epoch timestamp 1231006505 (the Bitcoin genesis block time <code>'2009-01-03 18:05:05'</code> UTC) because the key fingerprint is affected by the creation date (Epoch timestamp 0 was not chosen because of legacy behavior in GNUPG implementations for older keys). Additionally, when importing sub-keys under a key in GNUPG, the system time must be frozen to the same timestamp before importing (e.g. by use of <code>faketime</code>).
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section now covers multiple GPG key types, but the timestamp note still refers specifically to "The resulting RSA key". Either generalize the statement to apply to all OpenPGP keys derived here (including ECC), or explicitly scope the timestamp requirement to RSA-only if ECC behavior differs.

Copilot uses AI. Check for mistakes.

Note on GPG key capabilities on smartcard/hardware devices:
<b>Note on GPG key capabilities on smartcard/hardware devices:</b>

GPG capable smart-cards SHOULD be loaded as follows: The encryption slot SHOULD be loaded with the ENCRYPTION capable key; the authentication slot SHOULD be loaded with the AUTHENTICATION capable key. The signature capable slot SHOULD be loaded with the SIGNATURE capable key.

Expand Down Expand Up @@ -443,6 +469,16 @@ BIP32, BIP39

==Changelog==

===2.0.0===
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changelog entries below include dates (e.g., "1.3.0 (2024-10-22)"), but the new "2.0.0" entry has no date. Add a date (or follow whatever versioning/date convention the document uses) to keep the changelog consistent.

Suggested change
===2.0.0===
===2.0.0 (2024-11-01)===

Copilot uses AI. Check for mistakes.

====Added====

* ECC GPG key types for OpenPGP: Curve25519 (key_type 1'), secp256k1 (key_type 2'), NIST (key_type 3'), Brainpool (key_type 4')

====Changed====

* GPG key section restructured to use a single application number (828365') with <code>key_type</code> as a path level component, replacing separate per-type application numbers
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 2.0.0 changelog entry says the GPG section now uses a single application number with key_type, "replacing separate per-type application numbers", which doesn’t match the earlier changelog/history in this document (it previously introduced an RSA application at 828365'). Also, this conflicts with the PR description’s stated approach of using different application IDs per key type. Please reconcile the changelog text (and/or the spec approach) so the intended compatibility strategy is clear.

Copilot uses AI. Check for mistakes.

===1.3.0 (2024-10-22)===

====Added====
Expand Down
Loading