Umbra Privacy LogoUmbra Privacy
Key Architecture

X25519 Keypair

X25519 keypair for deriving shared secrets via Diffie-Hellman key exchange, enabling encrypted communication and confidential data

Overview

The X25519 Keypair is a Curve25519 elliptic curve keypair used for Diffie-Hellman (DH) key exchange. The primary purpose of this keypair is to derive shared secrets with other parties-without ever transmitting the secret itself over any channel.

The X25519 DH key exchange works as follows:

  1. You have your X25519 private key (kept secret)
  2. The other party has their X25519 public key (publicly known)
  3. You perform the X25519 scalar multiplication: SharedSecret=X25519(YourPrivate,TheirPublic)\text{SharedSecret} = \text{X25519}(\text{YourPrivate}, \text{TheirPublic})
  4. The other party can compute the same shared secret using their private key and your public key
  5. Both parties now share a secret that no eavesdropper can derive

This shared secret can then be used for multiple different purposes-encrypting data, keying symmetric ciphers, deriving further keys, or any cryptographic operation requiring a shared symmetric key.

Unlike the other three keys in Umbra's architecture, this keypair is not included in the User Commitment Tree-it operates independently to manage visibility of confidential account balances and enable secure communication channels.


Technical Specification

PropertyValue
AlgorithmX25519 (Curve25519 ECDH)
CurveCurve25519 (Montgomery form)
Private Key Size256 bits (32 bytes)
Public Key Size256 bits (32 bytes)
Shared Secret Size256 bits (32 bytes)
Security Level~128-bit security
On-Chain RegistrationPublic key registered for incoming encryptions

Mathematical Foundation

X25519 is based on elliptic curve Diffie-Hellman over Curve25519. Given:

  • Your private key aa (a 256-bit scalar)
  • Their public key BB (a point on the curve, encoded as 32 bytes)
  • The curve's base point GG

The shared secret is computed as:

SharedSecret=aB=a(bG)=b(aG)=bA\text{SharedSecret} = a \cdot B = a \cdot (b \cdot G) = b \cdot (a \cdot G) = b \cdot A

Where AA is your public key and bb is their private key. Both parties arrive at the same point on the curve, which is then encoded as the 32-byte shared secret.


Shared Secret Derivation

The core operation of the X25519 keypair is deriving a shared secret with another party's public key:

SharedSecret=X25519(YourPrivateKey,TheirPublicKey)\text{SharedSecret} = \text{X25519}(\text{YourPrivateKey}, \text{TheirPublicKey})

Properties of the Shared Secret

PropertyGuarantee
Mutual DerivationBoth parties compute the identical secret
Eavesdropper ResistanceCannot be derived from observing public keys alone
Forward SecrecyIf using ephemeral keys, past secrets remain secure even if long-term keys are compromised
UniformityOutput is indistinguishable from random (after hashing)
DeterminismSame inputs always produce the same shared secret

Key Derivation from Shared Secret

The raw X25519 output should typically be passed through a key derivation function (KDF) before use:

DerivedKey=KDF(SharedSecret,Context)\text{DerivedKey} = \text{KDF}(\text{SharedSecret}, \text{Context})

This ensures proper domain separation and extracts uniform randomness from the shared secret.


Use Cases

The X25519 keypair enables multiple cryptographic operations through shared secret derivation. Each use case involves performing a DH key exchange with a different party's public key.


Use Case 1: Encrypting Data for the MPC

The primary use case in Umbra is encrypting data for the Arcium MPC network. This enables confidential computation where the MPC can process encrypted data without any single node learning the plaintext.

How It Works

  1. Obtain the MXE Public Key: The Umbra program deployed on Solana mainnet has a well-known MXE (MPC Execution Environment) public key. This is an X25519 public key that represents the MPC network's decryption capability.

  2. Derive the Shared Secret: Using your X25519 private key and the MXE public key, derive a shared secret:

SharedSecretMPC=X25519(YourPrivateKey,MXEPublicKey)\text{SharedSecret}_{\text{MPC}} = \text{X25519}(\text{YourPrivateKey}, \text{MXEPublicKey})
  1. Key the Rescue Cipher: The shared secret is used to select a specific cipher instance from the family of all possible Rescue Ciphers. The Rescue Cipher is specifically designed to be MPC-friendly-its algebraic structure makes it efficient for multi-party computation.
