Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
609d47d
refactor: addInstance instead of series etc
Tabaie Jun 1, 2025
79d4cbf
feat: check for duplicate gates, allow limiting curves for gate
Tabaie Jun 1, 2025
82e33e5
refactor: gkr api tests
Tabaie Jun 1, 2025
ba06e5d
refactor gkr example
Tabaie Jun 1, 2025
700c152
refactor: solve hint called per instance
Tabaie Jun 2, 2025
30f5633
revert: newPrint back in std/gkr to avoid import cycle
Tabaie Jun 2, 2025
44d6b4c
refactor: remove circuit/instance rearranging
Tabaie Jun 2, 2025
f5f726c
chore: generify
Tabaie Jun 2, 2025
644fd6a
fix: registry duplicate detection
Tabaie Jun 2, 2025
2001e83
fix: solver hint id mismatch
Tabaie Jun 2, 2025
d3ca3c1
remove redundant make
Tabaie Jun 2, 2025
6474482
fix: works on plonk
Tabaie Jun 2, 2025
0c0b6b0
refactor: solve hint for test engine
Tabaie Jun 3, 2025
478d53d
fix prove hint
Tabaie Jun 3, 2025
6c83740
fix package tests
Tabaie Jun 3, 2025
d6e382f
refactor: remove println
Tabaie Jun 3, 2025
a8f30a4
chore: generify print removal
Tabaie Jun 3, 2025
8ac5f9f
feat: GetValue
Tabaie Jun 3, 2025
5bb879d
fix all gkrapi tests pass
Tabaie Jun 3, 2025
7f9a0f1
fix gkr-poseidon2
Tabaie Jun 3, 2025
355277c
Merge branch 'master' into feat/gkr/add-instance
Tabaie Jun 3, 2025
cfdb9d3
fix: reduce in test engine
Tabaie Jun 3, 2025
12788f3
fix: rename GkrCompressions -> GkrPermutations
Tabaie Jun 3, 2025
9a0bf0e
bench: gkrposeidon2
Tabaie Jun 3, 2025
618beff
fix pad for bls12377
Tabaie Jun 3, 2025
22b77f2
some more padding fixes
Tabaie Jun 3, 2025
250a35b
fix: padding issue in bn254
Tabaie Jun 4, 2025
1586760
chore generify fix
Tabaie Jun 4, 2025
e593d90
Let Uint64 panic
Tabaie Jun 4, 2025
9df619a
Update constraint/solver/gkrgates/registry.go
Tabaie Jun 4, 2025
8c88c52
refactor: use assert.EqualError
Tabaie Jun 4, 2025
f4d7aa8
Merge branch 'master' into feat/gkr/add-instance
Tabaie Jun 5, 2025
499ff52
refactor: import hash/all in test
Tabaie Jun 5, 2025
be747e0
refactor: shorten import name
Tabaie Jun 5, 2025
4ae9324
Merge branch 'master' into feat/gkr/add-instance
Tabaie Jun 6, 2025
4b43ce3
perf: addition rather than multiplication in gates
Tabaie Jun 8, 2025
6b86526
Revert "perf: addition rather than multiplication in gates"
Tabaie Jun 8, 2025
c4b01b5
feat: generify poseidon2-gkr (not all s-Boxes available yet)
Tabaie Jun 8, 2025
4765d61
revert incorrect renaming
Tabaie Jun 8, 2025
5342952
fix test
Tabaie Jun 8, 2025
9d9b13b
refactor generify tests
Tabaie Jun 8, 2025
430661a
feat: gkrposeidon2 compression for all curves
Tabaie Jun 8, 2025
b75843d
feat gkr-poseidon2 hasher
Tabaie Jun 8, 2025
ca85a41
Merge branch 'feat/gkr/add-instance' into feat/gkr/hashes
Tabaie Jun 8, 2025
be8a07e
fix more renaming
Tabaie Jun 8, 2025
1894cfa
feat: gkrmimc for sbox degree 5
Tabaie Jun 9, 2025
241d645
mimc length 1 works
Tabaie Jun 10, 2025
bb36459
fix final layer
Tabaie Jun 10, 2025
311d9d9
chore generify Println changes
Tabaie Jun 10, 2025
b3d1af8
fix: use multicommitter
Tabaie Jun 10, 2025
815adc7
feat: use kvstore for caching instances
Tabaie Jun 10, 2025
85d6aaa
Merge branch 'feat/gkr/add-instance' into feat/gkr/hashes
Tabaie Jun 10, 2025
7ab8702
feat: merkledamgard hasher as statestorer
Tabaie Jun 11, 2025
2fb7daa
test: SetState
Tabaie Jun 11, 2025
de55a27
feat: mimc.New to return StateStorer
Tabaie Jun 11, 2025
31a0a59
fix: single instance and no instance edge cases
Tabaie Jun 11, 2025
bb0eca0
Merge branch 'feat/gkr/add-instance' into feat/gkr/hashes
Tabaie Jun 11, 2025
db56157
fix: single-instance, circuit with depth
Tabaie Jun 11, 2025
7e4b954
Merge branch 'feat/gkr/add-instance' into feat/gkr/hashes
Tabaie Jun 11, 2025
b4544d6
Merge branch 'master' into feat/gkr/add-instance
Tabaie Jun 15, 2025
bdd01fd
Merge branch 'master' into feat/gkr/add-instance
Tabaie Jun 23, 2025
c170695
Merge branch 'master' into feat/gkr/add-instance
Tabaie Jul 2, 2025
70802ea
Merge branch 'master' into feat/gkr/add-instance
Tabaie Jul 7, 2025
4ca453c
docs: address cursor comments
Tabaie Jul 8, 2025
f2b1122
Merge branch 'master' into feat/gkr/add-instance
Tabaie Jul 9, 2025
b9c01be
Merge branch 'master' into feat/gkr/add-instance
Tabaie Jul 28, 2025
8e92d99
Merge branch 'feat/gkr/add-instance' into feat/gkr/hashes
Tabaie Jul 28, 2025
893ba91
Merge branch 'master' into feat/gkr/add-instance
Tabaie Aug 6, 2025
a13ac27
Merge branch 'master' into feat/gkr/add-instance
Tabaie Aug 19, 2025
8947d9f
refactor: remove MapRange
Tabaie Aug 19, 2025
4a09fd1
Merge branch 'master' into feat/gkr/add-instance
Tabaie Aug 28, 2025
929d732
Merge branch 'master' into feat/gkr/add-instance
Tabaie Sep 17, 2025
3ec0778
Merge branch 'feat/gkr/add-instance' into feat/gkr/hashes
Tabaie Sep 17, 2025
8c37435
fix: bad merge
Tabaie Sep 17, 2025
e6a64bc
bench: gkr mimc permutations
Tabaie Sep 17, 2025
d55dbf4
bench: gkr-mimc permutations
Tabaie Sep 17, 2025
d7eec96
Merge branch 'master' into feat/gkr/hashes
Tabaie Jan 7, 2026
610d49c
fix: match api changes
Tabaie Jan 7, 2026
8549a0b
fix: api use
Tabaie Jan 7, 2026
8bcce8f
remove engine_hints
Tabaie Jan 7, 2026
a045f11
revert change to engine.go
Tabaie Jan 7, 2026
9c35fd7
fix: mimc tests
Tabaie Jan 7, 2026
dd4e36a
fix: error message
Tabaie Jan 7, 2026
f2d2c2f
Merge branch 'master' into feat/gkr/hashes
Tabaie Jan 8, 2026
560e80e
fix: error on empty list
Tabaie Jan 8, 2026
bc1750c
Merge branch 'master' into feat/gkr/hashes
Tabaie Jan 9, 2026
fad4369
Merge branch 'master' into feat/gkr/hashes
Tabaie Jan 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions internal/generator/backend/template/gkr/gkr.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -771,13 +771,13 @@ func (gateAPI) Println(a ...frontend.Variable) {

for i, v := range a {
if _, err := x.SetInterface(v); err != nil {
toPrint[i] = x.String()
} else {
if s, ok := v.(string); ok {
toPrint[i] = s
continue
}
panic(fmt.Errorf("not numeric or string: %w", err))
} else {
toPrint[i] = x.String()
}
}
fmt.Println(toPrint...)
Expand Down
4 changes: 2 additions & 2 deletions internal/gkr/bls12-377/gkr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions internal/gkr/bls12-381/gkr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions internal/gkr/bls24-315/gkr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions internal/gkr/bls24-317/gkr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions internal/gkr/bn254/gkr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions internal/gkr/bw6-633/gkr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions internal/gkr/bw6-761/gkr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions internal/gkr/small_rational/gkr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 18 additions & 1 deletion std/hash/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package hash

import (
"fmt"

"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/math/uints"
)
Expand Down Expand Up @@ -114,7 +116,7 @@ type merkleDamgardHasher struct {

// NewMerkleDamgardHasher transforms a 2-1 one-way function into a hash
// initialState is a value whose preimage is not known
func NewMerkleDamgardHasher(api frontend.API, f Compressor, initialState frontend.Variable) FieldHasher {
func NewMerkleDamgardHasher(api frontend.API, f Compressor, initialState frontend.Variable) StateStorer {
return &merkleDamgardHasher{
state: initialState,
iv: initialState,
Expand All @@ -136,3 +138,18 @@ func (h *merkleDamgardHasher) Write(data ...frontend.Variable) {
func (h *merkleDamgardHasher) Sum() frontend.Variable {
return h.state
}

func (h *merkleDamgardHasher) State() []frontend.Variable {
return []frontend.Variable{h.state}
}

func (h *merkleDamgardHasher) SetState(state []frontend.Variable) error {
if h.state != h.iv {
return fmt.Errorf("the hasher is not in an initial state; reset before attempting to set the state")
}
if len(state) != 1 {
return fmt.Errorf("expected one state variable, got %d", len(state))
}
h.state = state[0]
return nil
}
17 changes: 17 additions & 0 deletions std/hash/mimc/gkr-mimc/gkr-mimc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package gkr_mimc

import (
"fmt"

"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/hash"
gkr_mimc "github.com/consensys/gnark/std/permutation/gkr-mimc"
)

func New(api frontend.API) (hash.StateStorer, error) {
f, err := gkr_mimc.NewCompressor(api)
if err != nil {
return nil, fmt.Errorf("could not create mimc hasher: %w", err)
}
return hash.NewMerkleDamgardHasher(api, f, 0), nil
}
172 changes: 172 additions & 0 deletions std/hash/mimc/gkr-mimc/gkr-mimc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package gkr_mimc

import (
"errors"
"fmt"
"os"
"path/filepath"
"slices"
"testing"

"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend/plonk"
"github.com/consensys/gnark/constraint"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/frontend/cs/scs"
"github.com/consensys/gnark/std/hash/mimc"
"github.com/consensys/gnark/test"
"github.com/stretchr/testify/require"
)

func TestGkrMiMC(t *testing.T) {
lengths := []int{1, 2, 3}
vals := make([]frontend.Variable, len(lengths)*2)
for i := range vals {
vals[i] = i + 1
}

for _, length := range lengths {
circuit := &testGkrMiMCCircuit{
In: make([]frontend.Variable, length*2),
}
assignment := &testGkrMiMCCircuit{
In: slices.Clone(vals[:length*2]),
}

test.NewAssert(t).CheckCircuit(circuit, test.WithValidAssignment(assignment))
}
}

type testGkrMiMCCircuit struct {
In []frontend.Variable
skipCheck bool
}

func (c *testGkrMiMCCircuit) Define(api frontend.API) error {
gkrmimc, err := New(api)
if err != nil {
return err
}

plainMiMC, err := mimc.New(api)
if err != nil {
return err
}

// first check that empty input is handled correctly
api.AssertIsEqual(gkrmimc.Sum(), plainMiMC.Sum())

ins := [][]frontend.Variable{c.In[:len(c.In)/2], c.In[len(c.In)/2:]}
for _, in := range ins {
gkrmimc.Reset()
gkrmimc.Write(in...)
res := gkrmimc.Sum()

if !c.skipCheck {
plainMiMC.Reset()
plainMiMC.Write(in...)
expected := plainMiMC.Sum()
api.AssertIsEqual(expected, res)
}
}

return nil
}

func TestGkrMiMCCompiles(t *testing.T) {
const n = 52000
circuit := testGkrMiMCCircuit{
In: make([]frontend.Variable, n),
}
cs, err := frontend.Compile(ecc.BLS12_377.ScalarField(), scs.NewBuilder, &circuit, frontend.WithCapacity(27_000_000))
require.NoError(t, err)
fmt.Println(cs.GetNbConstraints(), "constraints")
}

type hashTreeCircuit struct {
Leaves []frontend.Variable
}

func (c hashTreeCircuit) Define(api frontend.API) error {
if len(c.Leaves) == 0 {
return errors.New("no hashing to do")
}

hsh, err := New(api)
if err != nil {
return err
}

layer := slices.Clone(c.Leaves)

for len(layer) > 1 {
if len(layer)%2 == 1 {
layer = append(layer, 0) // pad with zero
}

for i := range len(layer) / 2 {
hsh.Reset()
hsh.Write(layer[2*i], layer[2*i+1])
layer[i] = hsh.Sum()
}

layer = layer[:len(layer)/2]
}

api.AssertIsDifferent(layer[0], 0)
return nil
}

func loadCs(t require.TestingT, fileTitle string, circuit frontend.Circuit) constraint.ConstraintSystem {
filename := filepath.Join(os.TempDir(), fileTitle)
_, err := os.Stat(filename)

if os.IsNotExist(err) {
// actually compile
cs, err := frontend.Compile(ecc.BLS12_377.ScalarField(), scs.NewBuilder, circuit)
require.NoError(t, err)
f, err := os.Create(filename)
require.NoError(t, err)
defer func() {
require.NoError(t, f.Close())
}()
_, err = cs.WriteTo(f)
require.NoError(t, err)
return cs
}

f, err := os.Open(filename)
require.NoError(t, err)
defer func() {
require.NoError(t, f.Close())
}()

cs := plonk.NewCS(ecc.BLS12_377)

_, err = cs.ReadFrom(f)
require.NoError(t, err)

return cs
}

func BenchmarkHashTree(b *testing.B) {
const size = 1 << 15 // about 2 ^ 16 total hashes

circuit := hashTreeCircuit{
Leaves: make([]frontend.Variable, size),
}
assignment := hashTreeCircuit{
Leaves: make([]frontend.Variable, size),
}

for i := range assignment.Leaves {
assignment.Leaves[i] = i
}

cs := loadCs(b, "gkrmimc_hashtree.cs", &circuit)

w, err := frontend.NewWitness(&assignment, ecc.BLS12_377.ScalarField())
require.NoError(b, err)

require.NoError(b, cs.IsSolved(w))
}
6 changes: 4 additions & 2 deletions std/hash/mimc/mimc.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func NewMiMC(api frontend.API) (MiMC, error) {
// NB! See the package documentation for length extension attack consideration.
//
// [gnark-crypto]: https://pkg.go.dev/github.com/consensys/gnark-crypto/hash
func New(api frontend.API) (hash.FieldHasher, error) {
func New(api frontend.API) (hash.StateStorer, error) {
h, err := NewMiMC(api)
if err != nil {
return nil, err
Expand All @@ -43,5 +43,7 @@ func New(api frontend.API) (hash.FieldHasher, error) {
}

func init() {
hash.Register(hash.MIMC, New)
hash.Register(hash.MIMC, func(api frontend.API) (hash.FieldHasher, error) {
return New(api)
})
}
Loading
Loading