Skip to content

Commit

Permalink
Taiga overview big update (#126)
Browse files Browse the repository at this point in the history
* Restructure, update the old sections

* Deprecate the blinding section and lots of other stuff

* Add more diagrams, remove the old diagrams, and update the old ones

* Add intent app section, extract intents from the exec model, update examples

* Update readme
  • Loading branch information
vveiln authored Mar 10, 2023
1 parent f3ae814 commit 36b96e6
Show file tree
Hide file tree
Showing 69 changed files with 690 additions and 1,101 deletions.
33 changes: 6 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,18 @@
# Taiga

Taiga is a framework for generalized shielded state transitions. This repository contains the implementation of Taiga in Rust. It is a WIP project and cannot be used in production yet.
Taiga is a framework for generalized shielded state transitions.
This repository contains the implementation of Taiga in Rust.

## Specifications
⚠️ It is a WIP project and cannot be used in production yet ⚠️

- [How Taiga works (with code examples)](./book/src/SUMMARY.md)
- [Cryptographic details of Taiga](./book/src/spec.md)
- [Current performance details](./book/src/conclusion.md)
- Choice of ZK-proof implementation. Currently, we use the [PLONK](https://github.com/ZK-Garage/plonk) implementation of [ZK-Garage](https://github.com/ZK-Garage/). The current choice of proof system is not final and might change, as well as the curves we chose:
* The main curve is `bls12_381_new`, a different curve from the well-known `bls12_381`. Poseidon hash circuits are small for the base field and the scalar field of this curve.
* The inner curve is `ed_on_bls12_381_new`. Its base field is the main curve scalar field and it has a small degree endomorphism enabling faster scalar multiplications compared to `ed_on_bls12_381`.
* The outer curve is `bw6_764_new`. Its scalar field is the base field of the main curve.


## How to run
### Taiga overview & specification

### The Taiga book

To generate the Taiga [book](./book/src/SUMMARY.md), run:
* To access the Taiga overview, run
```
cd book
mdbook serve --open
```

### Validity predicate examples

We provide [several VP examples](./src/circuit/vp_examples/). To generate VP example proofs and verify them, run:
```
cargo test vp_example --release
```

## Things yet to implement

* Blake2 hash circuits and all of the proofs that use blake2s
* The main curve base field Poseidon hash circuit
* Proper note encryption
* Proper blinding algorithm
* You can find the specification of Taiga [here](./book/src/spec.md).

2 changes: 1 addition & 1 deletion book/book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
language = "en"
multilingual = false
src = "src"
title = "Taiga documentation"
title = "Taiga Design Overview"

[output.html]

Expand Down
20 changes: 11 additions & 9 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Taiga
# Taiga Overview

- [Taiga overview](./overview.md)
- [Validity predicates](./validity-predicates.md)
- [Applications](app.md)
- [Users](./users.md)
- [Introduction](./intro.md)
- [Applications](./app.md)
- [Notes](./notes.md)
- [Action](./action.md)
- [Blinding](./blinding.md)
- [Transaction](./transaction.md)
- [Performance & conclusion](./conclusion.md)
- [Validity predicates](./validity-predicates.md)
- [The Action circuit](./action.md)
- [Execution model](./exec.md)
- [Intent Application](./intent.md)
- [Examples](./exec_examples.md)
- [Performance](./performance.md)
- [Technical specification draft](./spec.md)


43 changes: 17 additions & 26 deletions book/src/action.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
# Action
# The Action circuit

The action is a mechanism that allows a user to spend or create [notes](notes.md) by proving the right to do so using ZK proofs.
The Action circuit is a mechanism that ensures that the proposed state transitions follow the Taiga rules.
Unlike validity predicates, the Action circuit checks don't depend on the applications involved and are the same for all transactions.

## Spending a note
As an application state is contained in notes, and a state transition is represented as spending the old notes and creating new ones,
the Action circuit checks the correctness of the old state by checking properties of the old notes and the correctness of the new state by checking the properties of the new notes.

To spend a note, the users need to prove that they are allowed to do so, namely:
- To make sure that the correct `AppVP` is checked, prove the relationship between `app_VK` and the application field in the spent note.
![img_3.png](img/action_img_3.png)
- To make sure the correct `SendVP`(read more about `SendVP` [here](./users.md)) is checked, prove the relationship between `send_VK` and the owner field in the spent note.
- Compute the nullifier of the spent note (using the nullifier key `nk`) so that it cannot be double-spent. To make sure that the nullifier is computed correctly, prove the relationship between `nk` and the owner field in the spent note.
### Check the old state (spent notes)

![img_1.png](img/action_img_1.png)
For spent notes, the Action circuit checks that:
* the note existed before (can you spend a note that doesn't exist?),
* the note haven't been spent yet,
* the spender has a right to spend it (do you own the note?),
* and that the application the note belongs to approves the action (sure there is some application approves the check, but is it the one the note belongs to?).

## Creating a note
### Check the new state (created notes)

To create a note, the user also needs to prove the right to do so. `AppVP` must allow the creation of the note, as well as recipient user's `RecvVP`:
For the notes being created, the Action circuit checks that:
* the correct application approves it (same check as for spent notes)
* and the note commitment is derived correctly (the thing that makes everyone to know that the note exists must indeed represent the note)
* if the note is encrypted, check the encryption correctness (will the owner be able to decrypt it?)

- To make sure that the correct `AppVP` is checked, prove the relationship between `app_VK` and the application field in the note to be created.
![img_4.png](img/action_img_4.png)

- To make sure the correct `RecvVP` is checked (read more about `RecvVP` [here](./users.md)), prove the relationship between `recv_VK` and the owner field of the note to be created.
![img.png](img/action_img.png)

- To make sure that the [note](./notes.md) commitment `cm` is derived correctly, prove the relationship between `cm`, the note, and the receiver of the note

![img_2.png](img/action_img_2.png)

To see a more detailed description of the action circuit checks, see the [specification](./spec.md). See also the [action implementation](https://github.com/anoma/taiga/blob/main/src/action.rs) and the [action circuit implementation](https://github.com/anoma/taiga/blob/main/src/circuit/action_circuit.rs) for more details.

To ensure full privacy, we use [blinding](./blinding.md) to hide the verifier keys.

Next: [blinding](./blinding.md)
To learn in details about the checks the Action circuit performs, check the [technical specification of Taiga](./spec.md).
63 changes: 21 additions & 42 deletions book/src/app.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,33 @@
# Application

`App` define the type of note (e.g. XAN, ETH, BTC). Each application is identified by an address `appAddress` (the same way as user address identifies a user) and has its own VP `AppVP`.
### Application logic
Application VP is the defining structure of an application that contains the application logic.
Every time the application state is about to change, the application VP is called to validate the state transition.
If the application VP doesn't consider a state transition valid, the state will not be changed.

### Application VP
Each application has its own [validity predicate](./validity-predicates.md) `AppVP` that defines the conditions on which the application can be sent/received/etc (e.g. whitelist VP that only allows using the application a specified set of users). As with other VPs, `AppVP` checks that input and output notes of the tx satisfy certain constraints.
It is required that the `AppVP` of the applications involved in a tx evaluated to `true`.
An application VP might require validity of other VPs, enforcing the VP hierarchy with the application VP being the main VP checked.

In Taiga, VPs are shielded, so instead of showing that `AppVP` evaluates to `true` publicly, a ZK proof is created. To make sure that `AppVP` evaluates to `true`, an observer can verify the proof (using the verifier key):
#### Application address
Each application has a unique application identifier that we call an address. The application address is derived from its application VP.

```verify(AppVP_proof, app_VK) = True```
### Application state
As Taiga works in the UTXO model, application states are stored in notes, and changing the application state is done by spending the old application state notes and creating new application state notes.

### Application Address
Each app is identified by an address that is derived from its verifier key `app_VK`:
`appAddress = Com(app_VK)`
The application a note belongs to is indicated by the note's type which is derived using the application address, binding the note with the application.
One application can have notes of multiple types, all of which are derived using the application address and some additional information that helps to distinguish the note types.
Notes of distinct types are independent of each other, unless explicitly designed otherwise.

![img.png](images/app_note_with_multiple_types.png)

### Example
##### Create a application
In order to create a application, we need `AppVP`. Let's use the `TrivialValidityPredicate` (see [more](./validity-predicates.md)):
```rust
let mut app_vp = TrivialValidityPredicate::<CP> {
input_notes,
output_notes,
};
#### Shielded applications
All applications in Taiga are shielded, which means that the application VP of each application is hidden, the notes containing application states are encrypted,
and the produced transactions don't reveal any information about the applications they change the state of.

// transform the VP into a short form
let desc_vp = ValidityPredicateDescription::from_vp(&mut app_vp, &vp_setup).unwrap();
![img.png](images/app_intro.png)

let app = App::<CP>::new(desc_vp);
#### Are Taiga applications similar to Ethereum applications?

//app address can be used to create notes of that app;
let app_address = app.address().unwrap();
```
This example is reproducible with [this file](https://github.com/anoma/taiga/blob/main/src/doc_examples/app.rs) or with the command
```
cargo test doc_examples::app::test_app_creation
```
In some sense, Taiga applications are similar to Ethereum applications, but there are two key distinctions that come to mind:
* Ethereum uses smart contracts when Taiga uses validity predicates to describe the application logic (learn more about the difference [here](https://github.com/anoma/whitepaper/blob/main/whitepaper.pdf), page 3)
* Taiga applications are shielded by default, but can be defined separately over the transparent pool as well. The shielded and transparent parts of the application can interact with each other, but whatever happens in Taiga is always shielded

#### Dummy app

It is also possible to create a dummy app without VP:

```rust
let app = App::<CP>::dummy(&mut rng)
```

Using this app, we can create a [dummy note](./notes.md) of a specific app (all other fields are random):

```rust
let note = Note::<CP>::dummy_from_app(app, rng)
```

Next: [User](./users.md)
51 changes: 0 additions & 51 deletions book/src/blinding.md

This file was deleted.

80 changes: 0 additions & 80 deletions book/src/conclusion.md

This file was deleted.

13 changes: 13 additions & 0 deletions book/src/deprecated/blinding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Blinding

To verify a proof, a user needs something called **verifier key**. Verifier key is derived from the circuit and whoever has this key can verify the proof.

![img_1.png](../images/blinding_img_1.png)

However, verifier key leaks some information about the circuit which we don't want to reveal, so we use blinding to protect the key.

To blind the verifier key, we add to it some random data that vanishes at the right moment (thanks to the math). Using randomized verifier keys helps to hide the actual verifier key and break the link between the usages.
![img.png](../images/blinding_img2.png)

To make sure that the blinded key corresponds to the actual verifier key, the correctness of the blinding must be proven and verified.
![img.png](../images/blinding_img3.png)
Loading

0 comments on commit 36b96e6

Please sign in to comment.