ECDH Shared Key Exchange
The payoff node for the whole X-series dance
- public_key
- private_key
- shared_key
This is the node the pack's whole ECDH section has been building toward. XPrivateKeyFormat mints your private key, XPublicKeyFormat derives what you're allowed to share, and XExchange takes your private key plus the other side's public key and computes the shared secret you both can agree on - without ever transmitting it. Two people each feed in their own private key and the other's public key, and they both arrive at the same bytes. That's the Diffie-Hellman trick, and in the ComfyUI ARG Toolkit it's a single node. I verified the exchange path against the shipped code with the cryptography library and it produces exactly the shared key you'd expect.
The inputs:
- key_source -
Fresh Key(default) generates a new private key for the exchange;From Private Bytesuses theprivate_keyinput instead. For the shared secret to be stable and match your partner's, you usually wantFrom Private Byteswith a fixed, persisted key - otherwise every run is a one-time key. - key_type -
x25519orx448. Both sides must agree on this; x25519 is the sane default. - public_key - a
BYTESLIKEinput, and the tooltip is the critical detail: it's assumed to be in Raw formatting. Not PEM. The code literally doesfrom_public_bytes()on it, which requires the 32 raw bytes. If you feed it the PEM string fromXPublicKeyFormatwith default settings, you'll get a parse error. When you set upXPublicKeyFormat, choose encodingRawfor the bytes you hand to this node. - private_key - optional
BYTESLIKE, only used whenkey_sourceisFrom Private Bytes. It must be the same key type and raw byte length.
Output is one shared_key in BYTESLIKE - the raw shared secret. And this is where the second half of the story starts: that shared secret is not something you hand to AES. You need to stretch it through a KDF first, which is exactly what the pack's X963KDF_Derive node (or HKDF, also in the pack) is for. So the canonical workflow is XExchange → X963KDF_Derive → symmetric encryption. Wire the shared_key into the KDF's message input and derive a proper 32-byte key.
Two practical notes. First, everything here is the pack's custom BYTESLIKE wire type, so you can't just paste bytes into the boxes - you need a bytes-producing source node, or ByteslikeEncode set to Raw Bytes for testing literals. Second, an ECDH exchange is only as secure as the public key you trust: if an attacker swaps the public key in the middle, you'll compute a shared secret with them. For a real ARG or a demo this is fine; for actual secrets, that's what authenticated key exchange is for, and this pack doesn't do that.
Install is the pack standard: ComfyUI Manager → search "ComfyUI ARG Toolkit" → install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/AzelusLightvale/ComfyUI-ARG-Toolkit
# restart ComfyUI
The pack is one-author and GPLv3, with a README that honestly frames it as an amateur project whose tests only cover common cases. The underlying crypto is the cryptography library's x25519/x448 implementation - solid - but as with the rest of the modern-crypto section, verify before you trust, and remember the "assumed Raw" public key trap. If the shared keys don't match on both ends, the usual culprits are mismatched key types or a public key in the wrong format.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| key_source | BOOLEAN | true | The source of the private key to be used to create the shared key. |
| key_type | COMBO | x25519 | 2 options: x25519, x448 |
| public_key | BYTESLIKE | The public key (assumed in Raw formatting) to derive the shared key from. | |
| private_keyopt | BYTESLIKE | Only applicable if key_source is 'From Private Bytes'. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| shared_key | BYTESLIKE | — |