Skip to content

Commit

Permalink
Merge pull request #188 from KogarashiNetwork/feature/short-modify-2
Browse files Browse the repository at this point in the history
add nova readme
  • Loading branch information
ashWhiteHat authored Dec 26, 2023
2 parents 4452f72 + 3985387 commit 6cfe4cd
Show file tree
Hide file tree
Showing 13 changed files with 301 additions and 16 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM alpine:3.18.2

ENV PATH="$PATH:/root/.cargo/bin" \
RUSTFLAGS="-C target-feature=-crt-static" \
TOOLCHAIN="nightly-2022-11-14"

RUN apk add --no-cache --update-cache \
curl clang15 clang15-dev git gcc g++ protoc llvm-dev bash openssl-dev && \
curl https://sh.rustup.rs -sSf | \
sh -s -- -y --profile minimal --default-toolchain $TOOLCHAIN &&\
rustup target add wasm32-unknown-unknown --toolchain $TOOLCHAIN &&\
rustup component add rustfmt --toolchain $TOOLCHAIN

WORKDIR /app

COPY . .

WORKDIR /app/pallet/nova

RUN cargo test --release
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ We provide the composable layer 2 technologies by **Recursive Snarks** on top of
$ cargo test --all --release
```

or

```shell
$ docker-compose up
```

## Status

**We are in research and development phase and this is alpha quality software. Please use at your own risk**.
Expand Down
9 changes: 4 additions & 5 deletions bn254/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
# Bls12 381 Curve
[![CI](https://github.com/KogarashiNetwork/bls12_381/actions/workflows/ci.yml/badge.svg)](https://github.com/KogarashiNetwork/bls12_381/actions/workflows/ci.yml) [![crates.io badge](https://img.shields.io/crates/v/bls-12-381.svg)](https://crates.io/crates/bls-12-381) [![Documentation](https://docs.rs/bls-12-381/badge.svg)](https://docs.rs/bls-12-381) [![GitHub license](https://img.shields.io/badge/license-GPL3%2FApache2-blue)](#LICENSE) [![codecov](https://codecov.io/gh/KogarashiNetwork/bls12_381/branch/master/graph/badge.svg?token=W83P6U2QKE)](https://codecov.io/gh/KogarashiNetwork/bls12_381) [![dependency status](https://deps.rs/crate/zero-bls12-381/latest/status.svg)](https://deps.rs/crate/zero-bls12-381/latest)
# BN254 Curve

Pairing friendly bls12-381 curve supports fully `no_std` and [`parity-scale-codec`](https://github.com/paritytech/parity-scale-codec).
Pairing friendly bn254 curve supports fully `no_std` and [`parity-scale-codec`](https://github.com/paritytech/parity-scale-codec).

## Overview
This crate includes field and extension fields, curve implementation. There are two curve $G1$ and $G2$ described as following.

$G1: y^2 = x^3 + 4$
$G1: y^2 = x^3 + 3$

$G2: y^2 = x^3 + 4(u + 1)$
$G2: y^2 = x^3 + 3(u + 1)$

These two group supports bilinearity by pairing. Let $G$ and $H$ be generator of $G1$, and $G2$, and $e$ be pairing function. The relationship is described as following.

Expand Down
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: '3'
services:
nova:
build: .
container_name: nova
tty: true
stdin_open: true
3 changes: 3 additions & 0 deletions groth16/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ std = [
"zkstd/std",
"rayon"
]

[[example]]
name = "simple"
82 changes: 81 additions & 1 deletion groth16/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,83 @@
# zkSNARKs

Plonk and Groth16 implementation
Implementation of [`On the Size of Pairing-based Non-interactive Arguments`](https://eprint.iacr.org/2016/260.pdf)

## Usage

```rs
use bn_254::Fr as BnScalar;
use zkgroth16::{Bn254Driver, Circuit, Error, ZkSnark};
use zkstd::{
circuit::prelude::{FieldAssignment, R1cs},
common::OsRng,
};

// Circuit definition
// x: public input
// o: public output
// Constraints are as follows
// x^3 + x + 5 = o
#[derive(Debug)]
pub struct DummyCircuit {
x: BnScalar,
o: BnScalar,
}

impl DummyCircuit {
pub fn new(x: BnScalar, o: BnScalar) -> Self {
Self { x, o }
}
}

impl Default for DummyCircuit {
fn default() -> Self {
Self::new(0.into(), 0.into())
}
}

