Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doc/gateway #19

Merged
merged 6 commits into from
Sep 30, 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
71 changes: 70 additions & 1 deletion docs/fundamentals/fhevm/inputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Therefore, we employ zero-knowledge proofs of knowledge (ZKPoK) of input FHE cip
* the user knows the plaintext value
* the input ciphertext can only be used in a particular smart contract

The ZKPoK is verified by validator nodes when the input byte array is passed to an `TFHE.asEuintXX()` function to convert from a ciphertext to a handle that can be used in smart contracts for FHE operations.
The ZKPoK is verified by the KMS which delivers a signature (KMS_S) to the user. When the input byte array is passed to an `TFHE.asEuintXX()` function to convert from a ciphertext to a handle that can be used in smart contracts for FHE operations, the KMS_S is verified.

## Compact Input Lists

Expand Down Expand Up @@ -44,3 +44,72 @@ contract Adder {
```

Note that `inputProof` also contains the ZKPoK.


## Overview of input mechanism

Handling inputs requires a few steps. The first one is to retrieve public key material from the Gateway. The second point is to encrypt them and computing the associated proof. Last step is to use them as "usual" inputs in the smart contract.

### Public key material and CRS retrieval

The very first step to prepare input is to have the blockchain related public key material. The Gateway is the component reached by the user to get those material.

The Gateway is exposing a `/keys` endpoint that returns the public key and CRS alongside the signature. Users are able to verify them using KMSVerifier smart contract.



### Initialization phase

In this first part we need to encrypt the input with the blockchain public key to get the `ciphertext` `C`, and compute the `ZkPok`. `C`
is bounded to be used with a `contractAddress` and by a `callerAddress`. The goal is to make it signed by the KMS to enable the usage of the input
within smart contract further.

C == ciphertext - Encrypted with the blockchain public key

ZkPok == Zero-knowledge proof - Computed on client side as proof of knowledge of input

eInput == types + index

S == Signature

struct CVerificationStructForKMS {
address contractAddress;
bytes32 hashOfCiphertext;
address callerAddress;
}


```mermaid
sequenceDiagram
participant User
participant Gateway
participant KMS_BC as KMS BC
participant KMS_Core as KMS Core

User->>Gateway: 1. (C, contractAddr, callerAddr, ZKPoK)
Gateway->>KMS_BC: 2. VerifyInput(C, contractAddr, callerAddr, ZKPoK)
KMS_BC->>KMS_Core: 3. VerifyInput(C, contractAddr, callerAddr, ZKPoK)
Note over KMS_Core: 4. Verify ZkPoK
Note over KMS_Core: 5. KMS_S = Sign(CVerificationStructForKMS)
KMS_Core->>KMS_BC: 6. KMS_S
KMS_BC->>Gateway: 7. KMS_S
Gateway->>User: 8. KMS_S

```

### Usage

The user has received the KMS signature, this means that the proof has been verified and the input could be legitimately used within fhEVM.
This is quite useful because in fhEVM, only the KMS signature will be verified which is faster than verifying a ZkPoK proof.

```mermaid
sequenceDiagram
participant User
participant fhEVM

User->>fhEVM: (eInput, C, KMS_S)
Note over fhEVM: Reconstruct CVerificationStructFromKMS
Note over fhEVM: Verify KMS_S


```
Binary file added docs/fundamentals/gateway/asyncDecrypt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions docs/fundamentals/gateway/decryption.md
Original file line number Diff line number Diff line change
@@ -1 +1,30 @@
# Decryption

Everything in fhEVM is encrypted, at some point one could need to decrypt somes values. Let's give as illustration a blind auction application.
After reaching the end of the auction, one need to discover (only) the winner, here is where a asynchronous decrypt could appear.


> :warning: **Decryption is public**: It means everyone will be able to see the value. If this is a personal information see [Reencryption](./reencryption.md)

## How it's working

The Gateway acts as an oracle service: it will listen to decryption request events and return the decrypted value through a callback function.
The responsabilities of the Gateway are:
- Listening decryption request from fhEVM that contains a handle `h` that corresponds to a ciphertext `C`
- Computing a storage proof `P` to attest h (i.e. C) is decryptable
- Retrieve C from fhEVM using `h` as key
- Send a decyption request to TKMS which in turn is running an internal blockchain aka `KMS BC`
- Wait and listen for `decyptionResponse` (containing the plaitext and a few signatures from KMS to attest the integrity of the palintext) event from `KMS BC`
- Return `decyptionResponse` through the callback function

## High level overview of the decryption flow

We allow explicit decryption requests for any encrypted type. The values are decrypted with the network private key.

![](asyncDecrypt.png)






14 changes: 13 additions & 1 deletion docs/fundamentals/gateway/proof.md
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
# Inclusion proof
# Inclusion Proof

The execution layer in fhEVM can perform computations on ciphertexts. At some point, it becomes necessary to reveal the actual values of these ciphertexts. However, the private key is managed by the KMS (Key Management System). The question arises: how can we perform asynchronous decryption requests (which make the values public) and re-encryptions (for personal information) when the execution layer and the KMS are decoupled?
This is where inclusion proofs come into play.


## How to Compute an Inclusion Proof

## Verification of the Proof in KMS BC ISC

## Notes on Root Hash Verification

This section will be elaborated upon in the future to explain the validation of root hash integrity.
8 changes: 8 additions & 0 deletions docs/fundamentals/gateway/reencryption.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# Reencryption


Reencryption is performed on the client side by calling the gateway service using the [fhevmjs](https://github.com/zama-ai/fhevmjs/) library. To do this, you need to provide a view function that returns the ciphertext to be reencrypted.

1. The dApp retrieves the ciphertext from the view function (e.g., balanceOf).
2. The dApp generates a keypair for the user and requests the user to sign the public key.
3. The dApp calls the gateway, providing the ciphertext, public key, user address, contract address, and the user's signature.
4. The dApp decrypts the received value with the private key.
76 changes: 76 additions & 0 deletions docs/getting_started/gateway/configuration.md
Original file line number Diff line number Diff line change
@@ -1 +1,77 @@
# Configuration

The gateway acts as a bridge between the execution layer and the Threshold Key Management System (TKMS). Due to its central role, it needs to be properly configured. This document details all
the environment variables and gives an example of docker compose to run the gateway.

## Dependencies

- **Zama Gateway**: Depends on **fhEVM** and **Gateway KV Store**, which is initialized with the **Zama KMS** Docker Compose command. Therefore, this is the _last_ Docker Compose command that should be run.

## Prerequisites

- **Docker 26+** installed on your system.
- **fhEVM** validator running and configured.
- **TKMS** running and configured.

## Configuring Docker Compose Environment Variables

### Example Docker Compose for Zama Gateway

```yaml
name: zama-gateway

services:

gateway:
image: ghcr.io/zama-ai/kms-blockchain-gateway-dev:latest
command:
- "gateway"
environment:
- GATEWAY__ETHEREUM__CHAIN_ID=9000
- GATEWAY__ETHEREUM__LISTENER_TYPE=FHEVM_V1_1
- GATEWAY__ETHEREUM__WSS_URL=ws://fhevm-validator:8546
- GATEWAY__ETHEREUM__HTTP_URL=http://fhevm-validator:8545
- GATEWAY__ETHEREUM__FHE_LIB_ADDRESS=000000000000000000000000000000000000005d
- GATEWAY__ETHEREUM__ORACLE_PREDEPLOY_ADDRESS=c8c9303Cd7F337fab769686B593B87DC3403E0ce
- GATEWAY__KMS__ADDRESS=http://kms-validator:9090
- GATEWAY__KMS__KEY_ID=408d8cbaa51dece7f782fe04ba0b1c1d017b1088
- GATEWAY__STORAGE__URL=http://gateway-store:8088
- ASC_CONN__BLOCKCHAIN__ADDRESSES=http://kms-validator:9090
- GATEWAY__ETHEREUM__RELAYER_KEY=7ec931411ad75a7c201469a385d6f18a325d4923f9f213bd882bbea87e160b67
```

**Zama Gateway** requires several specific configurations as shown in the provided `docker-compose-gateway.yml` file.

| Variable | Description | Default Value |
| --- | --- | --- |
| GATEWAY__ETHEREUM__CHAIN_ID | Chain ID for fhEVM | 9000 |
| GATEWAY__ETHEREUM__LISTENER_TYPE | Listener type for Ethereum gateway | FHEVM_V1_1 |
| GATEWAY__ETHEREUM__WSS_URL | WebSocket URL for fhEVM Ethereum. You need to run fhEVM first and set this data | ws://localhost:9090 |
| GATEWAY__ETHEREUM__FHE_LIB_ADDRESS | FHE library address for Ethereum gateway. This should be obtained from fhEVM once it is running and configured | 000000000000000000000000000000000000005d |
| GATEWAY__ETHEREUM__ORACLE_PREDEPLOY_ADDRESS | Oracle predeploy contract address for fhEVM gateway | c8c9303Cd7F337fab769686B593B87DC3403E0cd |
| GATEWAY__KMS__ADDRESS | Address for KMS gateway | http://localhost:9090 |
| GATEWAY__KMS__KEY_ID | Key ID for KMS gateway. Refer to the [How to Obtain KMS Key ID](#kms-key-id) section | 04a1aa8ba5e95fb4dc42e06add00b0c2ce3ea424 |
| GATEWAY__STORAGE__URL | URL for storage gateway | http://localhost:8088 |
| ASC_CONN__BLOCKCHAIN__ADDRESSES | Blockchain addresses for ASC connection. Same as `GATEWAY__KMS__ADDRESS` | http://localhost:9090 |
| GATEWAY__ETHEREUM__RELAYER_KEY | Private key of the relayer | 7ec931411ad75a7c201469a385d6f18a325d4923f9f213bd882bbea87e160b67 |

## Steps for Running

1. Run the **Zama Gateway** Docker Compose:

```bash
docker compose -f docker-compose-gateway.yml up -d
```

> :warning: **Requirement**: At start, the Gateway will try to connect to the websocker URL `GATEWAY__ETHEREUM__WSS_URL`. Ensure it is running and the port is opened.

## KMS Key ID

To obtain the `Key ID` for the `GATEWAY__KMS__KEY_ID` environment variable, run the following command:

```bash
> docker run -ti ghcr.io/zama-ai/kms-service-dev:latest ls keys/PUB/PublicKey
04a1aa8ba5e95fb4dc42e06add00b0c2ce3ea424 8e917efb2fe00ebbe8f73b2ba2ed80e7e28970de
```


98 changes: 97 additions & 1 deletion docs/references/gateway_api.md
Original file line number Diff line number Diff line change
@@ -1 +1,97 @@
# Gateway API specifications
# Gateway API Specifications

## Endpoints

<details>
<summary>GET /keys ---- Retrieve public key, CRS (for input proof) and bootstrap key files download URLs</summary>

#### Description

This endpoint returns a JSON object containing URLs from an S3 bucket, allowing the client to download key files such as the blockchain public key, CRS files for input proof generation, and the bootstrap key.

For each file, a list of cryptographic signatures is provided to ensure the integrity and authenticity of the downloaded content. These signatures are generated using a threshold signature scheme. This means that instead of needing all the signatures to validate the content, only a subset—specifically one-third of the total signatures (if n nodes are signing)—is required to verify that the content is legitimate.

No query parameters are required, as the gateway is already preconfigured for a specific blockchain.



#### Query Parameters

No parameters.

#### Headers

None.

#### Response

**Success (200 OK)**

The request is successful, and the response will include a JSON object with the following structure:

```json
{
"keyId": "ab12cd",
"crsId": "34ef67",
"publicKey": {
"url": "https://s3.amazonaws.com/bucket-name/pubkey",
"signatures": [
"a5d2...",
"a8cd...",
"c0ff..."
]
},
"bootstrapKey": {
"url": "https://s3.amazonaws.com/bucket-name/bootstrapkey",
"signatures": [
"fd7a...",
"487b...",
"20fe..."
]
},
"crs": {
"2048": {
"url": "https://s3.amazonaws.com/bucket-name/crs",
"signatures": [
"ffee...",
"012f...",
"1ab5..."
]
}
}
}
```

**Error Responses**

| Status Code | Error Code | Description |
| ----------- | ------------ | ------------------------------------------------ |
| 400 | `BadRequest` | The request is invalid or missing required parameters. |
| 404 | `NotFound` | The requested resource was not found. |
| 500 | `ServerError` | An internal server error occurred. |

#### Example Error Responses

```json
{
"error": "BadRequest",
"message": "The request is invalid or missing required parameters."
}
```

```json
{
"error": "NotFound",
"message": "The requested resource was not found."
}
```

```json
{
"error": "ServerError",
"message": "An internal server error occurred. Please try again later."
}
```

</details>