RescueCipherInstance=RescueCipher(SharedSecretMPC)\text{RescueCipherInstance} = \text{RescueCipher}(\text{SharedSecret}_{\text{MPC}})
  1. Encrypt Your Data: Use the keyed Rescue Cipher instance to encrypt your confidential data:
Ciphertext=RescueCipherInstance.Encrypt(Plaintext,Nonce)\text{Ciphertext} = \text{RescueCipherInstance}.\text{Encrypt}(\text{Plaintext}, \text{Nonce})
  1. Submit to MPC: The ciphertext can now be submitted to the MPC network. The MPC nodes can collectively decrypt and process the data without any single node learning the plaintext.

Why Rescue Cipher?

The Rescue Cipher is chosen specifically for MPC compatibility:

PropertyBenefit for MPC
Algebraic StructureOperations are native to the finite field, reducing MPC overhead
Low Multiplicative DepthFewer rounds of MPC communication required
ZK-CompatibleCan be verified inside zero-knowledge circuits
Nonce-BasedSame plaintext + different nonce = different ciphertext (semantic security)
Field-NativeNo bit-level operations that are expensive in MPC

For complete technical details on the Rescue Cipher, see Rescue Cipher.

Encrypted Token Account Balances

A critical application of MPC encryption is Encrypted Token Account (ETA) balances:

  1. Your ETA balance is encrypted using a Rescue Cipher keyed by the shared secret with the MXE
  2. The encrypted balance is stored on-chain (visible to everyone as ciphertext)
  3. Only you (with your X25519 private key) and the MPC network can decrypt it
  4. The MPC can perform operations on your encrypted balance (transfers, etc.) without learning the actual value

Bidirectional MPC Communication

The shared secret enables communication in both directions:

DirectionProcess
You to MPCEncrypt with shared secret, MPC decrypts collectively
MPC to YouMPC encrypts with shared secret, you decrypt with your private key

This is essential for:

  • Submitting confidential inputs to MPC computations
  • Receiving confidential computation outputs from the MPC
  • Querying your encrypted balances

Use Case 2: Encrypting Data for Another User

Beyond MPC communication, the X25519 keypair enables peer-to-peer encrypted communication between users. Any two users with registered X25519 public keys can establish a shared secret and communicate confidentially.

How It Works

  1. Obtain the Recipient's Public Key: The recipient has registered their X25519 public key on-chain. You fetch this public key.

  2. Derive a Shared Secret: Using your X25519 private key and the recipient's public key:

SharedSecretUser=X25519(YourPrivateKey,RecipientPublicKey)\text{SharedSecret}_{\text{User}} = \text{X25519}(\text{YourPrivateKey}, \text{RecipientPublicKey})
  1. The Recipient Can Derive the Same Secret: Using their private key and your public key:
SharedSecretUser=X25519(RecipientPrivateKey,YourPublicKey)\text{SharedSecret}_{\text{User}} = \text{X25519}(\text{RecipientPrivateKey}, \text{YourPublicKey})

Both computations produce the identical shared secret.

  1. Encrypt Your Message: Use the shared secret to key a symmetric cipher and encrypt your message:
Ciphertext=EncryptSharedSecret(Message,Nonce)\text{Ciphertext} = \text{Encrypt}_{\text{SharedSecret}}(\text{Message}, \text{Nonce})
  1. Transmit the Ciphertext: Send the ciphertext to the recipient (on-chain, off-chain, or via any channel).

  2. Recipient Decrypts: The recipient derives the same shared secret and decrypts:

Message=DecryptSharedSecret(Ciphertext,Nonce)\text{Message} = \text{Decrypt}_{\text{SharedSecret}}(\text{Ciphertext}, \text{Nonce})

Sender encrypts:

Recipient decrypts:

Applications

ApplicationDescription
Private MemosAttach encrypted messages to transactions that only the recipient can read
Encrypted MetadataShare confidential transaction details with specific parties
Secure CoordinationCoordinate multi-party transactions without revealing details publicly
Selective DisclosureShare specific information with auditors or counterparties

Security Considerations for User-to-User Encryption

ConsiderationRecommendation
Nonce ReuseNever reuse a nonce with the same shared secret
Key RotationConsider ephemeral keys for forward secrecy
AuthenticationThe shared secret only provides confidentiality, not authentication-verify the public key belongs to the intended recipient
Public Key AuthenticityEnsure you're using the correct public key (on-chain registration helps)