impl Circuit for DummyCircuit {
fn synthesize(&self, composer: &mut R1cs<Bn254Driver>) -> Result<(), Error> {
// Declare public input
let x = FieldAssignment::instance(composer, self.x);
// Declare public output
let o = FieldAssignment::instance(composer, self.o);
// Declare public constant
let c = FieldAssignment::constant(&BnScalar::from(5));

// Constrain sym1 == x * x
let sym1 = FieldAssignment::mul(composer, &x, &x);
// Constrain y == sym1 * x
let y = FieldAssignment::mul(composer, &sym1, &x);
// Constrain sym2 = y + x
let sym2 = FieldAssignment::add(composer, &y, &x);

// Constrain sym2 + c == o
FieldAssignment::enforce_eq(composer, &(&sym2 + &c), &o);

Ok(())
}
}

fn main() {
// Public input and output
let x = BnScalar::from(3);
let o = BnScalar::from(35);

// Initialize circuit with arguments
let circuit = DummyCircuit::new(x, o);

// Setup prover and verifier
let (mut prover, verifier) =
ZkSnark::setup::<DummyCircuit>(OsRng).expect("Failed to compile circuit");

// Generate proof
let proof = prover
.create_proof(&mut OsRng, circuit)
.expect("Failed to prove");

// Verify proof
verifier
.verify(&proof, &[x, o])
.expect("Failed to verify the proof");
}
```
75 changes: 75 additions & 0 deletions groth16/examples/simple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use bn_254::Fr as BnScalar;
use zkgroth16::{Bn254Driver, Circuit, Error, ZkSnark};
use zkstd::{
circuit::prelude::{FieldAssignment, R1cs},
common::OsRng,
};

// Circuit definition
// x: public input
// o: public output
// Constraints are as follows
// x^3 + x + 5 = o
#[derive(Debug)]
pub struct DummyCircuit {
x: BnScalar,
o: BnScalar,
}

impl DummyCircuit {
pub fn new(x: BnScalar, o: BnScalar) -> Self {
Self { x, o }
}
}

impl Default for DummyCircuit {
fn default() -> Self {
Self::new(0.into(), 0.into())
}
}

impl Circuit for DummyCircuit {
fn synthesize(&self, composer: &mut R1cs<Bn254Driver>) -> Result<(), Error> {
// Declare public input
let x = FieldAssignment::instance(composer, self.x);
// Declare public output
let o = FieldAssignment::instance(composer, self.o);
// Declare public constant
let c = FieldAssignment::constant(&BnScalar::from(5));

// Constrain sym1 == x * x
let sym1 = FieldAssignment::mul(composer, &x, &x);
// Constrain y == sym1 * x
let y = FieldAssignment::mul(composer, &sym1, &x);
// Constrain sym2 = y + x
let sym2 = FieldAssignment::add(composer, &y, &x);

// Constrain sym2 + c == o
FieldAssignment::enforce_eq(composer, &(&sym2 + &c), &o);

Ok(())
}
}

fn main() {
// Public input and output
let x = BnScalar::from(3);
let o = BnScalar::from(35);

// Initialize circuit with arguments
let circuit = DummyCircuit::new(x, o);

// Setup prover and verifier
let (mut prover, verifier) =
ZkSnark::setup::<DummyCircuit>(OsRng).expect("Failed to compile circuit");

// Generate proof
let proof = prover
.create_proof(&mut OsRng, circuit)
.expect("Failed to prove");

// Verify proof
verifier
.verify(&proof, &[x, o])
.expect("Failed to verify the proof");
}
7 changes: 2 additions & 5 deletions groth16/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod prover;
mod verifier;
mod zksnark;

pub use circuit::Circuit;
pub use circuit::{Bn254Driver, Circuit};
pub use error::Error;
pub use proof::Proof;
pub use prover::Prover;
Expand All @@ -20,9 +20,7 @@ pub use zksnark::ZkSnark;

#[cfg(test)]
mod tests {
use crate::circuit::{Bn254Driver, Circuit};
use crate::error::Error;
use crate::zksnark::ZkSnark;
use super::*;

use bn_254::Fr as BnScalar;
use zkstd::circuit::prelude::{FieldAssignment, R1cs};
Expand Down Expand Up @@ -56,7 +54,6 @@ mod tests {

let sym1 = FieldAssignment::mul(composer, &x, &x);
let y = FieldAssignment::mul(composer, &sym1, &x);
// TODO: check why using the `Add` trait crashes this test
let sym2 = FieldAssignment::add(composer, &y, &x);

FieldAssignment::enforce_eq(composer, &(&sym2 + &c), &o);
Expand Down
8 changes: 6 additions & 2 deletions grumpkin/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Grumpkin Curve

grumpkin curve implementation.
Grumpkin curve supports fully `no_std` and [`parity-scale-codec`](https://github.com/paritytech/parity-scale-codec).

$E: y^2 = x^3 + 3$
$E: y^2 = x^3 - 17$

## Overview

This crate includes Grumpkin curve operation. This is cycle pair of bn254 curve.

## Test

Expand Down
2 changes: 2 additions & 0 deletions nova/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# Nova

Implementation of [`Nova: Recursive Zero-Knowledge Arguments from Folding Schemes`](https://eprint.iacr.org/2021/370.pdf)
91 changes: 91 additions & 0 deletions pallet/nova/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Nova Module

The Nova module provides functionality for Recursive Snarks.

## Overview

The Nova module provides functions for:

- Defining circuit to be folded
- Folding custom circuit r1cs
- Setup public parameters
- Checking satisfiability of folded r1cs

## Terminology

- **Recursive Snark**: One types of Snarks which proves a proof inside of another proof. [halo2](https://github.com/zcash/halo2) accumulation scheme is one of the most famous recursive Snark example. Prover proves the validity of verifier in addition to prover arithmetization.

- **Cycle of Curves**: Curve pair which has inverse scalar and base field for each other. Prover arithmetization is performed on base field and verifier arithmetization is on scalar field. In recursive snark, prover proves both arithmetization thus, cycle of curves can be used for optimization. [pasta](https://github.com/zcash/pasta_curves) curves is one of the most famous cycle of curves example.

- **Folding Scheme**: One types of recursive snark strategy. Folding scheme compresses the statement instead of generating proof. We can skip heavy computation such as the Fft and large Msm by avoiding proof generation.

- **IVC Scheme** One types of [Proof-Carrying Data](https://eprint.iacr.org/2020/1618.pdf). IVC (Incrementally Verifiable Computation) means computations over path graphs.

## Interface

### Dispatchable Functions

- `verify` - Verify IVC scheme final proof

## Usage

The following examples show how to use the Nova module in your custom module.

### Examples from the FRAME

The Nova module uses the `FunctionCircuit` trait to define circuit to be folded:

```rs
impl<F: PrimeField> FunctionCircuit<F> for ExampleFunction<F> {
fn invoke(z: &DenseVectors<F>) -> DenseVectors<F> {
let next_z = z[0] * z[0] * z[0] + z[0] + F::from(5);
DenseVectors::new(vec![next_z])
}

fn invoke_cs<C: CircuitDriver<Scalar = F>>(
cs: &mut R1cs<C>,
z_i: Vec<FieldAssignment<F>>,
) -> Vec<FieldAssignment<F>> {
let five = FieldAssignment::constant(&F::from(5));
let z_i_square = FieldAssignment::mul(cs, &z_i[0], &z_i[0]);
let z_i_cube = FieldAssignment::mul(cs, &z_i_square, &z_i[0]);

vec![&(&z_i_cube + &z_i[0]) + &five]
}
}
```

- `invoke` - Return function result
- `invoke_cs` - Custom circuit constraints

In above example, we prove $f(x) = x^3 + x + 5$ for given input $x$.
The Nova module verifies the folding scheme validity by `verify` pallet function.

```rs
let z0_primary = DenseVectors::new(vec![Fr::from(0)]);
let z0_secondary = DenseVectors::new(vec![Fq::from(0)]);
let mut ivc =
Ivc::<Bn254Driver, GrumpkinDriver, ExampleFunction<Fr>, ExampleFunction<Fq>>::init(
&pp,
z0_primary,
z0_secondary,
);
(0..2).for_each(|_| {
ivc.prove_step(&pp);
});
let proof = ivc.prove_step(&pp);

new_test_ext().execute_with(|| {
assert!(Nova::verify(Origin::signed(1), proof, pp.clone()).is_ok());
});
```

In above example, we verify the validity of folding $x_3 = f^{(3)}(x)$

## Test

```shell
$ cargo test --all --release
```

License: Apache-2.0
6 changes: 3 additions & 3 deletions pallet/nova/src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate as nova_ivc_pallet;
use crate as pallet_nova;
use crate::*;
use frame_support::parameter_types;
use frame_system as system;
Expand All @@ -19,7 +19,7 @@ frame_support::construct_runtime!(
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system::{Module, Call, Config, Storage, Event<T>},
TemplateModule: nova_ivc_pallet::{Module, Call, Storage},
TemplateModule: pallet_nova::{Module, Call, Storage},
}
);

Expand Down Expand Up @@ -76,7 +76,7 @@ impl<F: PrimeField> FunctionCircuit<F> for ExampleFunction<F> {
}
}

impl nova_ivc_pallet::Config for Test {
impl pallet_nova::Config for Test {
type E1 = Bn254Driver;
type E2 = GrumpkinDriver;
type FC1 = ExampleFunction<Fr>;
Expand Down

0 comments on commit 6cfe4cd

Please sign in to comment.