Skip to content

feat: add tx encryption key rotation#2373

Open
juan518munoz wants to merge 1 commit into
nextfrom
jmunoz-tx-encryption-key-rotation
Open

feat: add tx encryption key rotation#2373
juan518munoz wants to merge 1 commit into
nextfrom
jmunoz-tx-encryption-key-rotation

Conversation

@juan518munoz

@juan518munoz juan518munoz commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

Continues the transaction input encryption work from #2342 (part of #2319) by making the shared transaction encryption key rotate perpetually, once per epoch, with no operator action and no validator coordination.

Per-epoch key derivation

The secret configured via --encryption-key.hex / --encryption-key.kms-ciphertext is now a master secret rather than the encryption key itself. Each epoch's X25519 key is derived deterministically from it:

seed(epoch) = blake3("MIDEN_TX_ENCRYPTION_KEY_DERIVATION_V1" || master_secret || epoch_le_u16)

Since every validator holds the same master secret, all validators derive identical keys for every epoch and transition to the new key at each boundary independently. The key provider owns the derivation and is now epoch-aware, including a grace window on decryption so submissions sealed just before a boundary remain decryptable after it.

Changelog

[[entry]]
scope       = "rpc"
impact      = "breaking"
description = "`GetTransactionEncryptionKey` now returns a `TransactionEncryptionKeyResponse` carrying the current key and the key that replaces it at the next epoch boundary, each with its own validator attestations."

[[entry]]
scope       = "validator"
impact      = "breaking"
description = "The shared transaction encryption key now rotates every epoch. The configured secret is a master secret from which per-epoch keys are derived, and each epoch's secret key is archived in the validator database. Validator databases bootstrapped before this change must be re-bootstrapped."

@juan518munoz
juan518munoz marked this pull request as ready for review July 23, 2026 22:05
// Reserved for future attestation evidence beyond the validator signatures, e.g. a TEE quote,
// signature chain, compose hash, app measurement, epoch, or accepted measurement set.
reserved 6 to 9;
reserved 5 to 9;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

FYI we shouldn't reserve for future use.

Protobuf already supports adding new fields in a non-breaking fashion. reserved is used to protect removed fields. i.e. when removing a field in a backwards compatible way, replace it with reserved to prevent someone reusing that same field number, which would break the schema.

@Mirko-von-Leipzig Mirko-von-Leipzig left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I have some questions; without having reviewed things at all - I'm waiting on some internal consensus on how the whole operation might work.

  1. This aligns key rotation with the epoch. The epoch length is dictated by node storage requires. Should we be combining these concepts, or should the key epoch be independent?
  2. Do we need a way to rotate the master key? I feel like this just shuffles the security boundary around a little, while cosmetically rotating the public key. But I'm no security expert; perhaps this is somehow sufficient.

@juan518munoz

Copy link
Copy Markdown
Collaborator Author

This aligns key rotation with the epoch. The epoch length is dictated by node storage requires. Should we be combining these concepts, or should the key epoch be independent?

The concepts can be independent (for example defining the key epoch block_num / KEY_ROTATION_INTERVAL). It's this way only because it was the first idea that came to mind, we can change this if needed.

Do we need a way to rotate the master key? I feel like this just shuffles the security boundary around a little, while cosmetically rotating the public key. But I'm no security expert; perhaps this is somehow sufficient.

We probably need to have a way of rotating the master key, as it's single point of failure (a leak means all epoch keys become derivable). What the current epoch rotation does give is containment for the derived keys used during operation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants