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

Remove gnark dependency #143

Closed
wants to merge 18 commits into from
Closed
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
11 changes: 7 additions & 4 deletions .github/workflows/cairo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ name: Cairo 1 tests

on:
push:
branches: [main]
pull_request:
merge_group:
pull_request_target:

jobs:
test-cairo:
Expand All @@ -13,6 +14,8 @@ jobs:
- uses: software-mansion/setup-scarb@v1
with:
scarb-version: "2.7.0"
- run: scarb fmt --check
working-directory: src/cairo
- run: cd src/cairo && scarb test
- name: Check formatting and run tests
run: |
cd src/cairo
scarb fmt --check
scarb test
24 changes: 8 additions & 16 deletions .github/workflows/fustat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,29 @@ name: Cairo Zero (Fustat) tests

on:
push:
branches: [main]
pull_request:
merge_group:
pull_request_target:

jobs:
test-fustat:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10.14
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.10.14
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '^1.17'
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
components: rustfmt, clippy

- name: Setup repo
run: make setup
- name: Check cairo Formatting
run: |
source venv/bin/activate && ./tools/make/fustat_format_check.sh
- name: Compile cairo files
run: source venv/bin/activate && make build
- name: Run fustat programs
- name: Setup and run tests
run: |
make setup
source venv/bin/activate
pytest tests/fustat_programs/test_fustat.py -n auto -s
./tools/make/fustat_format_check.sh
make build
pytest tests/fustat_programs/test_fustat.py -n auto -s
28 changes: 11 additions & 17 deletions .github/workflows/hydra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,32 @@ name: Hydra backend test

on:
push:
branches: [main]
pull_request:
merge_group:
pull_request_target:

jobs:
test-hydra:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10.14
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.10.14
- name: Install dependencies
run: |
python -m venv venv
source venv/bin/activate
echo 'export PYTHONPATH="$PWD:$PYTHONPATH"' >> venv/bin/activate
pip install -r tools/make/requirements.txt
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '^1.17'
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
components: rustfmt, clippy

- name: Compile Gnark
run: make go
- name: Compile Rust bindings with maturin
- name: Install dependencies
run: |
python -m venv venv
source venv/bin/activate
echo 'export PYTHONPATH="$PWD:$PYTHONPATH"' >> venv/bin/activate
pip install -r tools/make/requirements.txt
- name: Compile Rust bindings and run tests
run: |
source venv/bin/activate
cd tools/garaga_rs
Expand All @@ -42,4 +36,4 @@ jobs:
- name: Run pytest
run: |
source venv/bin/activate
pytest -n auto
pytest -n auto
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ venv
*.so
*.html
*.sage.py
tools/gnark/main
tools/gnark/bls12_381/cairo_test/main

tools/garaga_rs/target/
tools/garaga_rs/Cargo.lock
tools/garaga_rs/sys

src/cairo/target/
5 changes: 1 addition & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,5 @@ clean:
mkdir -p build
mkdir build/compiled_cairo_files

go:
./tools/make/go.sh

hints:
./tools/make/gen_hints_document.py
./tools/make/gen_hints_document.py
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,26 @@ Garaga consists of a Pythonic backend and CairoZero / Starknet interfaces.
It also handles witnesses generation for the non-deterministic computations.
- The CairoZero / Starknet interfaces are responsible for composing and calling the circuits, as well as adding all the extra logic needed to make the algorithms work (Fiat-Shamir heuristic, SNARKS verifiers, etc).

## Deploying SNARKS verifier on Starknet

## Getting Started
`pip install garaga` with tutorials coming.
In the meantime, check `tools/starknet/`

## Development setup

To get started with Garaga, you'll need to have some tools and dependencies installed. Here's everything you need:

### Prerequisites

