Skip to content
This repository has been archived by the owner on Jun 10, 2024. It is now read-only.

update core logic of notary, verifier and prover #2

Merged
merged 1 commit into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 40 additions & 60 deletions tlsn/examples/simple/README.md
Original file line number Diff line number Diff line change
@@ -1,90 +1,70 @@
## Simple Example: Notarize Public Data from example.com (Rust) <a name="rust-simple"></a>
# Simple Notarization

This example demonstrates the simplest possible use case for TLSNotary:
1. Notarize: Fetch <https://example.com/> and create a proof of its content.
2. Verify the proof.
This guide will take you through the steps of:
- starting a `Notary` server
- running a `Prover` to notarize some web data
- running a `Verifier` to verify the notarized data

Next, we will redact the content and verify it again:
1. Redact the `USER_AGENT` and titles.
2. Verify the redacted proof.
Note that the TLSNotary protocol assumes that the `Notary` is trusted by the `Verifier`. To minimize the trust, the `Verifier` itself can act as a `Notary`.

### 1. Notarize <https://example.com/>
## Preliminaries

Run a simple prover:
### Install rust

If you don't have `rust` installed yet, install it with [rustup](https://rustup.rs/):
```shell
cargo run --release --example simple_prover
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

If the notarization was successful, you should see this output in the console:
## Guide
Clone this repository first

```log
Starting an MPC TLS connection with the server
Got a response from the server
Notarization completed successfully!
The proof has been written to `simple_proof.json`
```shell
git clone https://github.com/tlsnotary/tlsn
```

⚠️ In this simple example the `Notary` server is automatically started in the background. Note that this is for demonstration purposes only. In a real work example, the notary should be run by a neutral party or the verifier of the proofs. Consult the [Notary Server Docs](https://docs.tlsnotary.org/developers/notary_server.html) for more details on how to run a notary server.

### 2. Verify the Proof

When you open `simple_proof.json` in an editor, you will see a JSON file with lots of non-human-readable byte arrays. You can decode this file by running:
### Start a simple Notary server:

```shell
cargo run --release --example simple_verifier
cd tlsn/tlsn/examples/simple
cargo run --release --example simple_notary
```

This will output the TLS-transaction in clear text:
The `Notary` server will now be running in the background waiting for connections from a `Prover`. You can switch to another console to run the `Prover`.

P/S: The notary server used in this example is less functional compared to its [advanced version](../../../notary-server). This simple version is easier to integrate with from prover perspective, whereas the advanced version provides additional features like TLS connection with prover, WebSocket endpoint, API endpoints for further customisation etc.

```log
Successfully verified that the bytes below came from a session with Dns("example.com") at 2023-11-03 08:48:20 UTC.
Note that the bytes which the Prover chose not to disclose are shown as X.
### Run a simple Prover:

Bytes sent:
...
```shell
RUST_LOG=DEBUG,yamux=INFO cargo run --release --example simple_prover
```

### 3. Redact Information
The notarization session usually takes a few moments and the resulting proof will be written to the "proof.json" file. The proof can then be passed on to the `Verifier` for verification.

Open `simple/src/examples/simple_prover.rs` and locate the line with:
The `simple_prover` notarizes <https://example.com> and redacts the `USER_AGENT` HTTP header from the proof for the `Verifier`. You can change the code in `tlsn/tlsn/examples/simple/simple_prover.rs` to meet your needs:

```rust
let redact = false;
```
- change which server the `Prover` connects to
- add or remove HTTP request headers
- redact other strings in the request or the response

and change it to:
⚠️ Please note that by default the `Notary` server expects that the cumulative size of the request and the server response is not more than 16KB.

```rust
let redact = true;
```

Next, if you run the `simple_prover` and `simple_verifier` again, you'll notice redacted `X`'s in the output:
### Run a simple Verifier:

```shell
cargo run --release --example simple_prover
cargo run --release --example simple_verifier
```

```log
<!doctype html>
<html>
<head>
<title>XXXXXXXXXXXXXX</title>
...
```

You can also use <https://tlsnotary.github.io/proof_viz/> to inspect your proofs. Simply drag and drop `simple_proof.json` from your proof file explorer into the drop zone. Redacted bytes are marked with <span style="color:red">red Xs characters</span>.

### (Optional) Extra Experiments

Feel free to try these extra challenges:

- [ ] Modify the `server_name` (or any other data) in `simple_proof.json` and verify that the proof is no longer valid.
- [ ] Modify the `build_proof_with_redactions` function in `simple_prover.rs` to redact more or different data.

### Next steps

Try out the [Discord example](../Discord/README.md) and notarize a Discord conversations.

This will verify the proof from the `simple_prover` (`proof.json`) and output the result to the console.

Note how the parts which the prover chose not to disclose will be shown as "X":
```plaintext
GET / HTTP/1.1
host: example.com
accept: */*
accept-encoding: identity
connection: close
user-agent: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```
5 changes: 5 additions & 0 deletions tlsn/examples/simple/keys/notary.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgEvBc/VMWn3E4PGfe
ETc/ekdTRmRwNN9J6eKDPxJ98ZmhRANCAAQG/foUjhkWzMlrQNAUnfBYJe9UsWtx
HMwbmRpN4cahLMO7pwWrHe4RZikUajoLQQ5SB/6YSBuS0utehy/nIfMq
-----END PRIVATE KEY-----
4 changes: 4 additions & 0 deletions tlsn/examples/simple/keys/notary.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBv36FI4ZFszJa0DQFJ3wWCXvVLFr
cRzMG5kaTeHGoSzDu6cFqx3uEWYpFGo6C0EOUgf+mEgbktLrXocv5yHzKg==
-----END PUBLIC KEY-----
58 changes: 58 additions & 0 deletions tlsn/examples/simple/simple_notary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/// This is a simple implementation of the notary server with minimal functionalities (without TLS, does not support WebSocket and configuration etc.)
/// For a more functional notary server implementation, please use the notary server in `../../notary-server`
use p256::pkcs8::DecodePrivateKey;
use std::env;

use tokio::net::TcpListener;
use tokio_util::compat::TokioAsyncReadCompatExt;

use tlsn_verifier::tls::{Verifier, VerifierConfig};
const SESSION_ID: &str = "example";

const NOTARY_SIGNING_KEY_PATH: &str = "./keys/notary.key";

#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();

// Allow passing an address to listen on as the first argument of this
// program, but otherwise we'll just set up our TCP listener on
// 127.0.0.1:8080 for connections.
let addr = env::args()
.nth(1)
.unwrap_or_else(|| "127.0.0.1:8080".to_string());

// Next up we create a TCP listener which will listen for incoming
// connections. This TCP listener is bound to the address we determined
// above and must be associated with an event loop.
let listener = TcpListener::bind(&addr).await.unwrap();

println!("Listening on: {}", addr);

// Load the notary signing key
let signing_key =
p256::ecdsa::SigningKey::read_pkcs8_pem_file(NOTARY_SIGNING_KEY_PATH).unwrap();

loop {
// Asynchronously wait for an inbound socket.
let (socket, socket_addr) = listener.accept().await.unwrap();

println!("Accepted connection from: {}", socket_addr);

{
let signing_key = signing_key.clone();

// Spawn notarization task to be run concurrently
tokio::spawn(async move {
// Setup default config. Normally a different ID would be generated
// for each notarization.
let config = VerifierConfig::builder().id(SESSION_ID).build().unwrap();

Verifier::new(config)
.notarize::<_, p256::ecdsa::Signature>(socket.compat(), &signing_key)
.await
.unwrap();
});
}
}
}
Loading
Loading