Convert more docs

This commit is contained in:
Hendrik Eeckhaut
2025-05-14 08:40:57 +02:00
parent 7dd42235cc
commit 8232d0da96
50 changed files with 1748 additions and 53 deletions

View File

@@ -42,4 +42,10 @@ If you are using GitHub pages for hosting, this command is a convenient way to b
https://docusaurus.io/docs/sidebar/autogenerated
https://docusaurus.io/docs/sidebar/autogenerated
https://mdxjs.com/playground/
Front matter:
https://docusaurus.io/docs/markdown-features#front-matter
https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-docs#markdown-front-matter

View File

@@ -1,24 +0,0 @@
---
slug: mdx-blog-post
title: MDX Blog Post
authors: [slorber]
tags: [docusaurus]
---
Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/).
:::tip
Use the power of React to create interactive blog posts.
:::
{/* truncate */}
For example, use JSX to create an interactive button:
```js
<button onClick={() => alert('button clicked!')}>Click me!</button>
```
<button onClick={() => alert('button clicked!')}>Click me!</button>

View File

@@ -1,7 +1,7 @@
---
title: TLSNotary Updates
authors: [sinu]
tags: [mpc-tls, proxy]
# tags: [mpc-tls, proxy]
---
# Introduction

284
blog/2024-11-14-devcon.md Normal file
View File

