BIP: ? Layer: Applications Title: Standard Encryption Envelope (Password-Protected) Author: Keyser Söze <keys.soze@proton.me> Status: Draft Type: Standards Track Created: 2025-09-05 Licence: BSD-2-Clause Requires: ?
|
encrypted-wallet, which encapsulates a wallet payload (as defined in BIP-XXXX: Standard Wallet Payload) inside a COSE_Encrypt0 structure, using a password-derived key via Argon2id.
The envelope authenticates protected headers and allows future extensibility.
This BIP is licensed under the BSD 2-clause licence.
The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in RFC2119 as updated by RFC8174 when, and only when, they appear in all capitals.
Users require a secure, interoperable method of encrypting wallet backups.
By standardising the envelope separately from the payload, multiple cryptographic approaches can evolve without changing the base schema.
This BIP mandates the use of BIP-XXXX (Standard Wallet Payload) as the embedded plaintext format.
- Payload vs. Container: The deliberate separation of the data payload from the security container ensures that the core wallet data format defined in BIP XXX remains simple and interoperable, while allowing implementers to use various security mechanisms as defined in companion BIPs.
- BIP-XXXX: Every
encrypted-walletmust contain a validwallet-payloadas defined in BIP-XXXX. - COSE / RFC-9052: Provides envelope standard for encryption.
- Argon2id / RFC-9106: Secure password-based key derivation.
- Payload Creation: Creator constructs the Wallet Payload CBOR map with integer keys as per BIP-XXX.
- Deterministic Encoding: Payload is rendered into canonical CBOR.
- Encryption: Encryptor derives CEK via Argon2id, wraps payload in COSE_Encrypt0.
- Transmission / Storage: Encrypted result is saved or transferred.
- Restoration: Consumer reads
kdf-params, derives CEK, decrypts COSE_Encrypt0, verifies consistency, parses deterministic CBOR Wallet Payload.
COSE_Encrypt0 structures. All CBOR data, including the plaintext payload and any data used in the AAD, MUST be encoded using the canonical deterministic profile specified in RFC 8949, §4.2.1.
This map defines the encrypted container for the wallet.
It specifies key derivation parameters and the encrypted payload, which MUST be a COSE_Encrypt0 structure containing the wallet map.
| Integer Key | String Key | Type | Description | Required |
|---|---|---|---|---|
| 0 | version | uint | The version of the this envelope. The first stable version is 1. | Yes |
| 1 | kdf-params | map | Parameters for Argon2id key derivation. See KDF Params Map. | Yes |
| 2 | ciphertext | bstr | The encrypted wallet payload, encoded as a CBOR `bstr` containing a COSE_Encrypt0 structure. | Yes |
| 3.. | - | any | A reserved extension range. | No |
- The wallet map is always embedded inside the COSE_Encrypt0 ciphertext, never referenced externally.
| Integer Key | String Key | Type | Description | Required |
|---|---|---|---|---|
| 1 | kdf_type | uint | MUST be `1` (indicating Argon2id). | Yes |
| 2 | salt | bstr (min 16 bytes) | Unique salt value for key derivation. ≥16 bytes, random, from a CSPRNG, unique per encryption operation and MUST NOT repeat | Yes |
| 3 | time | uint | Time cost parameter (iterations). MUST be ≥ 1 (SHOULD be ≥ 3). | Yes |
| 4 | memory | uint | Memory in KiB, RECOMMENDED ≥ 65,536 KiB (desktop), ≥ 32,758 KiB (mobile), ≥ 8,192 KiB (constrained) | Yes |
| 5 | parallelism | uint | Parallelism degree. MUST ≥ 1, RECOMMENDED ≥ 2 | Yes |
| 6 | key_length | uint | If present, MUST equal `32`. Derived key length in bytes. | No |
| 7 | version | uint | Argon2d version MUST be 0x13 (RFC9106) | No |
| 8.. | - | any | A reserved extension range. | No |
- KDF Parameters: The
kdf-paramsmap MUST contain all parameters required to perform the key derivation.kdf_type(uint): MUST be 1 (Argon2id).salt(bstr): MUST be at least 16 bytes. Salt bytes MUST be produced by a CSPRNG and MUST be unique per-encryption operation.time(uint): Argon2 time cost (iterations). MUST be >= 1. RECOMMENDED default values: 3 for interactive devices.memory(uint, KiB): Memory cost in KiB. RECOMMENDED default values:- desktop: 65536 (64 MiB)
- mobile: 32768 (32 MiB)
- constrained: 8192 (8 MiB)
- The
key_lengthfield, if present, MUST be32to match the key size of AES-256-GCM. If absent, a length of 32 bytes is assumed. - The
versionArgon2d version field, if present, MUST be0x13
- Authentication of KDF Parameters: To prevent parameter substitution attacks, the complete
kdf-paramsmap MUST be included in the AAD. Specifically:- The complete
kdf-paramsmap MUST be authenticated via inclusion in the COSEexternal_aad(see COSE Structure and Authentication). This ensures that any modification of Argon2 parameters (e.g. salt, iteration count) is detected by AEAD authentication.
- The complete
- Argon2id Invocation:
- Argon2id parameters SHOULD be chosen conservatively to resist GPU/ASIC attacks. Recommended minimums are specified in the KDF Params Map table.
- The parameters for Argon2id (
salt,time,memory, etc.) MUST be fully specified in thekdf-paramsmap within theencrypted-walletenvelope.- Time cost parameter
time(iterations) MUST be ≥ 1 but SHOULD be ≥ 3. - For resource-constrained devices the time cost MAY be set to the minimum requirement of
time >= 1to ensure a usable and responsive experience. While this setting meets the minimum security threshold, it is strongly RECOMMENDED to use a value oftime >= 3wherever possible to increase resistance against brute-force attacks.
- Time cost parameter
- Protected Header: The protected header MUST be a CBOR map containing the following key/value pairs:
1 (alg):3 (A256GCM). This specifies AES-256-GCM as the encryption algorithm.5 (iv): The 96-bit (12-byte) nonce MUST be random bits from a CSPRNG and MUST be unique per encryption. Re-encrypting the same payload requires a freshiv. It is placed in the protected header to prevent modification, which is critical for the security of AEAD ciphers.
- External AAD: To prevent manipulation of unencrypted metadata, the
external_aadfor the COSE AEAD operation MUST be constructed. This AAD is the canonical CBOR encoding of a map containing:1: The registered CBOR tag for the payload.2: The completekdf-paramsmap.
- AEAD Input: Per RFC 9052, the data authenticated by the AEAD algorithm is the
Enc_structure, which is a CBOR array constructed as:[ context : "Encrypt0", protected : bstr, external_aad: bstr ]. This process cryptographically binds the key derivation parameters, Wallet Payload CBOR tag and protected headers to the ciphertext, ensuring that any tampering with these components will cause decryption to fail.
; Encryption envelope
encrypted-wallet = {
0 => 1..255, ; Envelope version
1 => kdf-params, ; Argon2id parameters (CBOR map)
2 => bstr, ; COSE_Encrypt0 as CBOR-encoded bstr
? 3.. => any, ; reserved extension range
}
kdf-params = {
1 => 1, ; kdf_type: 1 = argon2id
2 => bstr .size 16.., ; salt (min 16 bytes), random from CSPRNG
3 => uint, ; time (iterations) >= 1 (RECOMMEND >= 3))
4 => uint, ; memory (KiB) (>= 8192)
5 => uint, ; parallelism (>=1)
? 6 => uint, ; output key length (bytes), if absent assume 32
? 7 => uint ; Argon2d version MUST be 0x13 (19 decimal) per RFC9106
? 8.. => any, ; reserved extension range
}
While this specification mandates strong, standardised password-based key derivation, implementers SHOULD recognise that the security of the entire wallet payload ultimately depends on the entropy of the user-chosen password. For long-term archival, a weak or moderately strong password may be vulnerable to future advances in computational power that could enable offline brute-force attacks.
Implementers SHOULD therefore:
- Actively warn users about the risks of choosing a weak password.
- Provide clear guidance on creating high-entropy passphrases.
- Consider offering more advanced, non-password-based security options where feasible, such as hardware-key-based encryption, for users requiring maximum long-term security. See next section Expanding the Security Model
- Asymmetric Key Exchange: A source wallet could encrypt the payload using a public key provided by the destination wallet (or a key derived via a Diffie-Hellman exchange). This would create a backup that can only be decrypted by the intended recipient, completely removing the reliance on a shared password.
- Ephemeral Passwords: For direct transfers, two wallets could negotiate a high-entropy, single-use password that is never stored or seen by the user. This would provide strong security for the transfer without the long-term risks of a user-chosen password.
- Implementations MUST use the canonical deterministic encoding specified in RFC 8949 §4.2.1 (shortest integer encoding, sorted map keys by byte-wise representation, no indefinite-length items).
- Implementations MUST reject duplicate map keys (any range).
- Text strings MUST be UTF-8 NFC, no indefinite-length items anywhere.
- Floats MUST NOT be used and MUST be rejected.
- CBOR Tag (registered with IANA) MUST prefix the payload in tagged form.
- CBOR indefinite length strings and arrays MUST NOT be used.
- CBOR floats MUST NOT be used.
- On-the-wire maps MUST use integer keys.
- The
encrypted-envelopeMUST contain exactly one top-levelwallet-payloadobject.
- An implementation MUST verify that the encrypted envelope and its KDF parameters conform to all requirements specified in the Encryption Container section, including the KDF type (Argon2id), minimum costs, key length, and AAD construction. Implementations MUST reject any envelope that does not satisfy these constraints.
- The
kdf_typeMUST be 1 (Argon2id). - The
saltMUST be at least 16 bytes. - The
timeMUST be >= 1. - The
memorycost in KiB MUST be >=8192.
WORK IN PROGRESS(This script, once completed, will reproduce the hex blocks above exactly, given fixed inputs.)
- RFC 8949: Concise Binary Object Representation (CBOR)
- RFC 8610: Concise Data Definition Language (CDDL)
- RFC 9052: CBOR Object Signing and Encryption (COSE)
- RFC 9106: Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications
- IANA CBOR Tags Registry
- RFC 2119: Key words for use in RFCs to Indicate Requirement Levels
- RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words