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

feat/code review #141

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 0 additions & 12 deletions .github/workflows/contracts-checks.yml
Expand Up @@ -32,29 +32,17 @@ jobs:

# Generate modules

- name: Run generate-plonk
run: pnpm contracts generate-plonk

- name: Run generate-groth16
run: pnpm contracts generate-groth16

- name: Run generate-poseidon
run: pnpm contracts generate-poseidon

- name: Run generate-merkle
run: pnpm contracts generate-merkle

# Test modules

# - name: Run test-plonk
# run: pnpm contracts test-plonk

- name: Run test-groth16
run: pnpm contracts test-groth16

- name: Run test-poseidon
run: pnpm contracts test-poseidon

- name: Run test-merkle
run: pnpm contracts test-merkle

Expand Down
2 changes: 0 additions & 2 deletions .gitignore
Expand Up @@ -20,7 +20,6 @@ wip
/tests/*.js
.pact-history
.draft
lib*.repl
*.env
**/.env
**/node_modules
Expand All @@ -35,7 +34,6 @@ out
out_tests
.pact-history
.draft
lib*.repl
*.env
**/.env
**/node_modules
Expand Down
86 changes: 55 additions & 31 deletions contracts/README.md
@@ -1,46 +1,59 @@
## Overview

This project contains modules for three zero-knowledge proof technologies: `Groth16`, `Plonk`, and `Merkle Tree`. Each module includes code dynamically generated with EJS templates from input data in `.json` files.
This project contains modules for three zero-knowledge proof technologies: `Gas Payer',` `Groth16`, `Merkle Tree` and `Transact`. Some modules include code dynamically generated with EJS templates from input data in `.json` files.

Below is the project structure and a brief description of each module:

## Project structure
```markdown
.
├── groth16-verifier # Groth16 verifier module
│ ├── src # Source code for the Groth16 verifier
│ │ ├── ejs # EJS templates for generating Groth16 verifier code
│ │ │ ├── lib.ejs.repl # EJS template file
├── gas-payer # Gas payer module
│ ├── gas-payer-v1.pact # Source code for gas payer interface
│ ├── opact-gas-station.pact # Source code for gas payer implementation

├── groth16-verifier # Groth16 verifier module
│ ├── src # Source code for the Groth16 verifier
│ │ ├── ejs # EJS templates for generating Groth16 verifier code
│ │ │ ├── lib.ejs.repl # EJS template file
│ │ │ └── sample.verifier.json
│ │ └── lib.repl # Groth16 verifier code, generated from EJS template
│ └── tests # Test scripts for the Groth16 verifier
│ │ └── lib-1x2.repl # Used for 1x2 circuit (1 input, 2 outputs)
│ │ └── lib-2x2.repl # Used for 2x2 circuit (2 inputs, 2 outputs)
│ │ └── lib-3x2.repl # Used for 3x2 circuit (3 inputs, 2 outputs)
│ │ └── lib-4x2.repl # Used for 4x2 circuit (4 inputs, 2 outputs)
│ │ └── lib-5x2.repl # Used for 5x2 circuit (5 inputs, 2 outputs)
│ │ └── lib-6x2.repl # Used for 6x2 circuit (6 inputs, 2 outputs)
│ │ └── lib-7x2.repl # Used for 7x2 circuit (7 inputs, 2 outputs)
│ │ └── lib-8x2.repl # Used for 8x2 circuit (8 inputs, 2 outputs)
│ │ └── lib-9x2.repl # Used for 9x2 circuit (9 inputs, 2 outputs)
│ │ └── lib-10x2.repl # Used for 10x2 circuit (10 inputs, 2 outputs)
│ └── tests # Test scripts for the Groth16 verifier
│ └── groth16-tests.repl
├── plonk-verifier # Plonk verifier module
│ ├── src # Source code for the Plonk verifier
│ │ ├── ejs # EJS templates for generating Plonk verifier code
│ │ │ ├── lib.ejs.repl # EJS template file
│ │ │ └── sample.verifier.json
│ │ └── lib.repl # Plonk verifier code, generated from EJS template
│ └── tests # Test scripts for the Plonk verifier
│ └── plonk-tests.repl
├── merkle-tree # Merkle tree module
│ └── src # Source code for the Merkle tree
│ ├── ejs # EJS templates for generating Merkle tree code

├── merkle-tree # Merkle tree module
│ └── src # Source code for the Merkle tree
│ ├── ejs # EJS templates for generating Merkle tree code
│ │ ├── data.json
│ │ └── merkle-tree.ejs.repl # EJS template file
│ ├── lib.repl # Merkle tree code, generated from EJS template
├── package.json # Project metadata and dependencies
├── pnpm-lock.yaml # Exact version of your dependencies. Don't edit this file directly.
└── README.md # Project description and instructions
│ │ └── merkle-tree.ejs.repl # EJS template file
│ └── lib.repl # Merkle tree implementation code, generated from EJS template.

├── transact # Transact module
│ ├── src
│ │ ├── contract.pact # Source code for the Transact contract
│ └── tests # Test scripts for the Groth16 verifier
│ └── Kip # Reference source code for the KIP contract, used for testing.
│ └── transact-tests.repl # Test scripts for the Transact contract, simulating a deposit and withdrawal.
├── package.json # Project metadata and dependencies
├── pnpm-lock.yaml # Exact version of your dependencies. Don't edit this file directly.
└── README.md # Project description and instructions
```

