-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #188 from KogarashiNetwork/feature/short-modify-2
add nova readme
- Loading branch information
Showing
13 changed files
with
301 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,3 +27,6 @@ std = [ | |
"zkstd/std", | ||
"rayon" | ||
] | ||
|
||
[[example]] | ||
name = "simple" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters