mirror of
https://github.com/tlsnotary/website.git
synced 2026-01-06 21:43:53 -05:00
Convert more docs
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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
284
blog/2024-11-14-devcon.md
Normal 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, we’ll begin with the basics. To keep things simple, we’ll use a local, single-computer setup wherever possible.
|
||||
|
||||
### Rust: Interactive Verification without a Trusted Notary
|
||||
|
||||
We’ll start by running the most basic TLSNotary setup.
|
||||
|
||||

|
||||
|
||||
|
||||
We’ll 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 you’re not a Rust dev, don’t worry—you don’t 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, we’ll run the TLSNotary protocol with a Notary server blindly verifying the TLS session.
|
||||
|
||||

|
||||
|
||||
|
||||
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.
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
facebook:
|
||||
label: Facebook
|
||||
label: MPC-TLS
|
||||
permalink: /facebook
|
||||
description: Facebook tag description
|
||||
|
||||
|
||||
BIN
docs/MPC/2pc-mac-overview.png
Normal file
BIN
docs/MPC/2pc-mac-overview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
9
docs/MPC/_commitment_scheme.md
Normal file
9
docs/MPC/_commitment_scheme.md
Normal 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.
|
||||
5
docs/MPC/_committed_ot.md
Normal file
5
docs/MPC/_committed_ot.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Committed OT
|
||||
|
||||
// TODO here we describe our flavor of committed KOS
|
||||
// This page will be linked to from DEAP
|
||||
|
||||
5
docs/MPC/_dual_execution.md
Normal file
5
docs/MPC/_dual_execution.md
Normal 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
4
docs/MPC/_ectf.md
Normal 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
3
docs/MPC/_encodings.md
Normal 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
|
||||
1
docs/MPC/_garbled_circuits.md
Normal file
1
docs/MPC/_garbled_circuits.md
Normal file
@@ -0,0 +1 @@
|
||||
# Secure 2-Party Computation
|
||||
3
docs/MPC/_oblivious_transfer.md
Normal file
3
docs/MPC/_oblivious_transfer.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Oblivious Transfer
|
||||
|
||||
TODO
|
||||
16
docs/MPC/_tls_handshake.md
Normal file
16
docs/MPC/_tls_handshake.md
Normal 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
15
docs/MPC/commitments.md
Normal 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.
|
||||
|
||||
|
||||

|
||||
139
docs/MPC/deap.md
Normal file
139
docs/MPC/deap.md
Normal 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
77
docs/MPC/encryption.md
Normal 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
128
docs/MPC/ff-arithmetic.md
Normal 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
274
docs/MPC/mac.md
Normal 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^{m−1} ⊕ ... ⊕ X_{m−1}•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.**
|
||||
|
||||

|
||||
|
||||
#### 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.
|
||||
|
||||
209
docs/Protocol/commit_strategy.ipynb
Normal file
209
docs/Protocol/commit_strategy.ipynb
Normal file
File diff suppressed because one or more lines are too long
28
docs/Protocol/commit_strategy.md
Normal file
28
docs/Protocol/commit_strategy.md
Normal 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).
|
||||
24
docs/Protocol/mpc-tls/README.md
Normal file
24
docs/Protocol/mpc-tls/README.md
Normal 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. -->
|
||||
30
docs/Protocol/mpc-tls/encryption.md
Normal file
30
docs/Protocol/mpc-tls/encryption.md
Normal 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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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).
|
||||
19
docs/Protocol/mpc-tls/handshake.md
Normal file
19
docs/Protocol/mpc-tls/handshake.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Handshake
|
||||
|
||||

|
||||
|
||||
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`.
|
||||
18
docs/Protocol/notarization.md
Normal file
18
docs/Protocol/notarization.md
Normal 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.
|
||||
37
docs/Protocol/server_identity_privacy.md
Normal file
37
docs/Protocol/server_identity_privacy.md
Normal 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.
|
||||
21
docs/Protocol/verification.md
Normal file
21
docs/Protocol/verification.md
Normal 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).
|
||||
|
||||

|
||||
69
docs/_spec/notarized_session.md
Normal file
69
docs/_spec/notarized_session.md
Normal 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`
|
||||
|
||||
|
||||
|
||||
33
docs/_spec/verification_steps.md
Normal file
33
docs/_spec/verification_steps.md
Normal 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 -->
|
||||
|
||||

|
||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
116
docs/faq.mdx
Normal file
116
docs/faq.mdx
Normal 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. It’s 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 Server’s 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. TLSNotary’s 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
24
docs/glossary.md
Normal 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 | Rivest–Shamir–Adleman (public-key cryptosystem) |
|
||||
| TLS | transport layer security |
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Motivation
|
||||
|
||||
@@ -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_Diffie–Hellman). The resulting shared secret in TLS terms is **called the pre-master secret `PMS`**.
|
||||
|
||||
107
docs/notary_server.md
Normal file
107
docs/notary_server.md
Normal 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 host’s 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).
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_position: 3
|
||||
---
|
||||
# Quick Start
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
24
static/swagger-ui/notary_server_api.html
Normal file
24
static/swagger-ui/notary_server_api.html
Normal 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>
|
||||
|
||||
Reference in New Issue
Block a user