Ensure you have the following installed:
- [Python 3.10](https://www.python.org/downloads/) - The core language used for development.
- [Go](https://golang.org/doc/install) - Required for profiling and testing.
- [pprof](https://github.com/google/pprof) - A tool for visualization and analysis of profiling data.
- [Python 3.10](https://www.python.org/downloads/) - The core language used for development. Make sure you have the correct dependencies installed (namely, GMP) for the `fastecdsa` python package. See [here](https://pypi.org/project/fastecdsa/#installing) for linux and [here](https://github.com/AntonKueltz/fastecdsa/issues/74) for macos.
- [Scarb 2.7.0](https://docs.swmansion.com/scarb/download.html) - The Cairo package manager. Comes with Cairo inside. Requires [Rust](https://www.rust-lang.org/tools/install).

##### Optionally :

- [pprof](https://github.com/google/pprof) - A tool for visualization and analysis of profiling data. Requires [Go](https://go.dev/).
- [graphviz](https://graphviz.org/download/) - Necessary for generating graphical representations of profiling data.
- A functional [SageMath](https://www.sagemath.org/download.html) installation or an operational [Docker](https://www.docker.com/get-started/) daemon with non-sudo privileges.


### Setup

Expand All @@ -74,11 +81,6 @@ make setup
```

At this point, you should have everything you need to start developing with Garaga. Before proceeding, make sure to activate the virtual environment by running `source venv/bin/activate`.
### Compile & Run .cairo files (interactive script!)

```bash
make run
```

## Benchmarks

Expand All @@ -90,7 +92,6 @@ make run
| ADDMOD | 4 | Equivalent cost of a+b % p with the modulo builtin in VM steps |
| ASSERT_EQ | 2 | Equivalent cost of a==b % p with the modulo builtin in VM steps |
| RLC | 28 | Cost of writing a field element to the value segment and retrieving random coefficients |
| POSEIDON 3 LIMBS | 14 | Cost of hashing the first 3 limbs of 384 bits emulated field element with Poseidon |
| POSEIDON 4 LIMBS | 17 | Cost of hashing the 4 limbs of 384 bits emulated field element with Poseidon |


Expand Down
101 changes: 76 additions & 25 deletions hydra/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import random
from dataclasses import dataclass
from enum import Enum
from typing import TypeAlias
from fastecdsa import curvemath


Expand All @@ -16,6 +17,7 @@
PyFelt,
)
from hydra.hints.io import bigint_split, int_to_u256, int_to_u384
import garaga_rs

N_LIMBS = 4
BASE = 2**96
Expand Down Expand Up @@ -237,7 +239,9 @@ def NAF(x):
return NAF((x - z) // 2) + [z]


GNARK_CLI_SUPPORTED_CURVES = {BN254_ID, BLS12_381_ID}
GARAGA_RS_SUPPORTED_CURVES = {BN254_ID, BLS12_381_ID}

Curve: TypeAlias = WeierstrassCurve

CURVES: dict[int, WeierstrassCurve] = {
BN254_ID: PairingCurve(
Expand Down Expand Up @@ -781,12 +785,11 @@ def gen_random_point(curve_id: CurveID) -> "G2Point":
Generates a random point on a given curve.
"""
scalar = random.randint(1, CURVES[curve_id.value].n - 1)
if curve_id.value in GNARK_CLI_SUPPORTED_CURVES:
from tools.gnark_cli import GnarkCLI

cli = GnarkCLI(curve_id)
ng1ng2 = cli.nG1nG2_operation(1, scalar, raw=True)
return G2Point((ng1ng2[2], ng1ng2[3]), (ng1ng2[4], ng1ng2[5]), curve_id)
if curve_id.value in GARAGA_RS_SUPPORTED_CURVES:
curve = CURVES[curve_id.value]
a = (curve.G2x[0], curve.G2x[1], curve.G2y[0], curve.G2y[1])
b = garaga_rs.g2_scalar_mul(curve_id.value, a, scalar)
return G2Point((b[0], b[1]), (b[2], b[3]), curve_id)
else:
raise NotImplementedError(
"G2Point.gen_random_point is not implemented for this curve"
Expand All @@ -801,12 +804,11 @@ def get_nG(curve_id: CurveID, n: int) -> "G1Point":
n < CURVES[curve_id.value].n
), f"n must be less than the order of the curve"

if curve_id.value in GNARK_CLI_SUPPORTED_CURVES:
from tools.gnark_cli import GnarkCLI

cli = GnarkCLI(curve_id)
ng1ng2 = cli.nG1nG2_operation(1, n, raw=True)
return G2Point((ng1ng2[2], ng1ng2[3]), (ng1ng2[4], ng1ng2[5]), curve_id)
if curve_id.value in GARAGA_RS_SUPPORTED_CURVES:
curve = CURVES[curve_id.value]
a = (curve.G2x[0], curve.G2x[1], curve.G2y[0], curve.G2y[1])
b = garaga_rs.g2_scalar_mul(curve_id.value, a, n)
return G2Point((b[0], b[1]), (b[2], b[3]), curve_id)
else:
raise NotImplementedError(
"G2Point.get_nG is not implemented for this curve"
Expand All @@ -819,12 +821,10 @@ def scalar_mul(self, scalar: int) -> "G2Point":
return G2Point((0, 0), (0, 0), self.curve_id)
if scalar < 0:
return -self.scalar_mul(-scalar)
if self.curve_id.value in GNARK_CLI_SUPPORTED_CURVES:
from tools.gnark_cli import GnarkCLI

cli = GnarkCLI(self.curve_id)
sP = cli.g2_scalarmul((self.x, self.y), scalar)
return G2Point((sP[0], sP[1]), (sP[2], sP[3]), self.curve_id)
if self.curve_id.value in GARAGA_RS_SUPPORTED_CURVES:
a = (self.x[0], self.x[1], self.y[0], self.y[1])
b = garaga_rs.g2_scalar_mul(self.curve_id.value, a, scalar)
return G2Point((b[0], b[1]), (b[2], b[3]), self.curve_id)
else:
raise NotImplementedError(
"G2Point.scalar_mul is not implemented for this curve"
Expand All @@ -837,12 +837,15 @@ def add(self, other: "G2Point") -> "G2Point":
return self
if self.curve_id != other.curve_id:
raise ValueError("Points are not on the same curve")
if self.curve_id.value in GNARK_CLI_SUPPORTED_CURVES:
from tools.gnark_cli import GnarkCLI

cli = GnarkCLI(self.curve_id)
sP = cli.g2_add((self.x, self.y), (other.x, other.y))
return G2Point((sP[0], sP[1]), (sP[2], sP[3]), self.curve_id)
if self.curve_id.value in GARAGA_RS_SUPPORTED_CURVES:
a = (self.x[0], self.x[1], self.y[0], self.y[1])
b = (other.x[0], other.x[1], other.y[0], other.y[1])
c = garaga_rs.g2_add(self.curve_id.value, a, b)
return G2Point((c[0], c[1]), (c[2], c[3]), self.curve_id)
else:
raise NotImplementedError(
"G2Point.add is not implemented for this curve"
)

def __neg__(self) -> "G2Point":
p = CURVES[self.curve_id.value].p
Expand Down Expand Up @@ -887,6 +890,54 @@ def to_pyfelt_list(self) -> list[PyFelt]:
]
]

@staticmethod
def pair(pairs: list["G1G2Pair"], curve_id: CurveID = None):
from hydra.hints.tower_backup import E12 # avoids cycle
if curve_id == None:
if len(pairs) == 0: raise ValueError("Unspecified curve")
curve_id = pairs[0].curve_id
if curve_id.value in GARAGA_RS_SUPPORTED_CURVES:
args = []
for pair in pairs:
if pair.curve_id != curve_id:
raise ValueError("Pairs are not on the same curve")
args.append(pair.p.x)
args.append(pair.p.y)
args.append(pair.q.x[0])
args.append(pair.q.x[1])
args.append(pair.q.y[0])
args.append(pair.q.y[1])
res = garaga_rs.multi_pairing(curve_id.value, args)
return E12(res, curve_id.value)
else:
raise NotImplementedError(
"G1G2Pair.pair is not implemented for this curve"
)

@staticmethod
def miller(pairs: list["G1G2Pair"], curve_id: CurveID = None):
from hydra.hints.tower_backup import E12 # avoids cycle
if curve_id == None:
if len(pairs) == 0: raise ValueError("Unspecified curve")
curve_id = pairs[0].curve_id
if curve_id.value in GARAGA_RS_SUPPORTED_CURVES:
args = []
for pair in pairs:
if pair.curve_id != curve_id:
raise ValueError("Pairs are not on the same curve")
args.append(pair.p.x)
args.append(pair.p.y)
args.append(pair.q.x[0])
args.append(pair.q.x[1])
args.append(pair.q.y[0])
args.append(pair.q.y[1])
res = garaga_rs.multi_miller_loop(curve_id.value, args)
return E12(res, curve_id.value)
else:
raise NotImplementedError(
"G1G2Pair.miller is not implemented for this curve"
)


# v^6 - 18v^3 + 82
# w^12 - 18w^6 + 82
Expand Down
Loading
Loading