Skip to content

Commit

Permalink
feat: gnark e2e build (#381)
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 14, 2024
1 parent dfaac9b commit 2dac783
Show file tree
Hide file tree
Showing 9 changed files with 408 additions and 64 deletions.
1 change: 0 additions & 1 deletion recursion/compiler/examples/fibonacci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use p3_field::AbstractField;
use sp1_core::stark::StarkGenericConfig;
use sp1_core::utils::BabyBearPoseidon2;
use sp1_recursion_compiler::asm::VmBuilder;
use sp1_recursion_compiler::backend::GnarkBackend;
use sp1_recursion_compiler::prelude::*;
use sp1_recursion_core::runtime::Runtime;

Expand Down
13 changes: 0 additions & 13 deletions recursion/compiler/src/backend/gnark.txt

This file was deleted.

175 changes: 175 additions & 0 deletions recursion/compiler/src/gnark/lib/babybear/babybear.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package babybear

import (
"math/big"

"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/math/emulated"
)

var Modulus = new(big.Int).SetUint64(2013265921)

type Params struct{}

func (fp Params) NbLimbs() uint { return 1 }
func (fp Params) BitsPerLimb() uint { return 32 }
func (fp Params) IsPrime() bool { return true }
func (fp Params) Modulus() *big.Int { return Modulus }
func (fp Params) NumElmsPerBN254Elm() uint { return 8 }

type Variable struct {
value *emulated.Element[Params]
}

type ExtensionVariable struct {
value [4]*Variable
}

type Chip struct {
api frontend.API
field *emulated.Field[Params]
}

func NewChip(api frontend.API) *Chip {
field, err := emulated.NewField[Params](api)
if err != nil {
panic(err)
}
return &Chip{
api: api,
field: field,
}
}

func NewVariable(value int) *Variable {
variable := emulated.ValueOf[Params](value)
return &Variable{
value: &variable,
}
}

func NewExtensionVariable(value [4]int) *ExtensionVariable {
a := NewVariable(value[0])
b := NewVariable(value[1])
c := NewVariable(value[2])
d := NewVariable(value[3])
return &ExtensionVariable{value: [4]*Variable{a, b, c, d}}
}

func (c *Chip) Add(a, b *Variable) *Variable {
return &Variable{
value: c.field.Add(a.value, b.value),
}
}

func (c *Chip) Sub(a, b *Variable) *Variable {
return &Variable{
value: c.field.Sub(a.value, b.value),
}
}

func (c *Chip) Mul(a, b *Variable) *Variable {
return &Variable{
value: c.field.Mul(a.value, b.value),
}
}

func (c *Chip) Neg(a *Variable) *Variable {
return &Variable{
value: c.field.Neg(a.value),
}
}

func (c *Chip) Inv(a *Variable) *Variable {
return &Variable{
value: c.field.Inverse(a.value),
}
}

func (c *Chip) AssertEq(a, b *Variable) {
c.field.AssertIsEqual(a.value, b.value)
}

func (c *Chip) AssertNe(a, b *Variable) {
diff := c.field.Sub(a.value, b.value)
isZero := c.field.IsZero(diff)
c.api.AssertIsEqual(isZero, frontend.Variable(0))
}

func (c *Chip) AddExtension(a, b *ExtensionVariable) *ExtensionVariable {
v1 := c.Add(a.value[0], b.value[0])
v2 := c.Add(a.value[1], b.value[1])
v3 := c.Add(a.value[2], b.value[2])
v4 := c.Add(a.value[3], b.value[3])
return &ExtensionVariable{value: [4]*Variable{v1, v2, v3, v4}}
}

func (c *Chip) SubExtension(a, b *ExtensionVariable) *ExtensionVariable {
v1 := c.Sub(a.value[0], b.value[0])
v2 := c.Sub(a.value[1], b.value[1])
v3 := c.Sub(a.value[2], b.value[2])
v4 := c.Sub(a.value[3], b.value[3])
return &ExtensionVariable{value: [4]*Variable{v1, v2, v3, v4}}
}

func (c *Chip) MulExtension(a, b *ExtensionVariable) *ExtensionVariable {
w := NewVariable(11)
v := [4]*Variable{
NewVariable(0),
NewVariable(0),
NewVariable(0),
NewVariable(0),
}

for i := 0; i < 4; i++ {
for j := 0; j < 4; j++ {
if i+j >= 4 {
v[i+j-4] = c.Add(v[i+j-4], c.Mul(c.Mul(v[i], v[j]), w))
} else {
v[i+j] = c.Add(v[i+j], c.Mul(v[i], v[j]))
}
}
}

return &ExtensionVariable{value: v}
}

func (c *Chip) NegExtension(a *ExtensionVariable) *ExtensionVariable {
v1 := c.Neg(a.value[0])
v2 := c.Neg(a.value[1])
v3 := c.Neg(a.value[2])
v4 := c.Neg(a.value[3])
return &ExtensionVariable{value: [4]*Variable{v1, v2, v3, v4}}
}

func (c *Chip) InvExtension(a *ExtensionVariable) *ExtensionVariable {
v := [4]*Variable{
NewVariable(0),
NewVariable(0),
NewVariable(0),
NewVariable(0),
}
return &ExtensionVariable{value: v}
}

func (c *Chip) AssertEqExtension(a, b *ExtensionVariable) {
c.AssertEq(a.value[0], b.value[0])
c.AssertEq(a.value[1], b.value[1])
c.AssertEq(a.value[2], b.value[2])
c.AssertEq(a.value[3], b.value[3])
}

func (c *Chip) AssertNeExtension(a, b *ExtensionVariable) {
v1 := c.field.Sub(a.value[0].value, b.value[0].value)
v2 := c.field.Sub(a.value[1].value, b.value[1].value)
v3 := c.field.Sub(a.value[2].value, b.value[2].value)
v4 := c.field.Sub(a.value[3].value, b.value[3].value)
isZero1 := c.field.IsZero(v1)
isZero2 := c.field.IsZero(v2)
isZero3 := c.field.IsZero(v3)
isZero4 := c.field.IsZero(v4)
isZero1AndZero2 := c.api.And(isZero1, isZero2)
isZero3AndZero4 := c.api.And(isZero3, isZero4)
isZeroAll := c.api.And(isZero1AndZero2, isZero3AndZero4)
c.api.AssertIsEqual(isZeroAll, frontend.Variable(0))
}
30 changes: 30 additions & 0 deletions recursion/compiler/src/gnark/lib/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module github.com/succinctlabs/sp1-recursion-gnark

go 1.20

require (
github.com/consensys/gnark v0.9.1
github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb
)

require (
github.com/bits-and-blooms/bitset v1.8.0 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fxamacker/cbor/v2 v2.5.0 // indirect
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rs/zerolog v1.30.0 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.15.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)
63 changes: 63 additions & 0 deletions recursion/compiler/src/gnark/lib/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c=
github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
github.com/consensys/gnark v0.9.1 h1:aTwBp5469MY/2jNrf4ABrqHRW3+JytfkADdw4ZBY7T0=
github.com/consensys/gnark v0.9.1/go.mod h1:udWvWGXnfBE7mn7BsNoGAvZDnUhcONBEtNijvVjfY80=
github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb h1:f0BMgIjhZy4lSRHCXFbQst85f5agZAjtDMixQqBWNpc=
github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo=
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c=
github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
32 changes: 32 additions & 0 deletions recursion/compiler/src/gnark/lib/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// This file is auto-generated by sp1-recursion-compiler.
package main

import (
"github.com/consensys/gnark/frontend"
"github.com/succinctlabs/sp1-recursion-gnark/babybear"
)

type Circuit struct {
X frontend.Variable
Y frontend.Variable
}

func (circuit *Circuit) Define(api frontend.API) error {
fieldChip := babybear.NewChip(api)

// Variables.
var felt0 *babybear.Variable
var felt1 *babybear.Variable
var felt2 *babybear.Variable

// Operations.
felt0 = babybear.NewVariable(0)
felt1 = babybear.NewVariable(1)
for i := 0; i < 12; i++ {
felt2 = fieldChip.Add(felt1, babybear.NewVariable(0))
felt1 = fieldChip.Add(felt0, felt1)
felt0 = fieldChip.Add(felt2, babybear.NewVariable(0))
}
fieldChip.AssertEq(felt0, babybear.NewVariable(144))
return nil
}
18 changes: 18 additions & 0 deletions recursion/compiler/src/gnark/lib/template.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// This file is auto-generated by sp1-recursion-compiler.
package main

import (
"github.com/consensys/gnark/frontend"
"github.com/succinctlabs/sp1-recursion-gnark/babybear"
)

type Circuit struct {
X frontend.Variable
Y frontend.Variable
}

func (circuit *Circuit) Define(api frontend.API) error {
fieldChip := babybear.NewChip(api)
{{LINES}}
return nil
}
Loading

0 comments on commit 2dac783

Please sign in to comment.