@@ -0,0 +1,284 @@
---
title: TLSNotary Workshop DevCon 2024
authors: [heeckhau]
---
This blog post contains the instructions for the TLSNotary workshop we presented at [DevCon 2024](https://app.devcon.org/schedule/VPMQGM). The workshop aimed to introduce participants to TLSNotary, covering its use in both native Rust and browser environments.
:::warning
Please note that some of the instructions provided here might be outdated, as they were written for the version of TLSNotary available at the time of the workshop. For the latest updates and documentation, refer to the [official TLSNotary repository](https://github.com/tlsnotary).
:::
<!-- truncate -->
## Introduction
This workshop introduces you to TLSNotary, both in native Rust and in the browser.
**Workshop Objectives:**
* Understand the applications of TLSNotary.
* Learn the basics of attesting, proving, and verifying data using TLSNotary.
## Pre-Workshop Setup
To avoid network issues on conference Wi-Fi, please download the following dependencies in advance:
1. Clone repositories, get dependencies and build code
```shell
# Clone Git Repositories:
git clone -b dev https://github.com/tlsnotary/tlsn
git clone https://github.com/tlsnotary/tlsn-plugin-boilerplate
git clone https://github.com/tlsnotary/tlsn-js
# Install websocket proxy
cargo install wstcp
# Build rust code (and download dependencies)
cargo build --manifest-path tlsn/Cargo.toml --release --examples
# Build Javascript code (and download dependencies)
npm install --prefix tlsn-plugin-boilerplate
npm run --prefix tlsn-plugin-boilerplate build
```
Note that this requires the [Rust](https://www.rust-lang.org/tools/install) and [NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) toolchains.
2. [Install the TLSNotary Browser Plugin from the Chrome Web Store](https://chromewebstore.google.com/detail/tlsn-extension/gcfkkledipjbgdbimfpijgbkhajiaaph)
## Getting Started
In the first part of the workshop, well begin with the basics. To keep things simple, well use a local, single-computer setup wherever possible.
### Rust: Interactive Verification without a Trusted Notary
Well start by running the most basic TLSNotary setup.
![Overview Prover Verifier](https://hackmd.io/_uploads/ByCJOjF-Jg.svg)
Well run a local test server that serves the Prover JSON or HTML content. The Prover and Verifier will fetch this data via MPC, allowing the Prover to reveal parts of the JSON to the Verifier, who then verifies it.
We call this setup **Interactive Verification**.
> 🚀 The first examples use Rust. If youre not a Rust dev, dont worry—you dont need to write Rust code yourself. 😇
#### Source Code
The source code is located at `crates/examples/interactive/interactive.rs` in the `tlsn` repository.
The setup has three main parts:
* `main()`: wires everything together.
* `prover(...)`:
* Connects to the Verifier.
* Connects to the TLS Server.
* Performs MPC-TLS handshake.
* Sends a request to the Server and waits for the response.
* Redacts/reveals data and creates a proof for the Verifier.
* `verifier(...)`:
* Verifies MPC-TLS and waits for (redacted) data.
* Verifies disclosed data (hostname, content).
#### Start the Server
```shell
PORT=4000 cargo run --bin tlsn-server-fixture
```
#### Run the Example
To run the interactive example:
```shell
SERVER_PORT=4000 cargo run --release --example interactive
```
Expected log:
```log
Successfully verified https://test-server.io:4000/formats/html
Verified sent data:
GET https://test-server.io:4000/formats/html HTTP/1.1
host: test-server.io
connection: close
secret: 🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈
```
For detailed debug information:
```shell
RUST_LOG=debug,yamux=info,uid_mux=info SERVER_PORT=4000 cargo run --release --example interactive
```
> **Note:** We run in `release` mode because `debug` mode is too slow to complete the TLS session before it times out.
#### Extra Tasks (optional)
- [ ] Experiment with different redactions.
- [ ] Try proving JSON content instead (`/formats/json`).
### Rust: Notarize with a Trusted Notary
Next, well run the TLSNotary protocol with a Notary server blindly verifying the TLS session.
![Overview Notary](https://hackmd.io/_uploads/r1haDsKWkg.svg)
Leave the test server running.
Start the notary server:
```shell
cd crates/notary/server
cargo run -r -- --tls-enabled false
```
The `--tls-enabled false` argument disables TLS between the Prover and the Notary. We use it here to simplify the setup.
The process has three steps:
1. **Notarize** a request and response from the test server and obtain an attestation.
2. **Create a redacted, verifiable presentation** from the attestation.
3. **Verify the presentation.**
The term *presentation* aligns with [W3 Verifiable Credentials](https://www.w3.org/TR/vc-data-model/#dfn-verifiable-presentations).
#### 1. Notarize
Next create a presentation with:
```shell
SERVER_PORT=4000 cargo run --release --example attestation_prove
```
This notarizes a request and `json`-response from the test server and acquires an attestation. The result is written to two files: an attestation and the MPC secrets. In the next step the Prover can use these two files to create different presentations for the Verifier to verify.
#### 2. Create Presentation
```shell
cargo run --release --example attestation_present
```
In `crates/examples/attestation/present.rs`, inspect how certain content is revealed or concealed.
#### 3. Verify
Finally the verifier can verify the presentation:
```shell
cargo run --release --example attestation_verify
```
This will verify the presentation and print the disclosed data to the console.
Note that in a real world scenario, the Prover would send the Presentation to the Verifier, here we just used the filesystem.
#### Extra tasks (optional)
Try the above steps with different types of web content:
- [ ] **HTML**: Append `-- html` to the commands for each of the steps
- [ ] **Authenticated content**: Append `-- authenticated` to the commands for each of the steps. (This will add an authentication token to the request to access 'private' data).
### Browser: notarize with the Browser extension
Good job. Now that you have a better understanding of what is going on under the hood: Let's try TLSNotary in the Browser with our Browser Extension.
Running the TLSNotary protocol in the Browser needs something special. Browser extensions can not open TCP connections, and this is required to connect the Prover to the Server. So to run the Prover in a browser we need a workaround: a websocket proxy.
The easiest way to run a local websocket proxy is to use `wstcp`:
```shell
wstcp --bind-addr 127.0.0.1:55688 api.x.com:443
```
This command allows the browser to setup a TCP connection to `api.x.com` by talking to the websocket at port `55688`.
Next we need to configure the Browser Extension options to use the local notary and websocket proxy.
* Click the **Options** button in the Extension and make following changes
* **Notary** API: Keep the default, this will use PSE's development notary server. Note that you can also use a local notary server, but make sure its version matches the version of the browser extension (i.e. `v0.1.0-alpha.7`)
* **Proxy API**: `ws://localhost:55688`
> You can also use the [proxy server hosted by PSE](https://docs.tlsnotary.org/developers/notary_server.html#websocket-proxy-server). Note that this proxy server only supports a limited list of whitelisted domains. If you want to access other domains, you will need to run your own proxy server.
#### Notarize
Try either the Twitter or Discord plugin and follow the steps in UI. If everything works correctly, you should and up with a valid presentation. Click the **View Proof** button to check the verified presentation.
#### Extra items (optional)
- [ ] Instead of using a plugin, try to manually notarize a page as documented on https://docs.tlsnotary.org/quick_start/browser_extension.html
- [ ] Instead of using the plugin's presentation preview tool, download the presentation (called proof in the UI) and render it with https://explorer.tlsnotary.org instead.
## Notarize in teams
This part is optional but should be fun: team up with your neighbors and distribute roles: Server, Prover, Verifier and Notary. Can you make it work?
Make sure to open the required ports on your firewall.
### Notarize with a Trusted Notary
Distribute the roles and make sure to configure `NOTARY_HOST`, `NOTARY_PORT`,`SERVER_HOST` and `SERVER_PORT` to the correct values. Check `/crates/examples/attestation/prove.rs` for the details.
### Interactive verifier
For the interactive verifier you can use the *interactive verifier* demo from the https://github.com/tlsnotary/tlsn-js repo. The demo is in the `demo/interactive-demo` folder.
One team member starts the Verifier:
```bash
cd interactive-demo/verifier-rs; cargo run --release
```
And another team member runs the Prover. Make sure to configure the correct `VERIFIER_HOST` first:
```bash
cd interactive-demo/prover-rs; cargo run --release
```
- [ ] Make it work
- [ ] Check that the Verifier is not talking to the TLS server
- [ ] Check that the Verifier only sees what the prover wants to disclose.
- [ ] Try to make it break
## Building apps with TLSNotary
👍 Good job! We are progressing nicely and learning a lot.
The next topic is building web applications that use TLSNotary attestations.
First we will test a demonstration webapp that uses the browser extension to request an attestation of the user's Twitter profile.
Next we will build this plugin ourselves.
### Browser extension Connection API
Next topic is exploring a web application that verifies that you have a Twitter account and rewards you with a POAP if you do.
Visit https://demo.tlsnotary.org and walk through the steps.
You can verify what the web app is doing by reading the source code at https://github.com/tlsnotary/tlsn-plugin-demo.
You can find more information on the [Provider API in our documentation](https://docs.tlsnotary.org/extension/provider.html).
> ⚠️ **Note:** This demo allows for proving with any notary (so that you can use local notary to avoid stressing the network). In real world applications, please verify the attestation more carefully to make sure the attestations you receive are trustworthy.
### Browser extension plugins
```shell
git clone https://github.com/tlsnotary/tlsn-plugin-boilerplate
npm i
npm run build
```
After you run the above commands, the dist folder should now contain a `twitter_profile.tlsn.wasm` file. This is a plugin that can be loaded in the Extension.
Before we add the plugin into the extension, remove the existing Twitter plugin to avoid confusion (Hover the plugin and click the red cross in the top right of the extension).
Next click **Add plugin** and select the `twitter_profile.tlsn.wasm` file in the `dist` folder.
Next try the plugin by clicking it in the extension and following the steps in the sidebar.
You can find more information at https://docs.tlsnotary.org/extension/plugins.html
> Note: Because we use Extism to build the TLSNotary Extension plugins, you can also write plugins in Rust. See https://github.com/tlsnotary/tlsn-plugin-boilerplate/tree/main/examples/twitter_profile_rs for an example.
### Play Time
You now have experimented with the basic building blocks. Next step is to build your own applications with TLSNotary.
Think of what Web2 data you'd like to unlock: Private message, identity providers, reputation sources, financial information, ...
Build a custom plugin or develop a complete webapp with TLSNotary.

View File

@@ -1,27 +1,3 @@
yangshun:
name: Yangshun Tay
title: Front End Engineer @ Facebook
url: https://github.com/yangshun
image_url: https://github.com/yangshun.png
page: true
socials:
x: yangshunz
github: yangshun
slorber:
name: Sébastien Lorber
title: Docusaurus maintainer
url: https://sebastienlorber.com
image_url: https://github.com/slorber.png
page:
# customize the url of the author page at /blog/authors/<permalink>
permalink: "/all-sebastien-lorber-articles"
socials:
x: sebastienlorber
linkedin: sebastienlorber
github: slorber
newsletter: https://thisweekinreact.com
sinu:
name: Sinu
title: Tech lead
@@ -31,3 +7,12 @@ sinu:
socials:
x: sinu_eth
github: sinui0
heeckhau:
name: Hendrik Eeckhaut
url: https://github.com/heeckhau
image_url: https://github.com/heeckhau.png
page: true
socials:
x: heeckhau
github: heeckhau

View File

@@ -1,5 +1,5 @@
facebook:
label: Facebook
label: MPC-TLS
permalink: /facebook
description: Facebook tag description

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View File

@@ -0,0 +1,9 @@
# Commitment scheme
<!-- TODO will polish -->
BEFORE the `Notary` "opens his gabled circuit" in Step 17 of [DEAP](deap.md), the `User` commits (e.g. computes a blake3 hash) to the encodings of the plaintext generated by the `Notary` (i.e. the encoded output [v]_B from Step 8 in DEAP).
"Opening the garbled circuit" simply means that the `Notary` reveals and signs the seed of randomness which (among other things) was used to generate the [encoding](encodings.md) of the plaintext.
Having both the signed seed from the `Notary` and also the commitment to the plaintext encoding, the `User` can prove to any third-party Verifier the authenticity of the plaintext.

View File

@@ -0,0 +1,5 @@
# Committed OT
// TODO here we describe our flavor of committed KOS
// This page will be linked to from DEAP

View File

@@ -0,0 +1,5 @@
To ensure malicious security of the Garbled Circuits 2PC, TLSNotary uses the [Dual Execution protocol](https://securecomputation.org/docs/pragmaticmpc.pdf) (see Section 7.6).
DualEX inherently leaks n bits of private input with probability $\frac{1}{2^n}$. This is not a problem during the TLS handshake when the private inputs are symmetric keys or hash pre-images. Leaking n bits does not give the adversary any advantage, since with the same probability the adversary may have guessed those bits while brute-forcing the key or the pre-image.
However, the leakage becomes a problem when encrypting the request or decrypting the response, since leaking even 1 bit of the plaintext may be catastrophic for the User's privacy. To overcome this leakage, we use a variant of DualEx where privacy is guaranteed only for the User.

4
docs/MPC/_ectf.md Normal file
View File

@@ -0,0 +1,4 @@
# ECtF
This protocol enables the User and the Notary to convert their shares of an ECDH secret into shares of the pre-master secret (PMS).

3
docs/MPC/_encodings.md Normal file
View File

@@ -0,0 +1,3 @@
# Encodings
// Explain here how each input/output/intermediate wire in GC can have value either 0 or 1 and a random 128-bit value encodes that wire value

View File

@@ -0,0 +1 @@
# Secure 2-Party Computation

View File

@@ -0,0 +1,3 @@
# Oblivious Transfer
TODO

View File

@@ -0,0 +1,16 @@
# TLS handshake
During the TLS handshake the TLS Client and the TLS Server compute the session keys needed to perform the encryption and decryption of data.
In TLSNotary protocol `User` and `Notary` jointly play the role of the TLS Client. They use MPC to compute the session keys in such a way that neither party ever learns the full keys but each has their share of the keys.
First they compute their shares of the TLS Client's ECDH secret using [this protocol](key_exchange.md). Since an ECDH secret is an EC point, the parties have their shares of that point.
Then they compute their shares of the pre-master secret (PMS) using an MPC protocol described [here](./ectf.md).
Then the parties input their PMS shares as private inputs to the [DEAP](deap.md) protocol (along with some other public data). They perform the following in MPC:
- they derive their shares of the TLS session keys
- they encrypt the Client Finished message (and the `User` sends the CF to the server)
- (the `User` receives the Server Finished message from the server and) they decrypt the SF message and check its authenticity.

15
docs/MPC/commitments.md Normal file
View File

@@ -0,0 +1,15 @@
---
sidebar_position: 6
---
# Commitments
Here we illustrate the commitment scheme used to create authenticated commitments to the plaintext in scenarios where a general-purpose [`Notary`](../intro.md#tls-verification-with-a-general-purpose-notary) is used. (Note that this scheme is not used when the `Prover` proves directly to the `Verifier`)
A naive approach of extending the [`Encryption and Decryption`](../protocol/mpc-tls/encryption.md) steps to also compute a commitment (e.g. BLAKE3 hash) using MPC is too resource-intensive, prompting us to provide a more lightweight commitment scheme.
The high-level idea is that the `Prover` creates a commitment to the active plaintext encoding from the MPC protocol used for [`Encryption and Decryption`](../protocol/mpc-tls/encryption.md).
We also hide the amount of commitments (to preserve `Prover` privacy) by having the `Prover` commit to the Merkle tree of commitments.
![Commitment](../diagrams/encoding_commitment.svg)

139
docs/MPC/deap.md Normal file
View File

@@ -0,0 +1,139 @@
---
sidebar_position: 3
---
# Dual Execution with Asymmetric Privacy
TLSNotary uses the `DEAP` protocol described below to ensure malicious security of the overall protocol.
When using DEAP in TLSNotary, the `User` plays the role of Alice and has full privacy and the `Notary` plays the role of Bob and reveals all of his private inputs after the TLS session with the server is over. The Notary's private input is his TLS session key share.
The parties run the `Setup` and `Execution` steps of `DEAP` but they defer the `Equality Check`.
Since during the `Equality Check` all of the `Notary`'s secrets are revealed to User, it must be deferred until after the TLS session with the server is over, otherwise the User would learn the full TLS session keys and be able to forge the TLS transcript.
## Introduction
Malicious secure 2-party computation with garbled circuits typically comes at the expense of dramatically lower efficiency compared to execution in the semi-honest model. One technique, called Dual Execution [\[MF06\]](https://www.iacr.org/archive/pkc2006/39580468/39580468.pdf) [\[HKE12\]](https://www.cs.umd.edu/~jkatz/papers/SP12.pdf), achieves malicious security with a minimal 2x overhead. However, it comes with the concession that a malicious adversary may learn $k$ bits of the other's input with probability $2^{-k}$.
We present a variant of Dual Execution which provides different trade-offs. Our variant ensures complete privacy _for one party_, by sacrificing privacy entirely for the other. Hence the name, Dual Execution with Asymmetric Privacy (DEAP). During the execution phase of the protocol both parties have private inputs. The party with complete privacy learns the authentic output prior to the final stage of the protocol. In the final stage, prior to the equality check, one party reveals their private input. This allows a series of consistency checks to be performed which guarantees that the equality check can not cause leakage.
Similarly to standard DualEx, our variant ensures output correctness and detects leakage (of the revealing parties input) with probability $1 - 2^{-k}$ where $k$ is the number of bits leaked.
## Preliminary
The protocol takes place between Alice and Bob who want to compute $f(x, y)$ where $x$ and $y$ are Alice and Bob's inputs respectively. The privacy of Alice's input is ensured, while Bob's input will be revealed in the final steps of the protocol.
### Premature Leakage
Firstly, our protocol assumes a small amount of premature leakage of Bob's input is tolerable. By premature, we mean prior to the phase where Bob is expected to reveal his input.
If Alice is malicious, she has the opportunity to prematurely leak $k$ bits of Bob's input with $2^{-k}$ probability of it going undetected.
### Aborts
We assume that it is acceptable for either party to cause the protocol to abort at any time, with the condition that no information of Alice's inputs are leaked from doing so.
### Committed Oblivious Transfer
In the last phase of our protocol Bob must open all oblivious transfers he sent to Alice. To achieve this, we require a very relaxed flavor of committed oblivious transfer. For more detail on these relaxations see section 2 of [Zero-Knowledge Using Garbled Circuits \[JKO13\]](https://eprint.iacr.org/2013/073.pdf).
### Notation
* $x$ and $y$ are Alice and Bob's inputs, respectively.
* $[X]_A$ denotes an encoding of $x$ chosen by Alice.
* $[x]$ and $[y]$ are Alice and Bob's encoded _active_ inputs, respectively, ie $\mathsf{Encode}(x, [X]) = [x]$.
* $\mathsf{com}_x$ denotes a binding commitment to $x$
* $G$ denotes a garbled circuit for computing $f(x, y) = v$, where:
* $\mathsf{Gb}([X], [Y]) = G$
* $\mathsf{Ev}(G, [x], [y]) = [v]$.
* $d$ denotes output decoding information where $\mathsf{De}(d, [v]) = v$
* $\Delta$ denotes the global offset of a garbled circuit where $\forall i: [x]^{1}_i = [x]^{0}_i \oplus \Delta$
* $\mathsf{PRG}$ denotes a secure pseudo-random generator
* $\mathsf{H}$ denotes a secure hash function
## Protocol
The protocol can be thought of as three distinct phases: The setup phase, execution, and equality-check.
### Setup
1. Alice creates a garbled circuit $G_A$ with corresponding input labels $([X]_A, [Y]_A)$, and output label commitment $\mathsf{com}_{[V]_A}$.
2. Bob creates a garbled circuit $G_B$ with corresponding input labels $([X]_B, [Y]_B)$.
3. For committed OT, Bob picks a seed $\rho$ and uses it to generate all random-tape for his OTs with $\mathsf{PRG}(\rho)$. Bob sends $\mathsf{com}_{\rho}$ to Alice.
4. Alice retrieves her active input labels $[x]_B$ from Bob using OT.
5. Bob retrieves his active input labels $[y]_A$ from Alice using OT.
6. Alice sends $G_A$, $[x]_A$, $d_A$ and $\mathsf{com}_{[V]_A}$ to Bob.
7. Bob sends $G_B$ and $[y]_B$ to Alice.
### Execution
Both Alice and Bob can execute this phase of the protocol in parallel as described below:
#### Alice
8. Evaluates $G_B$ using $[x]_B$ and $[y]_B$ to acquire $[v]_B$.
9. Defines $\mathsf{check}_A = [v]_B$.
10. Computes a commitment $\mathsf{Com}(\mathsf{check}_A, r) = \mathsf{com}_{\mathsf{check}_A}$ where $r$ is a key only known to Alice. She sends this commitment to Bob.
11. Waits to receive $[v]_A$ from Bob[^1].
12. Checks that $[v]_A$ is authentic, aborting if not, then decodes $[v]_A$ to $v^A$ using $d_A$.
At this stage, a malicious Bob has learned nothing and Alice has obtained the output $v^A$ which she knows to be authentic.
#### Bob
13. Evaluates $G_A$ using $[x]_A$ and $[y]_A$ to acquire $[v]_A$. He checks $[v]_A$ against the commitment $\mathsf{com}_{[V]_A}$ which Alice sent earlier, aborting if it is invalid.
14. Decodes $[v]_A$ to $v^A$ using $d_A$ which he received earlier. He defines $\mathsf{check}_B = [v^A]_B$ and stores it for the equality check later.
15. Sends $[v]_A$ to Alice[^1].
16. Receives $\mathsf{com}_{\mathsf{check}_A}$ from Alice and stores it for the equality check later.
Bob, even if malicious, has learned nothing except the purported output $v^A$ and is not convinced it is correct. In the next phase Alice will attempt to convince Bob that it is.
Alice, if honest, has learned the correct output $v$ thanks to the authenticity property of garbled circuits. Alice, if malicious, has potentially learned Bob's entire input $y$.
[^1]: This is a significant deviation from standard DualEx protocols such as [\[HKE12\]](https://www.cs.umd.edu/~jkatz/papers/SP12.pdf). Typically the output labels are _not_ returned to the Generator, instead, output authenticity is established during a secure equality check at the end. See the [section below](#malicious-alice) for more detail.
### Equality Check
17. Bob opens his garbled circuit and OT by sending $\Delta_B$, $y$ and $\rho$ to Alice.
18. Alice, can now derive the _purported_ input labels to Bob's garbled circuit $([X]^{\\*}_B, [Y]^{\\*}_B)$.
19. Alice uses $\rho$ to open all of Bob's OTs for $[x]_B$ and verifies that they were performed honestly. Otherwise she aborts.
20. Alice verifies that $G_B$ was garbled honestly by checking $\mathsf{Gb}([X]^{\\*}_B, [Y]^{\\*}_B) == G_B$. Otherwise she aborts.
21. Alice now opens $\mathsf{com}_{\mathsf{check}_A}$ by sending $\mathsf{check}_A$ and $r$ to Bob.
22. Bob verifies $\mathsf{com}_{\mathsf{check}_A}$ then asserts $\mathsf{check}_A == \mathsf{check}_B$, aborting otherwise.
Bob is now convinced that $v^A$ is correct, ie $f(x, y) = v^A$. Bob is also assured that Alice only learned up to k bits of his input prior to revealing, with a probability of $2^{-k}$ of it being undetected.
## Analysis
### Malicious Alice
[On the Leakage of Corrupted Garbled Circuits \[DPB18\]](https://eprint.iacr.org/2018/743.pdf) is recommended reading on this topic.
During the first execution, Alice has some degrees of freedom in how she garbles $G_A$. According to \[DPB18\], when using a modern garbling scheme such as \[ZRE15\], these corruptions can be analyzed as two distinct classes: detectable and undetectable.
Recall that our scheme assumes Bob's input is an ephemeral secret which can be revealed at the end. For this reason, we are entirely unconcerned about the detectable variety. Simply providing Bob with the output labels commitment $\mathsf{com}_{[V]_A}$ is sufficient to detect these types of corruptions. In this context, our primary concern is regarding the _correctness_ of the output of $G_A$.
\[DPB18\] shows that any undetectable corruption made to $G_A$ is constrained to the arbitrary insertion or removal of NOT gates in the circuit, such that $G_A$ computes $f_A$ instead of $f$. Note that any corruption of $d_A$ has an equivalent effect. \[DPB18\] also shows that Alice's ability to exploit this is constrained by the topology of the circuit.
Recall that in the final stage of our protocol Bob checks that the output of $G_A$ matches the output of $G_B$, or more specifically:
$$f_A(x_1, y_1) == f_B(x_2, y_2)$$
For the moment we'll assume Bob garbles honestly and provides the same inputs for both evaluations.
$$f_A(x_1, y) == f(x_2, y)$$
In the scenario where Bob reveals the output of $f_A(x_1, y)$ prior to Alice committing to $x_2$ there is a trivial _adaptive attack_ available to Alice. As an extreme example, assume Alice could choose $f_A$ such that $f_A(x_1, y) = y$. For most practical functions this is not possible to garble without detection, but for the sake of illustration we humor the possibility. In this case she could simply compute $x_2$ where $f(x_2, y) = y$ in order to pass the equality check.
To address this, Alice is forced to choose $f_A$, $x_1$ and $x_2$ prior to Bob revealing the output. In this case it is obvious that any _valid_ combination of $(f_A, x_1, x_2)$ must satisfy all constraints on $y$. Thus, for any non-trivial $f$, choosing a valid combination would be equivalent to guessing $y$ correctly. In which case, any attack would be detected by the equality check with probability $1 - 2^{-k}$ where k is the number of guessed bits of $y$. This result is acceptable within our model as [explained earlier](#premature-leakage).
### Malicious Bob
[Zero-Knowledge Using Garbled Circuits \[JKO13\]](https://eprint.iacr.org/2013/073.pdf) is recommended reading on this topic.
The last stage of our variant is functionally equivalent to the protocol described in \[JKO13\]. After Alice evaluates $G_B$ and commits to $[v]_B$, Bob opens his garbled circuit and all OTs entirely. Following this, Alice performs a series of consistency checks to detect any malicious behavior. These consistency checks do _not_ depend on any of Alice's inputs, so any attempted selective failure attack by Bob would be futile.
Bob's only options are to behave honestly, or cause Alice to abort without leaking any information.
### Malicious Alice & Bob
They deserve whatever they get.

77
docs/MPC/encryption.md Normal file
View File

@@ -0,0 +1,77 @@
---
sidebar_position: 4
---
# Encryption
Here we will explain our protocol for 2PC encryption using a block cipher in counter-mode.
Our documentation on [Dual Execution with Asymmetric Privacy](deap.md) is recommended prior reading for this section.
## Preliminary
### Ephemeral Keyshare
It is important to recognise that the Notary's keyshare is an _ephemeral secret_. It is only private for the duration of the User's TLS session, after which the User is free to learn it without affecting the security of the protocol.
It is this fact which allows us to achieve malicious security for relatively low cost. More details on this [here](../mpc/deap.md).
### Premature Leakage
A small amount of undetected premature keyshare leakage is quite tolerable. For example, if the Notary leaks 3 bits of their keyshare, it gives the User no meaningful advantage in any attack, as she could have simply guessed the bits correctly with $2^{-3} = 12.5\%$ probability and mounted the same attack. Assuming a sufficiently long cipher key is used, eg. 128 bits, this is not a concern.
The equality check at the end of our protocol ensures that premature leakage is detected with a probability of $1 - 2^{-k}$ where k is the number of leaked bits. The Notary is virtually guaranteed to detect significant leakage and can abort prior to notarization.
### Plaintext Leakage
Our protocol assures _no leakage_ of the plaintext to the Notary during both encryption and decryption. The Notary reveals their keyshare at the end of the protocol, which allows the Notary to open their garbled circuits and oblivious transfers completely to the User. The User can then perform a series of consistency checks to ensure that the Notary behaved honestly. Because these consistency checks do not depend on any inputs of the User, aborting does not reveal any sensitive information (in contrast to standard DualEx which does).
### Integrity
During the entirety of the TLS session the User performs the role of the garbled circuit generator, thus ensuring that a malicious Notary can not corrupt or otherwise compromise the integrity of messages sent to/from the Server.
### Notation
* $p$ is one block of plaintext
* $c$ is the corresponding block of ciphertext, ie $c = \mathsf{Enc}(k, ctr) \oplus p$
* $k$ is the cipher key
* $ctr$ is the counter block
* $k_U$ and $k_N$ denote the User and Notary cipher keyshares, respectively, where $k = k_U \oplus k_N$
* $z$ is a mask randomly selected by the User
* $ectr$ is the encrypted counter-block, ie $ectr = \mathsf{Enc}(k, ctr)$
* $\mathsf{Enc}$ denotes the block cipher used by the TLS session
* $\mathsf{com}_x$ denotes a binding commitment to the value $x$
* $[x]_A$ denotes a garbled encoding of $x$ chosen by party $A$
## Encryption Protocol
The encryption protocol uses [DEAP](../mpc/deap.md) without any special variations. The User and Notary directly compute the ciphertext for each block of a message the User wishes to send to the Server:
$$f(k_U, k_N, ctr, p) = \mathsf{Enc}(k_U \oplus k_N, ctr) \oplus p = c$$
The User creates a commitment to the plaintext active labels for the Notary's circuit $\mathsf{Com}([p]_N, r) = \mathsf{com}_{[p]_N}$ where $r$ is a random key known only to the User. The User sends this commitment to the Notary to be used in the authdecode protocol later. It's critical that the User commits to $[p]_N$ prior to the Notary revealing $\Delta$ in the final phase of DEAP. This ensures that if $\mathsf{com}_{[p]_N}$ is a commitment to valid labels, then it must be a valid commitment to the plaintext $p$. This is because learning the complementary wire label for any bit of $p$ prior to learning $\Delta$ is virtually impossible.
## Decryption Protocol
The protocol for decryption is very similar but has some key differences to encryption.
For decryption, [DEAP](../mpc/deap.md) is used for every block of the ciphertext to compute the _masked encrypted counter-block_:
$$f(k_U, k_N, ctr, z) = \mathsf{Enc}(k_U \oplus k_N, ctr) \oplus z = ectr_z$$
This mask $z$, chosen by the User, hides $ectr$ from the Notary and thus the plaintext too. Conversely, the User can simply remove this mask in order to compute the plaintext $p = c \oplus ectr_z \oplus z$.
Following this, the User can retrieve the wire labels $[p]_N$ from the Notary using OT.
Similarly to the procedure for encryption, the User creates a commitment $\mathsf{Com}([p]_N, r) = \mathsf{com}_{[p]_N}$ where $r$ is a random key known only to the User. The User sends this commitment to the Notary to be used in the authdecode protocol later.
### Proving the validity of $[p]_N$
In addition to computing the masked encrypted counter-block, the User must also prove that the labels $[p]_N$ they chose afterwards actually correspond to the ciphertext $c$ sent by the Server.
This is can be done efficiently in one execution using the zero-knowledge protocol described in [[JKO13]](https://eprint.iacr.org/2013/073.pdf) the same as we do in the final phase of DEAP.
The Notary garbles a circuit $G_N$ which computes:
$$p \oplus ectr = c$$
Notice that the User and Notary will already have computed $ectr$ when they computed $ectr_z$ earlier. Conveniently, the Notary can re-use the garbled labels $[ectr]_N$ as input labels for this circuit. For more details on the reuse of garbled labels see [[AMR17]](https://eprint.iacr.org/2017/062.pdf).

128
docs/MPC/ff-arithmetic.md Normal file
View File

@@ -0,0 +1,128 @@
---
sidebar_position: 2
---
# Finite-Field Arithmetic
Some protocols used in TLSNotary need to convert two-party sharings of products
or sums of some field elements into each other. For this purpose we use share
conversion protocols which use oblivious transfer (OT) as a sub-protocol. Here
we want to have a closer look at the security guarantees these protocols offer.
### Adding covert security
Our goal is to add covert security to our share conversion protocols. This
means that we want an honest party to be able to detect a malicious adversary,
who is then able to abort the protocol. Our main concern is that the adversary
might be able to leak private inputs of the honest party without being noticed.
For this reason we require that the adversary cannot do anything which would
give him a better chance than guessing the private input at random, which is
guessing $k$ bits with a probability of $2^{-k}$ for not being detected.
In the following we want to have a closer look at how the sender and receiver can
deviate from the protocol.
#### Malicious receiver
Note that in our protocol a malicious receiver cannot forge the protocol output,
since he does not send anything to the sender during protocol execution. Even
when this protocol is embedded into an outer protocol, where at some point the
receiver has to open his output or a computation involving it, then all he can
do is to open an output $y'$ with $y' \neq y$, which is just equivalent to
changing his input from $b \rightarrow b'$.
#### Malicious sender
In the case of a malicious sender the following things can happen:
1. The sender can impose an arbitrary field element $b'$ as input onto the
receiver without him noticing. To do this he simply sends $(t_i^k, t_i^k)$ in
every OT, where $k$ is i-th bit of $b'$.
2. The sender can execute a selective-failure attack, which allows him to learn
any predicate about the receiver's input. For each OT round $i$, the sender
alters one of the OT values to be $T_i^k = t_i^k + c_i$, where $c_i \in
\mathcal{F}, \, k \in \{0, 1\}$. This will cause that in the end the equation
$a \cdot b = x + y$ no longer holds but only if the forged OT value has
actually been picked by the receiver.
3. The sender does not use a random number generator with a seed $r$ to sample
the masks $s_i$, instead he simply chooses them at will.
### M2A Protocol Review
Without loss of generality let us recall the Multiplication-To-Addition (M2A)
protocol, but our observations also apply to the Addition-To-Multiplication
(A2M) protocol, which is very similar. We start with a short review of the M2A
protocol.
Let there be a sender with some field element $a$ and some receiver with another
field element $b$. After protocol execution the sender ends up with $x$ and the
receiver ends up with $y$, so that $a \cdot b = x + y$.
- $a,b,x,y \in \mathcal{F}$
- $r$ - rng seed
- $m$ - bit-length of elements in $\mathcal{F}$
- $n$ - bit-length of rng seed
#### OT Sender
with input $a \in \mathcal{F}, \, r \leftarrow \{0, 1\}^n$
1. Sample some random masks: $s_i = rng(r, i), \, 0 \le i < m, \, s_i \in
\mathcal{F} $
2. For every $s_i$ compute:
- $t_i^0 = s_i$
- $t_i^1 = a \cdot 2^i + s_i$
3. Compute new share: $x = - \sum s_i$
3. Send $i$ OTs to receiver: $(t_i^0, t_i^1)$
#### OT Receiver
with input $b \in \mathcal{F}$
1. Set $v_i = t_i^{b_i}$ (from OT)
2. Compute new share: $y = \sum v_i$
### Replay protocol
In order to mitigate the mentioned protocol deviations in the case of a malicious
sender we will introduce a replay protocol.
In this section we will use capital letters for values sent in the replay
protocol, which in the case of an honest sender are equal to their lowercase
counterparts.
The idea for the replay protocol is that at some point after the conversion
protocol, the sender has to reveal the rng seed $r$ and his input $a$ to the
receiver. In order to do this, he will send $R$ and $A$ to the receiver after
the conversion protocol has been executed. If the sender is honest then of
course $r == R$ and $a == A$. The receiver can then check if the value he picked
during protocol execution does match what he can now reconstruct from $R$ and
$A$, i.e. that $T_i^{b_i} == t_i^{b_i}$.
**Using this replay protocol the sender at some point reveals all his secrets
because he sends his rng seed and protocol input to the receiver. This means
that we can only use covertly secure share conversion with replay as a
sub-protocol if it is acceptable for the outer protocol, that the input to
share-conversion becomes public at some later point.**
Now in practice we often want to execute several rounds of share-conversion, as we
need to convert several field elements. Because of this we let the sender use
the same rng seed $r$ to seed his rng once and then he uses this rng instance
for all protocol rounds. This means we have $l$ protocol executions $a_n \cdot
b_n = x_n + y_n$, and all masks $s_{n, i}$ produced from this rng seed $r$.
So the sender will write his seed $R$ and all the $A_n$ to some tape, which in
the end is sent to the receiver. As a security precaution we also let the sender
commit to his rng seed before the first protocol execution. In detail:
##### Sender
1. Sender has some inputs $a_n$ and picks some rng seed $r$.
2. Sender commits to his rng seed and sends the commitment to the receiver.
3. Sender sends all his OTs for $n$ protocol executions.
4. Sender sends tape which contains the rng seed $R$ and all the $A_n$.
##### Receiver
1. Receiver checks that $R$ is indeed the committed rng seed.
2. For every protocol execution $l$ the receiver checks that $T_{n, i}^{b_{n,
i}} == t_{n, i}^{b_{n, i}}$.
Having a look at the ways a malicious sender could cheat from earlier, we
notice:
1. The sender can no longer impose an arbitrary field element $b'$ onto the
receiver, because the receiver would notice that $t \neq T$ during the replay.
2. The sender can still carry out a selective-failure attack, but this is
equivalent to guessing $k$ bits of $b$ at random with a probability of
$2^{-k}$ for being undetected.
3. The sender is now forced to use an rng seed to produce the masks, because
during the replay, these masks are reproduced from $R$ and indirectly checked
via $t == T$.

274
docs/MPC/mac.md Normal file
View File

@@ -0,0 +1,274 @@
---
sidebar_position: 5
sidebar_label: MAC
---
# Computing MAC in 2PC
1. [What is a MAC](#section1)
2. [How a MAC is computed in AES-GCM](#section2)
3. [Computing MAC using secure two-party computation (2PC)](#section3)
## 1. What is a MAC <a name="section1"></a>
When sending an encrypted ciphertext to the Webserver, the User attaches a
checksum to it. The Webserver uses this checksum to check whether the ciphertext
has been tampered with while in transit. This checksum is known as the
"authentication tag" and also as the "Message Authentication Code" (MAC).
In order to create a MAC for some ciphertext not only the ciphertext but also
some secret key is used as an input. This makes it impossible to forge some
ciphertext without knowing the secret key.
The first few paragraphs of [this article](https://zsecurity.org/bit-flipping-attacks-against-cipher-block-chaining-algorithms/)
explain what would happen if there was no MAC: it would be possible for a
malicious actor to modify the **plaintext** by flipping certain bits of the
**ciphertext**.
## 2. How a MAC is computed in AES-GCM <a name="section2"></a>
In TLS the plaintext is split up into chunks called "TLS records". Each TLS
record is encrypted and a MAC is computed for the ciphertext. The MAC (in
AES-GCM) is obtained by XORing together the `GHASH output` and the `GCTR
output`. Let's see how each of those outputs is computed:
### 2.1 GCTR output
The `GCTR output` is computed by simply AES-ECB encrypting a counter block with
the counter set to 1 (the iv, nonce and AES key are the same as for the rest of
the TLS record).
### 2.2 GHASH output
The `GHASH output` is the output of the GHASH function described in the
[NIST publication](https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38d.pdf)
in section 6.4 in this way: "In effect, the GHASH function calculates $
X_1•H^{m} ⊕ X_2•H^{m1} ⊕ ... ⊕ X_{m1}•H^{2} ⊕ X_m•H$". $H$
and $X$ are elements of the extension field $\mathrm{GF}(2^{128})$.
* "•" is a special type of multiplication called `multiplication in a finite
field` described in section 6.3 of the NIST publication.
* ⊕ is `addition in a finite field` and it is defined as XOR.
In other words, GHASH splits up the ciphertext into 16-byte blocks, each block
is numbered $X_1, X_2, ...$ etc. There's also $H$
which is called the `GHASH key`, which just is the AES-encrypted zero-block. We
need to raise $H$ to as many powers as there are blocks, i.e. if
we have 5 blocks then we need 5 powers: $H, H^2, H^3, H^4, H^5$.
Each block is multiplied by the corresponding power and all products are summed
together.
Below is the pseudocode for multiplying two 128-bit field elements `x` and `y`
in $\mathrm{GF}(2^{128})$:
```
1. result = 0
2. R = 0xE1000000000000000000000000000000
3. bit_length = 128
4. for i=0 upto bit_length-1
5. if y[i] == 1
6. result ^= x
7. x = (x >> 1) ^ ((x & 1) * R)
8. return result
```
Standard math properties hold in finite field math, viz. commutative: $a+b=b+a$
and distributive: $a(b+c)=ab+ac$.
## 3. Computing MAC using secure two-party computation (2PC) <a name="section3"></a>
The goal of the protocol is to compute the MAC in such a way that neither party
would learn the other party's share of $H$ i.e. the `GHASH key`
share. At the start of the protocol each party has:
1. ciphertext blocks $X_1, X_2, ..., X_m$.
2. XOR share of $H$: the `User` has $H_u$
and the `Notary` has $H_n$.
3. XOR share of the `GCTR output`: the `User` has $GCTR_u$
and the `Notary` has $GCTR_n$.
Note that **2.** and **3.** were obtained at an earlier stage of the TLSNotary protocol.
### 3.1 Example with a single ciphertext block
To illustrate what we want to achieve, we consider the case of just having
a single ciphertext block $X_1$. The `GHASH_output` will be:
$X_1•H = X_1•(H_u ⊕ H_n) = X_1•H_u ⊕ X_1•H_n$
The `User` and the `Notary` will compute locally the left and the right terms
respectively. Then each party will XOR their result to the `GCTR output` share
and will get their XOR share of the MAC:
`User` : $X_1 • H_u \quad ⊕ \quad GCTR_u = MAC_u$
`Notary`: $X_1 • H_n \quad ⊕ \quad GCTR_n = MAC_n$
Finally, the `Notary` sends $ MAC_n$ to the `User` who obtains:
$MAC = MAC_n \quad ⊕ \quad MAC_u$
**For longer ciphertexts, the problem is that higher powers of the hashkey
$H^k$ cannot be computed locally, because we deal with additive sharings,
i.e.$ (H_u)^k ⊕ (H_n)^k \neq H^k$.**
### 3.2 Computing ciphertexts with an arbitrary number of blocks
We now introduce our 2PC MAC protocol for computing ciphertexts with an
arbitrary number of blocks. Our protocol can be divided into the following
steps.
##### Steps
1. First, both parties convert their **additive** shares $H_u$ and $H_n$ into
**multiplicative** shares $\overline{H}_u$ and $\overline{H}_n$.
2. This allows each party to **locally** compute the needed higher powers of these multiplicative
shares, i.e for $m$ blocks of ciphertext:
- the user computes $\overline{H_u}^2, \overline{H_u}^3, ... \overline{H_u}^m$
- the notary computes $\overline{H_n}^2, \overline{H_n}^3, ... \overline{H_n}^m$
3. Then both parties convert each of these multiplicative shares back to additive shares
- the user ends up with $H_u, H_u^2, ... H_u^m$
- the notary ends up with $H_n, H_n^2, ... H_n^m$
4. Each party can now **locally** compute their additive MAC share $MAC_{n/u}$.
The conversion steps (**1** and **3**) require communication between the user
and the notary. They will use **A2M** (Addition-to-Multiplication) and **M2A**
(Multiplication-to-Addition) protocols, which make use of **oblivious
transfer**, to convert the shares. **The user will be the sender and the notary
the receiver.**
![2PC MAC Overview](2pc-mac-overview.png)
#### 3.2.1 (A2M) Convert additive shares of H into multiplicative share
At first (step **1**) we have to get a multiplicative share of $H_{n/u}$,
so that notary and user can locally compute the needed higher powers. For this
we use an adapted version of the A2M protocol in chapter 4 of [Efficient Secure
Two-Party Exponentiation](https://www.cs.umd.edu/~fenghao/paper/modexp.pdf).
The user will decompose his share into $i$ individual oblivious transfers
$t_{u, i}^k = R \cdot (k \cdot 2^i + H_{u, i} \cdot 2^i ⊕ s_i)$, where
- $R$ is some random value used for all oblivious transfers
- $s_i$ is a random mask used per oblivious transfer, with $\sum_i s_i = 0$
- $k \in \\{0, 1\\}$ depending on the receiver's choice.
The notary's choice in the i-th OT will depend on the bit value in the i-th
position of his additive share $H_n$. In the end the multiplicative share of
the user $\overline{H_u}$ will simply be the inverse $R^{-1}$ of the
random value, and the notary will sum all his OT outputs, so that all the
$s_i$ will vanish and hence he gets his multiplicative share
$\overline{H_n}$.
$$
\begin{align}
H &= H_u ⊕ H_n \\\\
&= R^{-1} \cdot R \cdot \sum_i (H_{u,i} ⊕ H_{n, i}) \cdot 2^i ⊕ s_i \\\\
&= R^{-1} \cdot \sum_i t_{u, i}^{H_{n, i}} ⊕ R \cdot \sum_i s_i \\\\
&= \overline{H_u} \cdot \overline{H_n}
\end{align}
$$
#### 3.2.2 (M2A) Convert multiplicative shares $\overline{H^k}$ into additive shares
In step **3** of our protocol, we use the oblivious transfer method described
in chapter 4.1 of the Gilboa paper [Two Party RSA Key
Generation](https://link.springer.com/content/pdf/10.1007/3-540-48405-1_8.pdf)
to convert all the multiplicative shares $\overline{H_{n/u}^k}$ back into
additive shares $H_{n/u}^k$. We only show how the method works for the share
$\overline{H_{n/u}^1}$, because it is the same for higher powers.
The user will be the OT sender and decompose his shares into $i$ individual
oblivious transfers $t_{u,i}^k = k \cdot \overline{H_u} \cdot 2^i + s_i$,
where $k \in \\{0, 1\\}$, depending on the receiver's choices. Each of these
OTs is masked with a random value $s_i$. He will then obliviously send them to
the notary. Depending on the binary representation of his multiplicative share,
the notary will choose one of the choices and do this for all 128 oblivious
transfers.
After that the user will locally XOR all his $s_i$ and end up with his additive
share $H_u$, and the notary will do the same for all the results of the
oblivious transfers and get $H_n$.
$$
\begin{aligned}
\overline{H} &= \overline{H_u} \cdot \overline{H_n} \\\\
&= \overline{H_u} \cdot \sum_i \overline{H_{n, i}} \cdot 2^i \\\\
&= \sum_i (\overline{H_{n, i}} \cdot \overline{H_u} \cdot 2^i ⊕ s_i) ⊕ \sum_i s_i \\\\
&= \sum_i t_{u, i}^{\overline{H_{n, i}}} ⊕ \sum_i s_i \\\\
&\equiv H_n ⊕ H_u
\end{aligned}
$$
### 3.3 Free Squaring
In the actual implementation of the protocol we only compute odd multiplicative
shares, i.e. $\overline{H}, \overline{H^3}, \overline{H^5}, \ldots$, so that
we only need to share these odd shares in step **3**. This is possible because
we can compute even additive shares from odd additive shares. We observe that
for even $k$:
$$
\begin{align}
H^k &= (H_n^{k/2} ⊕ H_u^{k/2})^2 \\\\
&= (H_n^{k/2})^2 ⊕ H_n^{k/2} H_u^{k/2} ⊕ H_u^{k/2} H_n^{k/2} ⊕ (H_u^{k/2})^2 \\\\
&= (H_n^{k/2})^2 ⊕ (H_u^{k/2})^2 \\\\
&= H_n^k ⊕ H_u^k
\end{align}
$$
So we only need to convert odd multiplicative shares into odd additive shares,
which gives us a 50% reduction in cost. The remaining even additive shares can
then be computed locally.
### 3.3 Creating a robust protocol
Both the A2M and M2A protocols on their own only provide semi-honest security.
They are secure against a malicious receiver, but the sender has degrees of
freedom to cause leakage of the MAC keyshares. However, for our purposes this
does not present a problem as long as leakage is detected.
To detect a malicious sender, we require the sender to commit to the PRG seed
used to generate the random values in the share conversion protocols. After the
TLS session is closed the MAC keyshares are no longer secret, which allows the
sender to reveal this seed to the receiver. Subsequently, the receiver can
perform a consistency check to make sure the sender followed the protocol
honestly.
#### 3.3.1 Malicious notary
The protocol is secure against a malicious notary, because he is the OT
receiver, which means that there is actually no input from him during the
protocol execution except for the final MAC output. He just receives the OT
input from the user, so the only thing he can do is to provide a wrong MAC
keyshare. This will cause the server to reject the MAC when the user sends the
request. The protocol simply aborts.
#### 3.3.2 Malicious user
A malicious user could actually manipulate what he sends in the OT and
potentially endanger the security of the protocol by leaking the notary's
MAC key. To address this we force the user to reveal his MAC key after the
server response so that the notary can check for the correctness of the whole
MAC 2PC protocol. Then if the notary detects that the user cheated, he would
simply abort the protocol.
The only problem when doing this is, that we want the whole TLSNotary protocol
to work under the assumption that the notary can intercept the traffic between
the user and the server. This would allow the notary to trick the user into
thinking that the TLS session is already terminated, if he can force the server
to respond. The user would send his MAC key share too early and the notary
could, now having the complete MAC key, forge the ciphertext and create a valid
MAC for it. He would then send this forged request to the server and forward the
response of the server to the user.
To prevent this scenario we need to make sure that the TLS connection to the
server is terminated before the user sends his MAC key share to the notary.
Following the [TLS RFC](https://www.rfc-editor.org/rfc/rfc8446#section-6.1),
we leverage `close_notify` to ensure all messages sent to the server have been
processed and the connection is closed. Unfortunately, many server TLS
implementations do not support `close_notify`. In these cases we instead send an
invalid message to the server which forces it to respond with a fatal alert
message and close the connection.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,28 @@
---
sidebar_position: 3
---
# Commit Strategy
When the `Prover` generates authenticated commitments to the plaintext of the transcript, it is possible to choose which range(s) of the plaintext to commit to. This dictates the range(s) that can be selectively disclosed later to the application-specific `Verifier`. This section discusses different commit strategies, as well as their associated costs.
## Strategy
Depending on the application, different commit strategies can be chosen. One can commit to everything at once, to each byte individually, or any selection of ranges. There is no significant computational impact when you choose a large number of commitments, but there is a linear storage cost increase.
TLSNotary offers a default strategy that commits to ranges corresponding with HTTP objects. This results in a good balance between *selective disclosure flexibility* and *storage size* for most use cases.
The table below provides an overview of the different commit strategies:
| Strategy | Description | Selective Disclosure | Cost | Usage |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Commit to custom range(s) | Only commit to the range(s) that need to be selectively disclosed later | Only the committed ranges can be revealed. Subranges or other ranges cannot be revealed | Smallest artefact size | Suitable when only a single (or a few) selective disclosure pattern is required and size is important |
| Commit to HTTP objects | Commit to ranges that correspond to all common HTTP objects in both request and response, e.g., every header's key and value, every key and value in JSON response body | Flexible to selectively reveal different HTTP objects in different presentations of the transcript | Larger artefact size than strategy #1 | Suitable for most use cases — the default strategy used in the repository's [example](https://github.com/tlsnotary/tlsn/blob/4d5102b6e141ecb84b8a835604be1d285ae6eaa5/crates/examples/attestation/prove.rs#L99) |
| Commit to each byte | One commit for each byte, resulting in the maximum number of commitments | Maximum flexibility as any range of the transcript can be selectively disclosed in multiple presentations | Largest artefact size among all strategies | Suitable when needed to support selective disclosure on many arbitrary ranges beyond common HTTP objects |
## Cost
The commitment strategies differ mainly in the number of committed ranges (`K`). As `K` increases, the primary cost is the size of the generated artefact. The table below details the artefacts and how their sizes scale with `K`.
| Artefact | Description | Size Scaling | Explanation |
| ------------- | ------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
| `Attestation` | Artifact signed by the `Notary` attesting to the authenticity of the plaintext from a TLS session | Constant | `Attestation` only contains data that remains constant-sized regardless of `K`, e.g., the Merkle root of the commitments |
| `Secret` | Artifact containing secret data that correspond to commitments in `Attestation` | Linear | `Secret` contains some data whose sizes scale linearly with `K`, e.g., a Merkle tree whose number of leaves equals `K` |
Using the default hash algorithm (i.e., BLAKE3), every additional range committed costs around 250 bytes of increment in the size of `Secret`. For more details, please visit this [Jupyter notebook](https://github.com/tlsnotary/docs-mdbook/blob/main/src/protocol/commit_strategy.ipynb).

View File

@@ -0,0 +1,24 @@
---
sidebar_position: 1
---
# MPC-TLS
During the MPC-TLS phase the `Prover` and the `Verifier` run an MPC protocol enabling the `Prover` to connect to, and exchange data with, a TLS-enabled `Server`.
Listed below are some key points regarding this protocol:
- The `Verifier` only learns the *encrypted* application data of the TLS session.
- The `Prover` is not solely capable of constructing requests, nor can they forge responses from the `Server`.
- The protocol enables the `Prover` to prove the authenticity of the exchanged data to the `Verifier`.
<!-- The MPC-TLS protocol consists of the following steps:
1. **Handshake**
A TLS handshake is the first step in establishing a TLS connection between the `Prover`/`Verifier` and the `Server`. The result of this handshake is a *Pre Master Secret (PMS)*, a symmetrical key that will be used for further encrypted communication. The server has the full key; the `Prover` and the `Verifier` only have their share of this key.
2. **Encryption, Decryption, and MAC Computation**
Next, the `Prover` and `Verifier` use MPC to encrypt, and decrypt, data sent to, and received from, the `Server`. They also compute a *Message Authentication Code (MAC)*
for the data that ensures untampered communication. -->

View File

@@ -0,0 +1,30 @@
---
sidebar_position: 2
sidebar_label: Encryption and Decryption
---
# Encryption, Decryption, and MAC Computation
This section explains how the `Prover` and `Verifier` use MPC to encrypt data sent to the server, decrypt data received from the server, and compute the MAC for the ciphertext using MPC. It shows how the `Prover` and `Verifier` collaborate to encrypt and decrypt data. The `Verifier` performs these tasks "blindly", without acquiring knowledge of the plaintext.
## Encryption
To encrypt the plaintext, both parties input their TLS key shares as private inputs to the [MPC](../../mpc/deap.md) protocol, along with some other public data. Additionally, the `Prover` inputs her plaintext as a private input.
![Encryption](../../diagrams/mpc-encryption.svg)
Both parties see the resulting ciphertext and execute the [2PC MAC](../../mpc/mac.md) protocol to compute the MAC for the ciphertext.
The `Prover` then dispatches the ciphertext and the MAC to the server.
## Decryption
Once the `Prover` receives the ciphertext and its associated MAC from the server, the parties first authenticate the ciphertext by validating the MAC. They do this by running the [MPC](../../mpc/mac.md) protocol to compute the authentic MAC for the ciphertext. They then verify if the authentic MAC matches the MAC received from the server.
Next, the parties decrypt the ciphertext by providing their key shares as private inputs to the [MPC](../../mpc/deap.md) protocol, along with the ciphertext and some other public data.
![Decryption](../../diagrams/mpc-decryption.svg)
The resulting plaintext is revealed ONLY to the `Prover`.
Please note, the actual low-level implementation details of decryption are more nuanced than what we have described here. For more information, please consult [Low-level Decryption details](../../mpc/encryption.md).

View File

@@ -0,0 +1,19 @@
---
sidebar_position: 1
---
# Handshake
![](../../diagrams/key_exchange.svg)
A TLS handshake is the first step in establishing a TLS connection between a `Prover` and a `Server`. In TLSNotary the `Prover` is the one who starts the TLS handshake and physically communicates with the `Server`, but all cryptographic TLS operations are performed together with the `Verifier` using MPC.
The `Prover` and `Verifier` use a series of MPC protocols to compute the TLS session key in such a way that both only have their share of the key and never learn the full key. Both parties then proceed to complete the TLS handshake using their shares of the key.
See our section on [Key Exchange](../../mpc/key_exchange.md) for more details of how this is done.
> Note: to a third party observer, the `Prover`'s connection to the server appears like a regular TLS connection and the security guaranteed by TLS remains intact for the `Prover`.
>
> The only exception is that since the `Verifier` is a party to the MPC TLS, the security for the `Prover` against a malicious `Verifier` is provided by the underlying MPC protocols and not by TLS.
With the shares of the session key computed and the TLS handshake completed, the parties now proceed to the next MPC protocol where they use their session key shares to jointly generate encrypted requests and decrypt server responses while keeping the plaintext of both the requests and responses private from the `Verifier`.

View File

@@ -0,0 +1,18 @@
---
sidebar_position: 2
---
# Notarization
Even though the `Prover` can prove data provenance directly to the `Verifier`, in some scenarios it may be beneficial for the `Verifier` to outsource the verification of the TLS session to a trusted `Notary` as explained [here](../intro.md#tls-verification-with-a-general-purpose-notary).
As part of the TLSNotary protocol, the `Prover` creates authenticated commitments to the plaintext and has the `Notary` sign them without the `Notary` ever seeing the plaintext. This offers a way for the `Prover` to selectively prove the authenticity of arbitrary ranges of the plaintext to an application-specific `Verifier` later.
Please refer to the [Commitments](../mpc/commitments.md) section for low-level details on the commitment scheme; and [Commit Strategy](./commit_strategy.md) section for different strategies the `Prover` can employ when generating these authenticated commitments.
## Signing the Session Header
The `Notary` signs an artifact known as a `Session Header`, thereby attesting to the authenticity of the plaintext from a TLS session. A `Session Header` contains a `Prover`'s commitment to the plaintext and a `Prover`'s commitment to TLS-specific data which uniquely identifies the server.
The `Prover` can later use the signed `Session Header` to prove data provenance to an application-specific `Verifier`.
It's important to highlight that throughout the entire TLSNotary protocol, including this signing stage, the `Notary` does not gain knowledge of either the plaintext or the identity of the server with which the `Prover` communicated.

View File

@@ -0,0 +1,37 @@
---
sidebar_position: 5
---
# Server identity privacy
To maximize `Prover` privacy, the server identity is not revealed to the `Verifier` by default.
The TLSNotary protocol mitigates the threat of a malicious `Verifier` attempting to infer the server identity from the messages they receive during MPC-TLS.
The exact low-level details are outlined below.
## Handshake hash
During the MPC-TLS handshake, the `Verifier` learns the hash digest of all handshake messages
(see "Verify Data" in https://tls12.xargs.org/#client-handshake-finished/annotated).
If the hashed message lacks sufficient randomness that is unknown to the `Verifier`, they could collect all TLS certificates in existence and attempt a dictionary attack on the digest.
## Sources of handshake randomness
The randomness in a handshake comes from `client random`, `server random`, and the `signature` (see "Signature" in https://tls12.xargs.org/#server-key-exchange/annotated). For optimization, both `client random` and `server random` are revealed to the `Verifier` during MPC-TLS. We argue that the `signature` contains sufficient randomness unknown to the `Verifier` to prevent the dictionary attack described above.
Note that the signed message **is known** to the `Verifier`. This message is computed as H(`client_random` + `server_random` + kx_params), where
- H is a hash function, usually SHA256
- kx_params are ECDHE key exchange parameters known to the `Verifier`
## Signature unforgeability
Unforgeability is a key property of signature schemes that ensures that even if the attacker (the `Verifier` in this case) knows both the message the public key of the signer, it is computationally infeasible to forge a valid signature for that message.
>We follow the terminology from the signature forgery taxonomy here: https://crypto.stackexchange.com/questions/44188/what-do-the-signature-security-abbreviations-like-euf-cma-mean/44210#44210
> - `EF-CMA`: Existential Forgery under Chosen-Message Attack
> - `UF-KMA`: Universal Forgery under Known-Message Attack
All TLS signature schemes are EF-CMA-secure, but we argue that even the weaker UF-KMA security would suffice for our scenario where an attacker is given:
- an arbitrary message,
- a public key, and
- many arbitary messages and their signatures collected from previous server interactions.
This scenario fits precisely within the UF-KMA model. Since UF-KMA is a subset of EF-CMA, we conclude that our approach is secure.

View File

@@ -0,0 +1,21 @@
---
sidebar_position: 4
---
# Verification
To prove data provenance to a third-party `Verifier`, the `Prover` provides the following information:
- [`Session Header`](notarization.md#signing-the-session-header) signed by the `Notary`
- `opening` to the plaintext commitment
- `TLS-specific data` which uniquely identifies the server
- `identity` of the server
The `Verifier` performs the following verification steps:
- verifies that the `opening` corresponds to the commitment in the `Session Header`
- verifies that the `TLS-specific data` corresponds to the commitment in the `Session Header`
- verifies the `identity` of the server against `TLS-specific data`
Next, the `Verifier` parses the `opening` with an application-specific parser (e.g. HTTP or JSON) to get the final output. Since the `Prover` is allowed to selectively disclose the data, that data which was not disclosed by the `Prover` will appear to the `Verifier` as redacted.
Below is an example of a verification output for an HTTP 1.1 request and response. Note that since the `Prover` chose not to disclose some sensitive information like their HTTP session token and address, that information will be withheld from the `Verifier` and will appear to him as redacted (in red).
![Verification example](../diagrams/verification_example.svg)

View File

@@ -0,0 +1,69 @@
# Notarized session
The `Notary` signs the following artifacts known as a `Session Header`, thereby attesting to the authenticity of the plaintext from a TLS session. The `User` can then use the signed `Session Header` to prove data provenance to a third-party `Verifier`.
It's important to highlight that throughout the entire TLSNotary protocol, including this signing stage, the `Notary` does not gain knowledge of either the plaintext or the server with which the `User` communicated.
## Session Header
A `Session Header` consists of the following components:
### Server Ephemeral Public Key
In TLS, session keys are derived from a one-time per-TLS-session ephemeral public key. The server signs this key with its certificate and transmits both the key and the signature to the `User`.
Since the `Notary` remains unaware of the signature or the certificate, the server's identity is concealed. However, the `User` can disclose the server's identity to a `Verifier` by revealing the signature and the certificate.
### Plaintext Encodings
These are the [encodings](../mpc/encodings.md) employed by the Notary to encode the plaintext.
Again, note that the `Notary` does not gain knowledge of the actual plaintext. The `Notary` transmits these encodings to the `User` using [Oblivious Transfer](../mpc/oblivious_transfer.md).
For efficiency, the `Notary` employs a small PRG seed to generate random plaintext encodings.
### Root of the Merkle Tree of Commitments
The root of the Merkle tree, where each leaf represents the `User`'s commitment to plaintext encodings.
### Commitment to the TLS Handshake Data
This represents the `User`'s commitment to various public data from the TLS handshake:
- Server certificate chain
- Signature over the `Server Ephemeral Public Key`, created using the `Server Certificate Chain`
- Client random
- Server random
### Time
Indicates the time when the Notary signed the `Session Header`.
### Total Bytes Sent and Received
The total amount of application data bytes that the `User` sent to and received from the server.
## Session Data
<!-- // (can be seen in tlsn-core/src/session/data.rs) -->
- `handshake_data_decommitment` contains `HandshakeData` which the `User` committed to (with salt)
`HandshakeData` contains various TLS-specific details:
- `server_cert_details` (server certificate chain)
- `server_kx_details` (data used in ECDH key exchange)
- `client_random` (client random from the `Client Hello` TLS message)
- `server_random` (server random from the `Server Hello` TLS message)
- `tx_transcript` and `rx_transcript` contain all application level plaintext bytes which were transmitted to/received from the server
- `merkle_tree` is a Merkle tree the leaves of which are the `User`'s commitments to plaintext. The `User` may commit to multiple slices of plaintext and then selectively disclose to the `Verifier` only those slices which he wants to make public
- `commitments` contains the `User`'s commitments to plaintext, where each commitment structure is:
- `merkle_tree_index` is the index in the `merkle_tree`
- `commitment` is the actual commitment value e.g. a blake3 hash
- `ranges` are byte ranges within `tx/rx_transcript` where the bytes committed to are located
- `direction` is used to identify whether it is a commitment to tx or rx data
- `salt` is a salt for the `commitment`

View File

@@ -0,0 +1,33 @@
# Verification
A `Verifier` receives the following from the `User`:
<!-- // TODO will explain each -->
- domain name (e.g. "tlsnotary.org")
- signed `Session Header`
- openings to the commitments (the plaintext which the User committed to)
- handshake_data which consists of:
- server certificate
- key exchange details
- client and server random
and performs the following steps to verify the commitments:
<!-- // you can see these steps in tlsn/tlsn-core/tests/api.rs -->
- verify that `Session Header` was signed by the Notary
- verify handshake_data against handshake_commitment
- verify validity of `server certificate` for the `domian name`
- verify that `key exchange details` were signed by the `server certificate`
- use encoder_seed to re-generate encodings and re-create a commitment for the opening plaintext
(maybe this step needs to be spelled out in more detail)
- use `merkle_root` to check that this re-created commitment is in the Merkle tree
To summarize: the `Verifier` will only learn those portions of the TLS session transcript which the `User` chose to reveal. The portions which were not revealed (`User`'s private data) will appear to the `Verifier` as redacted. Here is an example of what the `Verifier` output may look like:
<!-- // paste here a picture of an HTTP request with redacted fields -->
![Verification example](../diagrams/verification_example.svg)

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

116
docs/faq.mdx Normal file
View File

@@ -0,0 +1,116 @@
---
title: Frequently Asked Questions
sidebar_position: 3
sidebar_label: FAQ
---
import TOCInline from '@theme/TOCInline';
<TOCInline toc={toc} />
### Doesn't TLS allow a third party to verify data authenticity?
No, it does not. TLS is designed to guarantee the authenticity of data **only to the participants** of the TLS connection. TLS does not have a mechanism to enable the server to "sign" the data.
The TLSNotary protocol overcomes this limitation by making the third-party `Verifier` a participant in the TLS connection.
### Why is it necessary to add a verifier to the TLS connection
One may wonder why the `Prover` can not simply generate a proof of the TLS connection locally without the help of another party.
This is not possible because of the way TLS is designed. Specifically, TLS utilizes symmetric-key cryptography with message authentication codes (MACs). As a consequence the TLS client, i.e. the `Prover`,
knows the secret key the `Server` uses to authenticate data and can trivially generate fake transcripts locally. Introducing another party into the connection mitigates this problem by removing unilateral access to the secret key from the `Prover`.
### How exactly does a Verifier participate in the TLS connection?
The `Verifier` collaborates with the `Prover` using secure multi-party computation (MPC). There is no requirement for the `Verifier` to monitor or to access the `Prover's` TLS connection. The `Prover` is the one who communicates with the server.
### What are the trust assumptions of the TLSNotary protocol?
The protocol does not have trust assumptions. In particular, it does not rely on secure hardware or on the untamperability of the communication channel.
The protocol does not rely on participants to act honestly. Specifically, it guarantees that, on the one hand, a malicious `Prover` will not be able to convince the `Verifier` of the authenticity of false data, and, on the other hand, that a malicious `Verifier` will not be able to learn the private data of the `Prover`.
### What is the role of a Notary?
In some scenarios where the `Verifier` is unable to participate in a TLS connection, they may choose to delegate the verification of the online phase of the protocol to an entity called the `Notary`.
Just like the `Verifier` would ([see FAQ above](#faq2)), the `Notary` collaborates with the `Prover` using MPC to enable the `Prover` to communicate with the server. At the end of the online phase, the `Notary` produces an attestation trusted by the `Verifier`. Then, in the offline phase, the `Verifier` is able to ascertain data authenticity based on the attestation.
### Is the Notary an essential part of the TLSNotary protocol?
No, it is not essential. The `Notary` is an optional role which we introduced in the `tlsn` library as a convenience mode for `Verifiers` who choose not to participate in the TLS connection themselves.
For historical reasons, we continue to refer to the protocol between the `Prover` and the `Verifier` as the "TLSNotary" protocol, even though the `Verifier` may choose not to use a `Notary`.
### Which TLS versions are supported?
We support TLS 1.2, which is an almost-universally deployed version of TLS on the Internet.
There are no immediate plans to support TLS 1.3. Once the web starts to transition away from TLS 1.2, we will consider adding support for TLS 1.3 or newer.
### What is the overhead of using the TLSNotary protocol?
Due to the nature of the underlying MPC, the protocol is bandwidth-bound. We are in the process of implementing more efficient MPC protocols designed to decrease the total data transfer.
With the upcoming protocol upgrade planned for 2025, we expect the `Prover's` **upload** data overhead to be:
~25MB (a fixed cost per one TLSNotary session) + ~10 MB per every 1KB of outgoing data + ~40KB per every 1 KB of incoming data.
In a concrete scenario of sending a 1KB HTTP request followed by a 100KB response, the `Prover's` overhead will be:
25 + 10 + 4 = ~39 MB of **upload** data.
### Does TLSNotary use a proxy?
A proxy is required only for the browser extension because browsers do not allow extensions to open TCP connections. Instead, our extension opens a websocket connection to a proxy (local or remote) which opens a TCP connection with the server. Our custom TLS client is then attached to this connection and the proxy only sees encrypted data.
[PSE hosts a WebSocket proxy](https://docs.tlsnotary.org/developers/notary_server.html#websocket-proxy-server) that you can use for development and experimentation. Note that this proxy supports only a limited [whitelist of domains](https://docs.tlsnotary.org/developers/notary_server.html#websocket-proxy-server). For other domains, you can easily run your own local WebSocket by following [these steps](https://docs.tlsnotary.org/quick_start/browser_extension.html#websocket-proxy).
### Why does my session time out?
If you are experiencing slow performance or server timeouts, make sure you are building with the `--release` profile. Debug builds are significantly slower due to extra checks. Use:
```
cargo run --release
```
### How to run TLSNotary with extra logging?
To get deeper insights into what TLSNotary is doing, you can enable extra logging with `RUST_LOG=debug` or `RUST_LOG=trace`. This will generate a lot of output, as it logs extensive network activity. Its recommended to filter logs for better readability. The recommended configuration is:
```
RUST_LOG=trace,yamux=info,uid_mux=info cargo run --release
```
In the browser extension, you can change the logging level via **Options > Advanced > Logging Level**.
For the notary server, please refer to [this](https://github.com/tlsnotary/tlsn/blob/main/crates/notary/server/README.md#logging) on how to change the logging level.
### How do I troubleshoot connection issues?
If a TLSNotary request fails, first ensure that the request works independently of TLSNotary by testing it with tools like `curl`, Postman, or another HTTP client. This helps rule out any server or network issues unrelated to TLSNotary.
Next, confirm that your request includes the necessary headers:
- `Accept-Encoding: identity` to avoid compressed responses.
- `Connection: close` to ensure the server closes the connection after the response.
If the issue persists, [enable extra logging](#faq11) with `RUST_LOG=debug` or `RUST_LOG=trace` for deeper insights into what TLSNotary is doing.
If you are connecting through a WebSocket proxy (e.g., in the browser extension), double-check that the WebSocket proxy connects to the intended domain. Note that PSE's public WebSocket proxy only supports a limited [whitelist](https://docs.tlsnotary.org/developers/notary_server.html#websocket-proxy-server). If you use a local proxy, make sure the domain is correct.
### Does TLSNotary solve the Oracle Problem?
No, the TLSNotary protocol does not solve the "Oracle Problem". The Oracle Problem refers to the challenge of ensuring that off-chain data used in blockchain smart contracts is trustworthy and tamper-proof. While TLSNotary allows a Prover to cryptographically authenticate TLS data to a designated Verifier, trust is still required in the designated Verifier when it attests to the verified data on-chain. Therefore, this is not a trustless, decentralized solution to the Oracle Problem.
TLSNotary can be used to bring data on-chain, but when the stakes are high, it is recommended to combine TLSNotary with a dedicated oracle protocol to mitigate these risks. Multiple projects are currently exploring the best solutions.
### What is a presentation in TLSNotary?
In TLSNotary, a **presentation** refers to data shared by the Prover to selectively reveal specific parts of the TLS data committed to earlier during the attestation phase. By using these earlier commitments, the Prover can choose to disclose only particular segments of the TLS data while keeping other parts hidden or redacted. This enables a flexible and controlled way to share proofs, ensuring that sensitive information remains private.
The term “presentation” is inspired by similar terminology in the [W3C Verifiable Credentials standard](https://www.w3.org/TR/vc-data-model/#dfn-verifiable-presentations).
### Why does TLSNotary need an online Verifier? Can't this be done serverlessly in the browser with Zero Knowledge?
TLSNotary uses a multi-party computation (MPC) approach to secure the TLS session. Without MPC, the Prover would have full control over the TLS session keys and could forge the Servers responses. Zero-knowledge (ZK) proofs alone cannot prevent this. To prevent forged responses, the Verifier participates in the handshake, splitting the TLS session keys between the Prover and the Verifier.
In proxy-based designs only ZK proofs are needed. In such designs the verifier proxies the connection with the server, observes the encrypted traffic, and later verifies a ZK proof from the Prover that the plaintext matches the encrypted data. TLSNotarys direct connection model avoids introducing a network assumption and provides stronger resistance to censorship compared to the proxy approach.

24
docs/glossary.md Normal file
View File

@@ -0,0 +1,24 @@
# Glossary
| Term | Explanation |
| ----- | ----------------------------------------------- |
| 2PC | Secure Two-party computation |
| A2M | Addition-to-Multiplication |
| AES | Advanced Encryption Standard |
| DEAP | Dual Execution with Asymmetric Privacy |
| ECB | Electronic codebook (encryption mode) |
| ECDH | Elliptic-Curve Diffie-Hellman |
| GC | Garbled Circuit |
| GCM | Galois/Counter Mode |
| GHASH | GCM hash |
| HMAC | Hash-based Message Authentication Code |
| M2a | Multiplication-to-Addition |
| MAC | Message Authentication Code |
| MPC | Secure Multi-party computation |
| OT | oblivious transfer |
| PMS | Pre master secret (TLS) |
| PRF | Pseudo Random Function |
| PRG | pseudorandom generator |
| PSE | Privacy and Scaling Exploration |
| RSA | RivestShamirAdleman (public-key cryptosystem) |
| TLS | transport layer security |

View File

@@ -1,5 +1,5 @@
---
sidebar_position: 1
sidebar_position: 2
---
# Motivation

View File

@@ -1,3 +1,6 @@
---
sidebar_position: 1
---
# Key Exchange
In TLS, the first step towards obtaining TLS session keys is to compute a shared secret between the client and the server by running the [ECDH protocol](https://en.wikipedia.org/wiki/Elliptic-curve_DiffieHellman). The resulting shared secret in TLS terms is **called the pre-master secret `PMS`**.

107
docs/notary_server.md Normal file
View File

@@ -0,0 +1,107 @@
---
sidebar_position: 4
---
# Run a Notary Server
This guide shows you how to run a [notary server](https://github.com/tlsnotary/tlsn/tree/main/crates/notary/server) in an Ubuntu server instance.
## Configure Server Setting
All the following settings can be configured in the [config file](https://github.com/tlsnotary/tlsn/blob/main/crates/notary/server/config/config.yaml).
1. Before running a notary server you need the following files. ⚠️ The default dummy fixtures are for testing only and should never be used in production.
| File | Purpose | File Type | Compulsory to change | Sample Command |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ---------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| TLS private key | The private key used for the notary server's TLS certificate to establish TLS connections with provers | TLS private key in PEM format | Yes unless TLS is turned off | \<Generated when creating CSR for your Certificate Authority, e.g. using [Certbot](https://certbot.eff.org/)> |
| TLS certificate | The notary server's TLS certificate to establish TLS connections with provers | TLS certificate in PEM format | Yes unless TLS is turned off | \<Obtained from your Certificate Authority, e.g. [Let's Encrypt](https://letsencrypt.org/)> |
| Notary signature private key | The private key used for the notary server's signature on the generated transcript of the TLS sessions with provers | A K256 elliptic curve private key in PKCS#8 PEM format | Yes | `openssl genpkey -algorithm EC -out eckey.pem -pkeyopt ec_paramgen_curve:secp256k1 -pkeyopt ec_param_enc:named_curve` |
| Notary signature public key | The public key used for the notary server's signature on the generated transcript of the TLS sessions with provers | A matching public key in PEM format | Yes | `openssl ec -in eckey.pem -conv_form compressed -pubout -out eckey.pub` |
2. Expose the notary server port (specified in the config file) on your server networking setting
3. Optionally one can turn on [authorization](https://github.com/tlsnotary/tlsn/tree/main/crates/notary/server#authorization), or turn off [TLS](https://github.com/tlsnotary/tlsn/tree/main/crates/notary/server#optional-tls) if TLS is handled by an external setup, e.g. reverse proxy, cloud setup
## Using Cargo
1. Install required system dependencies
```bash
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install libclang-dev pkg-config build-essential libssl-dev
```
2. Install rust
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
```
3. Download notary server source code
```bash
mkdir ~/src; cd ~/src
git clone https://github.com/tlsnotary/tlsn.git
```
4. Switch to your desired [released version](https://github.com/tlsnotary/tlsn/releases), or stay in the `main` branch to use the latest version (⚠️ only prover of the same version is supported for now)
```bash
git checkout tags/<version>
```
5. To configure the [server setting](#configure-server-setting), please refer to the `Using Cargo` section in the repo's [readme](https://github.com/tlsnotary/tlsn/blob/main/crates/notary/server/README.md#using-cargo)
6. Run the server
```bash
cd crates/notary/server
cargo run --release
```
## Using Docker
1. Install docker following your preferred method [here](https://docs.docker.com/engine/install/ubuntu/)
2. To configure the [server setting](#configure-server-setting), please refer to the `Using Docker` section in the repo's [readme](https://github.com/tlsnotary/tlsn/blob/main/crates/notary/server/README.md#using-docker)
3. Run the notary server docker image of your desired version (⚠️ only prover of the same version is supported for now)
```bash
docker run --init -p 127.0.0.1:7047:7047 ghcr.io/tlsnotary/tlsn/notary-server:<version>
```
## API Endpoints
Please refer to the list of all HTTP APIs [here](../../swagger-ui/notary_server_api.html), and WebSocket APIs [here](https://github.com/tlsnotary/tlsn/tree/main/crates/notary/server#websocket-apis).
## PSE Development Notary Server
> **_⚠ WARNING:_** notary.pse.dev is hosted for development purposes only. You are welcome to use it for exploration and development; however, please refrain from building your business on it. Use it at your own risk.
The TLSNotary team hosts a public notary server for development, experimentation, and demonstration purposes. The server is currently open to everyone, provided that it is used fairly.
We host multiple versions of the notary server: Check https://notary.pse.dev to get a list of the currently hosted versions. The version with a `-sgx` suffix run the TLSNotary notary software in a Trusted Execution Environment (TEE), Intel SGX on Azure.
You can verify the software attestation by visiting `https://notary.pse.dev/<version>/info`.
To check the status of the notary server, visit the `healthcheck` endpoint at:
`https://notary.pse.dev/<version>/healthcheck`
### WebSocket Proxy Server
Because web browsers don't have the ability to make TCP connections directly, TLSNotary requires a WebSocket proxy to set up TCP connections when it is used in a browser. To facilitate the exploration of TLSNotary and to run the examples easily, the TLSNotary team hosts a public WebSocket proxy server. Note that this proxy only supports a predefined set of domains. You can view the full list of supported domains in the [websockify configuration file](https://github.com/privacy-scaling-explorations/tlsn-infra/blob/main/docker/websockify/websockify_config).
You can utilize this WebSocket proxy with the following syntax:
```
wss://notary.pse.dev/proxy?token=<domain>
```
Replace `<domain>` with the domain you wish to access (for example, `swapi.dev`).
## Running Notary Server on Windows Subsystem for Linux (WSL)
When running the Notary Server and WebSocket Proxy on Windows Subsystem for Linux (WSL), you may encounter networking issues. In older versions of Windows (prior to Windows 11 22H2), WSL uses a virtual Ethernet adapter with its own IP address, which requires additional firewall configuration.
#### For Windows Versions Prior to 11 22H2:
1. **Identify the WSL IP Address**:
Run the following command inside the WSL terminal:
```bash
wsl hostname -I
```
2. **Configure Port Forwarding on the Windows Host**:
To forward traffic from the Windows host to the Notary Server inside WSL, set up port forwarding. Run the following PowerShell command on your Windows host, replacing `connectaddress` with the WSL IP address you retrieved in the previous step:
```powershell
netsh interface portproxy add v4tov4 listenport=7047 listenaddress=0.0.0.0 connectport=7047 connectaddress=192.168.101.100
```
#### For Windows 11 22H2 and Later:
In newer versions of Windows (Windows 11 22H2 and above), networking has been simplified with the introduction of mirrored mode. This mode allows WSL instances to share the hosts network interface, eliminating the need for manual port forwarding configurations. You can enable mirrored mode as recommended by Microsoft [here](https://learn.microsoft.com/en-us/windows/wsl/networking#mirrored-mode-networking).

View File

@@ -1,5 +1,5 @@
---
sidebar_position: 1
sidebar_position: 3
---
# Quick Start

View File

@@ -23,6 +23,9 @@ function HomepageHeader() {
to="/docs/intro">
Check out our documentation
</Link>
</div>
<br />
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="https://demo.tlsnotary.org">

View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="SwaggerUI" />
<title>Notary Server HTTP APIs</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-bundle.js" crossorigin></script>
<script>
window.onload = () => {
window.ui = SwaggerUIBundle({
url: 'https://raw.githubusercontent.com/tlsnotary/tlsn/main/crates/notary/server/openapi.yaml#/',
dom_id: '#swagger-ui',
});
};
</script>
</body>