-
Notifications
You must be signed in to change notification settings - Fork 412
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: John Guibas <[email protected]>
- Loading branch information
Showing
5 changed files
with
215 additions
and
39 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
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,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 | ||
} |
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,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); | ||
} | ||
} |
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,8 +1,7 @@ | ||
#![no_std] | ||
|
||
extern crate alloc; | ||
|
||
pub mod asm; | ||
pub mod backend; | ||
pub mod builder; | ||
pub mod heap; | ||
pub mod ir; | ||
|