Skip to content

Commit

Permalink
gnark backend (#375)
Browse files Browse the repository at this point in the history
Co-authored-by: John Guibas <[email protected]>
  • Loading branch information
jtguibas and John Guibas authored Mar 13, 2024
1 parent 7650d6d commit 114db25
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 39 deletions.
74 changes: 37 additions & 37 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,43 +20,43 @@
],
"rust-analyzer.linkedProjects": [
"Cargo.toml",
// Examples.
"examples/chess/program/Cargo.toml",
"examples/chess/script/Cargo.toml",
"examples/ed25519/script/Cargo.toml",
"examples/ed25519/program/Cargo.toml",
"examples/fibonacci/program/Cargo.toml",
"examples/fibonacci/script/Cargo.toml",
"examples/fibonacci-io/program/Cargo.toml",
"examples/fibonacci-io/script/Cargo.toml",
"examples/io/program/Cargo.toml",
"examples/io/script/Cargo.toml",
"examples/json/program/Cargo.toml",
"examples/json/script/Cargo.toml",
"examples/regex/program/Cargo.toml",
"examples/regex/script/Cargo.toml",
"examples/rsa/program/Cargo.toml",
"examples/rsa/script/Cargo.toml",
"examples/ssz-withdrawals/program/Cargo.toml",
"examples/ssz-withdrawals/script/Cargo.toml",
"examples/tendermint/program/Cargo.toml",
"examples/tendermint/script/Cargo.toml",
// Tests.
"tests/blake3-compress/Cargo.toml",
"tests/cycle-tracker/Cargo.toml",
"tests/ecrecover/Cargo.toml",
"tests/ed-add/Cargo.toml",
"tests/ed-decompress/Cargo.toml",
"tests/keccak-permute/Cargo.toml",
"tests/keccak256/Cargo.toml",
"tests/secp256k1-add/Cargo.toml",
"tests/secp256k1-decompress/Cargo.toml",
"tests/secp256k1-double/Cargo.toml",
"tests/sha-compress/Cargo.toml",
"tests/sha-extend/Cargo.toml",
"tests/sha2/Cargo.toml",
// Eval.
"eval/Cargo.toml"
// // Examples.
// "examples/chess/program/Cargo.toml",
// "examples/chess/script/Cargo.toml",
// "examples/ed25519/script/Cargo.toml",
// "examples/ed25519/program/Cargo.toml",
// "examples/fibonacci/program/Cargo.toml",
// "examples/fibonacci/script/Cargo.toml",
// "examples/fibonacci-io/program/Cargo.toml",
// "examples/fibonacci-io/script/Cargo.toml",
// "examples/io/program/Cargo.toml",
// "examples/io/script/Cargo.toml",
// "examples/json/program/Cargo.toml",
// "examples/json/script/Cargo.toml",
// "examples/regex/program/Cargo.toml",
// "examples/regex/script/Cargo.toml",
// "examples/rsa/program/Cargo.toml",
// "examples/rsa/script/Cargo.toml",
// "examples/ssz-withdrawals/program/Cargo.toml",
// "examples/ssz-withdrawals/script/Cargo.toml",
// "examples/tendermint/program/Cargo.toml",
// "examples/tendermint/script/Cargo.toml",
// // Tests.
// "tests/blake3-compress/Cargo.toml",
// "tests/cycle-tracker/Cargo.toml",
// "tests/ecrecover/Cargo.toml",
// "tests/ed-add/Cargo.toml",
// "tests/ed-decompress/Cargo.toml",
// "tests/keccak-permute/Cargo.toml",
// "tests/keccak256/Cargo.toml",
// "tests/secp256k1-add/Cargo.toml",
// "tests/secp256k1-decompress/Cargo.toml",
// "tests/secp256k1-double/Cargo.toml",
// "tests/sha-compress/Cargo.toml",
// "tests/sha-extend/Cargo.toml",
// "tests/sha2/Cargo.toml",
// // Eval.
// "eval/Cargo.toml"
],
"rust-analyzer.showUnlinkedFileNotification": false
}
21 changes: 21 additions & 0 deletions recursion/compiler/src/backend/gnark.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Welcome to the gnark playground!
package main

import "github.com/consensys/gnark/frontend"

// gnark is a zk-SNARK library written in Go. Circuits are regular structs.
// The inputs must be of type frontend.Variable and make up the witness.
// The witness has a
// - secret part --> known to the prover only
// - public part --> known to the prover and the verifier
type Circuit struct {
X frontend.Variable `gnark:"x"` // x --> secret visibility (default)
Y frontend.Variable `gnark:",public"` // Y --> public visibility
}

// Define declares the circuit logic. The compiler then produces a list of constraints
// which must be satisfied (valid witness) in order to create a valid zk-SNARK
func (circuit *Circuit) Define(api frontend.API) error {
{{LINES}}
return nil
}
125 changes: 125 additions & 0 deletions recursion/compiler/src/backend/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
use core::marker::PhantomData;

use crate::ir::{Config, DslIR};

const GNARK_TEMPLATE: &str = include_str!("gnark.txt");

#[derive(Debug, Clone)]
pub struct GnarkBackend<C: Config> {
pub phantom: PhantomData<C>,
}