### Groth16 Verifier
### Gas Payer

Groth16 is a zero-knowledge proof scheme, which allows a party to prove that they have knowledge of certain information without revealing that information. This scheme is widely used in privacy-centric applications and is efficient in terms of proof size and verification time. In this module, we use EJS templates to generate the Groth16 verifier code dynamically. The `lib.ejs.repl` file is the template and the `sample.verifier.json` file contains input data for this template. The generated code is stored in the `lib.repl` file.
The gas payer module contains the source code for the gas payer interface and its implementation. The gas payer is a smart contract that allows users not to pay for gas when they interact with the Opact contract, because the gas payer contract pays for the gas on behalf of the user. The `gas-payer-v1.pact` file contains the source code for the gas payer interface, and the `opact-gas-station.pact` file contains the source code for the gas payer implementation.

### Plonk Verifier
### Groth16 Verifier

Plonk is another zero-knowledge proof scheme, which is quite efficient and versatile. It has been adopted for various privacy and scaling solutions in the blockchain space. Similar to the Groth16 module, we use an EJS template (`lib.ejs.repl`) and input data (`sample.verifier.json`) to generate the Plonk verifier code, which is stored in the `lib.repl` file.
Groth16 is a zero-knowledge proof scheme, which allows a party to prove that they have knowledge of certain information without revealing that information. This scheme is widely used in privacy-centric applications and is efficient in terms of proof size and verification time. In this module, we use EJS templates to generate the Groth16 verifier code dynamically. The `lib.ejs.repl` file is the template and the `sample.verifier.json` file contains input data for this template. The generated code is stored in the `lib.repl` file.

### Merkle Tree

Expand Down Expand Up @@ -72,15 +85,27 @@ Then for each contract:

Specifically, for each module:
- `groth16-verifier`: We run `generate-groth16` and `test-groth16`.
- `plonk-verifier`: We run `generate-plonk` and `test-plonk`.
- `merkle-tree`: We run `generate-merkle`.

## Generate the contract code

To generate the contract code, we use the `contracts` command of the `pnpm` package manager. To generate the Groth16 verifier and Merkle Tree code, we run the following commands:

```bash
pnpm contracts generate-groth16
pnpm contracts generate-merkle
```

The output of the generated files is already available in this repository within the `src` part of each respective folder. Each file starting with `lib` is the generated file from the EJS template.

## Run the test

The unit tests for each module are placed in the `tests` directory. For example, in order to test the Plonk verifier, we run the following command:
The unit tests for each module are placed in the `tests` directory. In order to test the contracts, we run the following command:

```bash
pnpm contracts test-plonk
pnpm contracts test-groth16
pnpm contracts test-merkle
pnpm contracts test-transact
```

If everything went well, you should see the following output:
Expand All @@ -92,7 +117,6 @@ Load successful
If any test fails, you should see something like this:

```bash
plonk-verifier/tests/plonk-tests.repl:7:0:ExecError: FAILURE: verify: expected {"paired": true}:object:*, received {"paired": false}:object:*
Load failed
```