Use Case 3: Deriving Multiple Keys from One Exchange

A single X25519 key exchange can derive multiple independent keys for different purposes using a key derivation function (KDF):

Key1=KDF(SharedSecret,"encryption")\text{Key}_1 = \text{KDF}(\text{SharedSecret}, \text{"encryption"}) Key2=KDF(SharedSecret,"authentication")\text{Key}_2 = \text{KDF}(\text{SharedSecret}, \text{"authentication"}) Key3=KDF(SharedSecret,"key-encryption")\text{Key}_3 = \text{KDF}(\text{SharedSecret}, \text{"key-encryption"})

This enables:

  • Authenticated encryption: Separate keys for encryption and MAC
  • Key hierarchies: Derive session keys from a master shared secret
  • Domain separation: Different keys for different protocol contexts

On-Chain Registration

Before others can encrypt data for you, your X25519 public key must be registered on-chain:

What Registration Enables

CapabilityDescription
Incoming ETA TransfersSenders can look up your public key and encrypt transfer amounts for you
MPC ResultsThe MPC network can encrypt computation outputs for you
User-to-User EncryptionOther users can establish shared secrets with you
Protocol DiscoveryApplications know which key to use for your encryptions

Registration Process

  1. Generate your X25519 keypair (deterministically from seed or randomly)
  2. Submit a registration transaction with your X25519 public key
  3. The public key is stored in your on-chain account record
  4. Others can now query your public key and encrypt data for you

Key Generation

The X25519 Keypair can be generated using several approaches:

MethodDescriptionSecurity Model
RandomGenerate from cryptographically secure randomnessInformation-theoretic independence
DeterministicDerive from L1 private key or master seedCryptographic independence
DKGDistributed key generation across multiple partiesThreshold security

Deterministic Derivation

For convenience, the X25519 keypair can be derived from a master seed:

X25519Private=KDF(MasterSeed,"x25519-keypair")\text{X25519Private} = \text{KDF}(\text{MasterSeed}, \text{"x25519-keypair"})

Pros:

  • Single backup (master seed) recovers all keys
  • Simpler key management

Cons:

  • Master seed compromise = X25519 keypair compromise
  • Coupled security model

Independent Random Generation

For maximum security isolation:

Pros:

  • Compromise of other keys doesn't affect X25519 keypair
  • Information-theoretic independence

Cons:

  • Must backup X25519 private key separately
  • More complex key management

Visibility vs. Ownership

Umbra separates visibility (who can see) from ownership (who can control) for Encrypted Token Accounts:

AspectControlled ByKey Type
OwnershipL1 Interaction KeyEd25519
VisibilityX25519 KeypairX25519

This separation enables powerful capabilities:

CapabilityHow It Works
Blind TransfersL1 key can transfer ETA funds even without X25519 key (you just can't see balances)
View-Only AccessShare X25519 key with auditor-they can see balances but not transfer
Threshold VisibilityUse DKG for X25519 so multiple parties must cooperate to decrypt

Security Considerations

Compromise Impact

If your X25519 private key is compromised:

ImpactSeverity
ETA Balance VisibilityAttacker can see all your encrypted balances
Decrypt Messages For YouAttacker can decrypt any data encrypted to your public key
Derive Shared SecretsAttacker can derive shared secrets with any party
Fund TheftNo direct impact-requires L1 key
Mixer UTXO SpendingNo impact-requires Shielded Spending Key

Loss Impact

If you lose your X25519 private key:

ImpactConsequence
Cannot See ETA BalancesYour balances are still there, but you can't decrypt them
Cannot Decrypt MessagesData encrypted to your public key becomes unreadable
Funds Still ControllableL1 key can still transfer ETA funds (blind transfers)
RecoveryIf derived from master seed, recover by re-deriving

Summary

AspectDetails
TypeX25519 Keypair (Curve25519 ECDH)
Primary PurposeDerive shared secrets via Diffie-Hellman key exchange
Use Case 1Encrypt data for MPC using Rescue Cipher
Use Case 2Encrypt data for other users (peer-to-peer)
Use Case 3Derive multiple keys from one exchange
In User Commitment?No
On-Chain RegistrationPublic key must be registered
Compromise ImpactVisibility only (no fund theft)
Loss ImpactCannot decrypt (funds still controllable via L1 Key)