impl<C: Config> GnarkBackend<C> {
pub fn emit(&mut self, program: Vec<DslIR<C>>) -> String {
let mut lines: Vec<String> = Vec::new();
for instruction in program {
match instruction {
// Variables.
DslIR::Imm(a, b) => {
lines.push(format!("{} := frontend.Variable({})", a.id(), b));
}
DslIR::AddV(a, b, c) => {
lines.push(format!("{} := api.Add({}, {})", a.id(), b.id(), c.id()));
}
DslIR::AddVI(a, b, c) => {
lines.push(format!(
"{} := api.Add({}, frontend.Variable({}))",
a.id(),
b.id(),
c
));
}
DslIR::SubV(a, b, c) => {
lines.push(format!("{} := api.Sub({}, {})", a.id(), b.id(), c.id()));
}
DslIR::SubVI(a, b, c) => {
lines.push(format!(
"{} := api.Sub(frontend.Variable({}), {})",
a.id(),
b.id(),
c
));
}
DslIR::MulV(a, b, c) => {
lines.push(format!("{} := api.Mul({}, {})", a.id(), b.id(), c.id()));
}
DslIR::MulVI(a, b, c) => {
lines.push(format!(
"{} := api.Mul(frontend.Variable({}), {})",
a.id(),
b.id(),
c
));
}
DslIR::DivV(a, b, c) => {
lines.push(format!("{} := api.Div({}, {})", a.id(), b.id(), c.id()));
}
DslIR::DivVI(a, b, c) => {
lines.push(format!(
"{} := api.Div(frontend.Variable({}), {})",
a.id(),
b.id(),
c
));
}
DslIR::NegV(a, b) => {
lines.push(format!("{} := api.Neg({})", a.id(), b.id()));
}
DslIR::InvV(a, b) => {
lines.push(format!("{} := api.Inv({})", a.id(), b.id()));
}
// Felts.
DslIR::ImmFelt(a, b) => {
lines.push(format!("{} := types.Felt({})", a.id(), b));
}
DslIR::ImmExt(a, b) => {
lines.push(format!("{} := types.Ext({})", a.id(), b));
}
_ => todo!(),
}
}
let lines = lines.join("\n ");
GNARK_TEMPLATE.replace("{{LINES}}", &lines)
}
}

#[cfg(test)]
mod tests {
use p3_baby_bear::BabyBear;
use p3_field::{extension::BinomialExtensionField, AbstractField};

use crate::ir::Var;

use super::*;

struct BabyBearConfig;

impl Config for BabyBearConfig {
type N = BabyBear;
type F = BabyBear;
type EF = BinomialExtensionField<BabyBear, 4>;
}

#[test]
fn test() {
let mut backend = GnarkBackend::<BabyBearConfig> {
phantom: PhantomData,
};
let program = vec![
DslIR::Imm(Var::new(0), BabyBear::zero()),
DslIR::Imm(Var::new(1), BabyBear::one()),
DslIR::AddV(Var::new(2), Var::new(0), Var::new(1)),
DslIR::AddVI(Var::new(3), Var::new(2), BabyBear::one()),
DslIR::SubV(Var::new(4), Var::new(2), Var::new(3)),
DslIR::SubVI(Var::new(5), Var::new(4), BabyBear::one()),
DslIR::MulV(Var::new(6), Var::new(2), Var::new(5)),
DslIR::MulVI(Var::new(7), Var::new(6), BabyBear::one()),
DslIR::DivV(Var::new(7), Var::new(6), Var::new(5)),
DslIR::DivVI(Var::new(8), Var::new(7), BabyBear::one()),
DslIR::NegV(Var::new(9), Var::new(8)),
DslIR::InvV(Var::new(10), Var::new(9)),
];
let result = backend.emit(program);
println!("{}", result);
}
}
31 changes: 31 additions & 0 deletions recursion/compiler/src/ir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub use symbolic::*;

#[derive(Debug, Clone, Copy)]
pub struct Var<N>(pub u32, pub PhantomData<N>);

#[derive(Debug, Clone, Copy)]
pub struct Felt<F>(pub u32, pub PhantomData<F>);

Expand Down Expand Up @@ -112,3 +113,33 @@ impl<N> From<usize> for Usize<N> {
Usize::Const(c)
}
}

impl<N> Var<N> {
pub fn new(id: u32) -> Self {
Self(id, PhantomData)
}

pub fn id(&self) -> String {
format!("var{}", self.0)
}
}

impl<F> Felt<F> {
pub fn new(id: u32) -> Self {
Self(id, PhantomData)
}

pub fn id(&self) -> String {
format!("felt{}", self.0)
}
}

impl<F, EF> Ext<F, EF> {
pub fn new(id: u32) -> Self {
Self(id, PhantomData)
}

pub fn id(&self) -> String {
format!("ext{}", self.0)
}
}
3 changes: 1 addition & 2 deletions recursion/compiler/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#![no_std]

extern crate alloc;

pub mod asm;
pub mod backend;
pub mod builder;
pub mod heap;
pub mod ir;
Expand Down

0 comments on commit 114db25

Please sign in to comment.