Expand Down
40 changes: 37 additions & 3 deletions contracts/gas-payer/opact-gas-station.pact
@@ -1,40 +1,74 @@
(namespace 'free)

(module opact-gas-station GOVERNANCE
@doc
"This module, is designed to manage gas payments for transactions on the blockchain. \
\ It ensures that only authorized users (typically admin) can update the smart contract. \
\ The module implements a gas payment system, following the gas-payer-v1 interface, to handle transaction fees."

(defcap GOVERNANCE ()
"makes sure only admin account can update the smart contract"
@doc
"Capability ensuring that only the admin account can update the smart contract. \
\ This is a governance measure to maintain control over the module's functionality."

(enforce-keyset "free.opact-admin")
)

(implements gas-payer-v1)
(use coin)

(defschema gas
@doc
"Schema defining the structure for gas accounting. \
\ It includes the balance of gas available and the guard for security, \
\ governing who can access and use the gas."

balance:decimal
guard:guard)

(deftable ledger:{gas})

(defcap GAS_PAYER:bool
( user:string
( user:string
limit:integer
price:decimal
)
@doc
"Capability defining the conditions under which a user can pay for gas. \
\ It checks for specific transaction types and ensures that only cals from free.opact are allowed."

(enforce (= "exec" (at "tx-type" (read-msg))) "Inside an exec")
(enforce (= 1 (length (at "exec-code" (read-msg)))) "Tx of only one pact function")
(enforce (= "(free.opact" (take 11 (at 0 (at "exec-code" (read-msg))))) "only opact smart contract")
(compose-capability (ALLOW_GAS))
)

(defcap ALLOW_GAS () true)
(defcap ALLOW_GAS ()
@doc
"An unparameterized capability that allows for gas usage. \
\ It always returns true, signifying that gas allowance is granted."

true)

(defun create-gas-payer-guard:guard ()
@doc
"Function to create a guard for a coin account that can pay gas. \
\ This utilizes the custom gas-payer-guard to ensure proper control and authorization for gas payment."

(create-user-guard (gas-payer-guard))
)

(defun gas-payer-guard ()
@doc
"The guard function for gas payment. \
\ It requires both the GAS and ALLOW_GAS capabilities to be in scope, \
\ ensuring that gas payments are authorized."

(require-capability (GAS))
(require-capability (ALLOW_GAS))
)
)

; This code is used to create the opact-gas-payer account using the gas-payer-guard and
; transfer an initial balance of 2.0 to it from the opact-deployer account.
(coin.transfer-create "opact-deployer" "opact-gas-payer" (free.opact-gas-station.create-gas-payer-guard) 2.0)
44 changes: 40 additions & 4 deletions contracts/groth16-verifier/src/ejs/lib.ejs.repl
@@ -1,24 +1,44 @@
(namespace (read-msg 'ns))

(module groth16-<%= n_public - 7 %>x2 GOVERNANCE
@doc
"This module implements Groth16 zk-SNARKs (Zero-Knowledge Succinct Non-Interactive Argument of Knowledge) verification. \
\ It dynamically names the module based on the number of public inputs. \
\ The module includes definitions for G1 and G2 points on an elliptic curve, a verifier structure, \
\ and a proof structure. It also provides functions to verify zk-SNARKs proofs."

(defcap GOVERNANCE ()
@doc
"Governance capability to enforce specific administrative privileges. \
\ It ensures that only authorized keysets can perform critical operations within the module."

(enforce-keyset "free.opact-admin")
)

(defschema G1Point
"Structure representing a G1 point."
@doc
"Structure representing a G1 point in an elliptic curve, consisting of x and y coordinates as integers. \
\ G1 points are used in various cryptographic operations within the zk-SNARKs protocol."

x: integer
y: integer
)

(defschema G2Point
"Structure representing a G2 point."
@doc
"Structure representing a G2 point in an elliptic curve. G2 points are similar to G1 points but require arrays \
\ of integers for coordinates to accommodate the complexity and size of the data involved in zk-SNARKs."

x: [integer]
y: [integer]
)

(defschema Verifier
"Structure representing the verifier."
@doc
"Structure representing the verifier in zk-SNARKs. \
\ It includes the number of public inputs, points alfa1, beta2, gamma2, \
\ delta2 in G1 or G2, an array of G1 points for input consistency (ic), and the snark scalar field."

n_public: integer
alfa1: object{G1Point}
beta2: object{G2Point}
Expand All @@ -29,14 +49,21 @@
)

(defschema Proof
"Structure representing a proof."
@doc
"Structure representing a proof in zk-SNARKs. \
\ It includes an array of public values and points a, b, and c in G1 or G2."

public_values: [integer]
a: object{G1Point}
b: object{G2Point}
c: object{G1Point}
)

(defun verify (proof:object{Proof})
@doc
"Structure representing a proof in zk-SNARKs. It comprises the public values and points a, b, and c in G1 or G2 forms. \
\ This structure is used to encapsulate the proof data that needs to be verified using the Groth16 verification algorithm."

(
let*
(
Expand Down Expand Up @@ -87,6 +114,10 @@
)

(defun negate(p:object{G1Point})
@doc
"Function to negate a G1 point, a common operation in elliptic curve cryptography. \
\ It takes a G1 point and returns its negation. This function is used within the verification process."

(
let*
(
Expand All @@ -102,6 +133,11 @@
)

(defun check-pairing(a1:object{G1Point} a2:object{G2Point} b1:object{G1Point} b2:object{G2Point} c1:object{G1Point} c2:object{G2Point} d1:object{G1Point} d2:object{G2Point})
@doc
"Function to perform a pairing check, a core component of zk-SNARKs verification. \
\ It involves checking the mathematical relationships between pairs of G1 and G2 points, \
\ which is used to ensure the validity of a zk-SNARKs proof."

(
let*
(
Expand Down