DECO
Presentation: https://www.youtube.com/watch?v=cTBqiwAx5jA
Last updated
Presentation: https://www.youtube.com/watch?v=cTBqiwAx5jA
Last updated
Thanks to TLS, users can access their private data securely with guarantees of end-to-end confidentiality and integrity. However, in the traditional TLS model, it is impossible to prove this data to a third party without relying on trust assumptions. In other words, a user’s private data remains trapped at its origin, with no cryptographically verifiable way to share or prove it externally.
DECO (DECentralized Oracle) is a protocol proposed by researchers at Cornell in 2019 that addresses this problem. It enables privacy-preserving and selective disclosure of data transmitted over TLS, allowing users to prove facts about their data to third parties without revealing the underlying content.
Moreover, DECO is the first oracle protocol to support both TLS 1.2 and TLS 1.3, making it compatible with modern web security standards without requiring any modifications to the server. Prior to DECO, such functionality required either modifying the server or relying on Trusted Execution Environments (TEEs).
Elliptic Curve Diffie-Hellman (ECDH) is a key exchange protocol built on elliptic curve cryptography (ECC). It enables two parties to safely derive a shared secret key over an insecure channel using only public keys.
This is an elliptic-curve variant of the classic Diffie-Hellman Key Exchange (DHKE) protocol.
Let be a generator point on the elliptic curve:
Private key generation: Alice and Bob independently sample secret keys .
Public key computation:
Alice:
Bob:
Key exchange:
Alice sends to Bob.
Bob sends to Alice.
Shared secret key computation:
Alice computes
Bob computes
Thus, both parties derive the same shared key without revealing their private inputs.
MAC-then-Encrypt is the authenticated encryption approach used in TLS 1.2 and earlier. It ensures both confidentiality and integrity by:
Computing a message authentication code (MAC) with the key and the message :
Encrypting the message and MAC with the key :
To decrypt and verify :
Decrypt the ciphertext:
Verify the MAC:
HMAC is a type of Message Authentication Code (MAC) that uses a hash function to ensure both integrity and authentication of data.
The core idea is to combine a cryptographic hash function with a secret key to generate an authentication code (MAC) for a message. This allows the recipient to verify that the data has not been tampered with and that it was sent by a trusted sender.
HMAC is computed as follows:
: outer padding (0x5c)
: inner padding (0x36)
AES-CBC-HMAC is a scheme that combines AES encryption in CBC (Cipher Block Chaining) mode with HMAC-based authentication to ensure both confidentiality and integrity of the message. It follows the MAC-then-Encrypt paradigm.
Generate HMAC:
Encrypt the message and MAC using AES in CBC mode:
is the Initialization Vector, which is sent along with the ciphertext .
Decrypt and split the message:
Verify the MAC:
TODO(chokobole): Add AES-GCM
The TLS handshake is the process by which a client and a server establish a secure connection. It typically involves the following steps:
Cipher suite negotiation: The client and server agree on which cryptographic algorithms (cipher suite) to use.
Session key generation: The client and server derive symmetric keys:
: symmetric encryption key
: symmetric authentication key
These keys are used in the following Record Protocol for data transmission.
DECO supports ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) as the key exchange method.
The TLS Record Protocol operates in the following steps:
Data fragmentation: The sender splits application data into fixed-size plaintext records . The last block is padded if necessary.
Optional compression: The data may optionally be compressed before encryption.
Authenticated encryption: Each record is encrypted and authenticated using one of the following modes:
TLS ≤ 1.2: MAC-then-Encrypt (e.g., AES-CBC-HMAC)
Decryption and integrity check (receiver side): The receiver decrypts the record and verifies integrity by recomputing the MAC.
Optional decompression and reassembly: If compression was applied, the data is decompressed and multiple records are combined to reconstruct the original application data.
DECO supports both CBC-HMAC and GCM mode for AES-based encryption.
Let’s assume the above JSON message was received from a bank server over TLS. Our goal is to prove in zero-knowledge (ZK) that the account with account_id = 2
has a balance greater than or equal to 1000, without revealing any information about the other accounts.
For simplicity, we assume that the TLS session uses AES-CBC-HMAC (as in TLS 1.2), though this can be extended to AES-GCM as well.
TODO(chokobole): Add how DECO is instantiated with AES-GCM
The most straightforward idea is to construct a circuit like the one below and generate a ZK proof. (We omit AES-CBC's IV for clarity.)
Here, we use the notation from the circuit overview.
denotes applying the jq query to message
This naive approach has a critical security flaw: The client already knows the MAC key .
This means the client can forge a valid MAC for a tampered message. For example, even if the real balance is only 500, the client could create a fake message like:
and generate a valid MAC on it—making it appear as though the server authenticated this falsified message.
Thus, performing MAC verification entirely inside the ZK circuit fails to prevent forgery when the client knows the MAC key.
The limitation of the naive approach lies in the fact that, under the standard TLS model, the client learns the MAC key before receiving the server’s response .
Because the client directly knows the MAC key, it can forge a message and still generate a valid ZK proof, introducing a serious vulnerability.
To resolve this, DECO introduces a Three-Party Handshake involving:
: TLS client and ZK prover
: Verifier
: TLS server
The MAC key is split between and , so that cannot compute it alone.
first commits to the received TLS message.
Only then does reveal their MAC key share, preventing the prover from tampering with the message (At this moment, and know the full MAC key ).
TODO(chokobole): Add details on how the MAC key is derived from the shared secrets and .
In Method 1, the prover knows the full MAC key , allowing them to compute HMAC and all related operations locally.
However, from Method 2 onward, the MAC key is only additively shared between and , meaning:
cannot reconstruct the full key.
This introduces a performance challenge: Naively computing HMAC via 2PC is expensive, as HMAC internally invokes the hash function twice, each requiring complex boolean circuits with a high gate count.
Now in order to send a query, the prover and the verifier compute the MAC together as follows:
To address the performance bottleneck in Method 2, Method 3 applies an optimization strategy that leverages the structural properties of HMAC and the internal workings of SHA-256.
The goal is to minimize the scope of 2PC computations by offloading as much of the work as possible to local computation.
where:
is the compression function of the hash
is the initial vector.
Using this structure, HMAC can be split and optimized as follows:
Initial compression via 2PC:
Compute inner hash locally:
As is already known, the prover can compute the inner hash locally using the full message .
Compute outer hash via 2PC only:
where is defined as:
By computing the most expensive part of the computation (inner hash) locally, this optimization significantly reduces the cost of 2PC.
As in Method 1, verifying the entire AES-CBC-HMAC process inside a ZK circuit introduces significant computational overhead. To address this, we can apply a circuit-level optimization that leverages the CBC structure and MAC-then-Encrypt semantics.
Assume that the message consists of 1024 AES blocks, and the MAC consists of 3 fixed-size AES blocks:
After CBC encryption, it transforms into:
If we naively construct the circuit, we would need to perform 1027 AES encryptions inside the circuit:
Using the MAC-then-Encrypt structure, we can only verify the MAC portion of the CBC-encrypted message in the circuit. The HMAC itself can be checked outside the circuit:
Then the verifier checks the HMAC externally:
This is secure under the assumption that HMAC is collision-resistant.
If the -th block (where ) contains sensitive data, we can selectively include it in the circuit:
Where:
We can further reduce the circuit by applying the HMAC optimization described in Method 3:
Then, outside the circuit:
Compute
Verify
Verify
However, there's still a critical issue: How do we know that actually corresponds to the field we intend to prove?
For example, if we're trying to prove the balance of account_id = 2
, there's nothing in the above circuit that guarantees isn't actually from account 1 or 3.
Thus, we need an additional mechanism to ensure:
Context Integrity — the value is taken from the correct location
To address this, the prover constructs a sanitized version of the TLS response message , denoted , where sensitive data fields are removed.
For example, suppose the original message looks like this:
The actual values that were removed are committed separately as a vector of scalars:
The verifier proceeds as follows:
Each represents a redacted numeric value from the response, and the remaining static content is encoded as a list of fixed string tokens , representing the prefix/suffix structure of the original JSON:
Using this setup, the verifier checks the following conditions:
is a syntactically valid JSON.
The following circuit holds:
: commitment of
The commitment scheme used must support homomorphism under string concatenation.
TODO(chokobole): Add details on commitment schemes that support this homomorphic property.
If a malicious prover tampers with the response structure, the verification fails due to a mismatch in the number of commitments or string layout:
❌ Missing fields
❌ Sensitive data not redacted
: the expected index of the scalar vector .
TODO(chokobole): The paper and Chainlink blog do not provide detailed implementation of how is constructed.
DECO enables verifiable web data disclosure, a capability that traditional TLS protocols do not support. It overcomes the inherent limitation of web data being "private-by-design" and trapped at the origin, using zero-knowledge proofs (ZK).
Its core contributions are as follows:
Through a Three-Party Handshake architecture, DECO securely splits the TLS session key (especially the MAC key) between the prover and verifier , preventing the prover from forging TLS responses.
It is designed to verify both TLS message integrity and application-level data predicates inside a ZK circuit, enabling selective and private disclosure.
The context integrity problem for DECO is solved through grammar-aware parsing and enabling position binding proofs in ZK—for example, proving a specific value comes from a structured key-value JSON field without revealing the entire context.
Server authentication: The server presents a digital certificate (usually ) to prove its identity. Client authentication is optional (e.g., in non-mutual TLS setups).
TLS ≥ 1.3: AEAD modes (e.g., AES-, )
is the query: .accounts[] | select(.account_id == 2) | .balance
HMAC must be computed via a Two-Party MPC (2PC) protocol. In order to send a query, the prover and the verifier compute the MAC together as follows(We use the notation defined in ) :
SHA-256 follows the construction, processing messages in blocks. It computes hashes in the following recursive manner:
This method is based on the and aims to resolve a key limitation identified in Method 4—namely, the inability to verify that a block truly corresponds to the intended field.
In the above example, corresponds to the balance for account_id = 2
, solving the ambiguity issue from .
DECO leverages the structure of SHA-256, the MAC-then-Encrypt construction, and parsing-aware validation techniques to minimize 2-Party Computation (2PC) overhead and optimize ZK proof efficiency.
Written by from