Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] integrate zeknox GPU-acceleration library into gnark #1332

Open
wants to merge 65 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
e0a9c5a
log msm g1 g2 time, and add comment
doutv Oct 10, 2024
48e8cc7
log computeH time
doutv Oct 10, 2024
0a93689
init zeknox GPU acceleration
doutv Oct 10, 2024
e566588
MSM G1 & G2 acclerating! with local cuda repo
doutv Oct 16, 2024
ffd2781
sequencial GPU MSM & refactor
doutv Oct 17, 2024
e26498a
mimc test gpu acceleration
doutv Oct 17, 2024
e6eb42e
fix verify bug, delete channel
doutv Oct 17, 2024
31479f7
add p256 example for testing
doutv Oct 18, 2024
c481b0a
parallel but verify fail in most cases
doutv Oct 18, 2024
4cb00d6
fix msm cfg & add input check
doutv Oct 18, 2024
4d43c3e
fix parallel GPU proving, use errgroup
doutv Oct 18, 2024
6895eb1
small fix
doutv Oct 18, 2024
f52ad4c
add doc
doutv Oct 18, 2024
18e871d
set msm LargeBucketFactor config
doutv Oct 22, 2024
88237e2
update msmg1, msmg1 return affine
doutv Oct 23, 2024
26ba8db
fix cuda int
doutv Oct 23, 2024
d99fc59
generate witness in every prove
doutv Oct 24, 2024
6a13e9b
delete unused deviceInfo
doutv Oct 24, 2024
59bccd9
deviceInfo each points store ArePointsInMont
doutv Oct 24, 2024
fd2ace4
update cuda library, verify GPU proof success!
doutv Oct 24, 2024
a2694e0
refactor msm, 1 msm func for both G1 and G2
doutv Oct 24, 2024
8328573
parallel msm, sometimes verify fail
doutv Oct 24, 2024
8c49c6c
parallel + copy point every time
doutv Oct 24, 2024
8d84de2
serial GPU msm, always success
doutv Oct 24, 2024
554277a
small improvement in zeknox prover
dloghin Nov 5, 2024
48475b8
improve p256 example
dloghin Nov 20, 2024
48d719d
update zeknox to v1.0.0
dloghin Nov 21, 2024
2e0ef67
init zeknox GPU acceleration
doutv Oct 10, 2024
2da1853
MSM G1 & G2 acclerating! with local cuda repo
doutv Oct 16, 2024
70d36b2
sequencial GPU MSM & refactor
doutv Oct 17, 2024
be85d2a
fix verify bug, delete channel
doutv Oct 17, 2024
68f6664
parallel but verify fail in most cases
doutv Oct 18, 2024
3bd0c16
fix msm cfg & add input check
doutv Oct 18, 2024
3f8da26
fix parallel GPU proving, use errgroup
doutv Oct 18, 2024
91f00e7
small fix
doutv Oct 18, 2024
1faa8ba
add doc
doutv Oct 18, 2024
ea745dd
set msm LargeBucketFactor config
doutv Oct 22, 2024
915559f
update msmg1, msmg1 return affine
doutv Oct 23, 2024
134f437
fix cuda int
doutv Oct 23, 2024
2dd91be
delete unused deviceInfo
doutv Oct 24, 2024
5a38086
deviceInfo each points store ArePointsInMont
doutv Oct 24, 2024
9ca0eba
update cuda library, verify GPU proof success!
doutv Oct 24, 2024
7ef565a
refactor msm, 1 msm func for both G1 and G2
doutv Oct 24, 2024
c0073c9
parallel msm, sometimes verify fail
doutv Oct 24, 2024
c942aba
parallel + copy point every time
doutv Oct 24, 2024
7826d9c
serial GPU msm, always success
doutv Oct 24, 2024
e067460
small improvement in zeknox prover
dloghin Nov 5, 2024
80e74c1
update zeknox to v1.0.0
dloghin Nov 21, 2024
7fbb8ed
disable zeknox by default
doutv Nov 22, 2024
bb7d861
delete comment
doutv Nov 22, 2024
fd62f9b
Merge remote-tracking branch 'origin/master' into pr
doutv Nov 22, 2024
e26f6d1
restore
doutv Nov 22, 2024
4e4fef8
rename to zeknox
doutv Nov 22, 2024
41f3192
add guide in readme
doutv Nov 22, 2024
ea037dd
add zeknox build tag
dloghin Nov 27, 2024
70957a0
add zeknox build tag
dloghin Nov 27, 2024
8ff71e7
add zeknox build tag
dloghin Nov 27, 2024
8fccf0c
update readme
dloghin Nov 28, 2024
28c52db
Merge branch 'Consensys:master' into master
dloghin Nov 28, 2024
aaa21ac
merged with upstream master
dloghin Nov 28, 2024
b1dc00f
clean source code
dloghin Nov 29, 2024
b7da2ae
revert examples
doutv Dec 10, 2024
24c51c0
delete comment
doutv Dec 10, 2024
5080423
add zeknox sha3 example
doutv Dec 10, 2024
ea139bc
add warmup and multiple runs flag
dloghin Jan 9, 2025
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,5 @@ gnarkd/circuits/**
go.work
go.work.sum

examples/gbotrel/**
examples/gbotrel/**
build/
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,40 @@ func main() {

### GPU Support

#### Zeknox Library
Unlock free GPU acceleration with [OKX zeknox library](https://github.com/okx/zeknox).

##### Download prebuilt binaries
```sh
curl -L -o libzeknox.a https://github.com/okx/zeknox/releases/download/v1.0.0/bn254-msm-86-89-90-libzeknox.a
curl -L -o libblst.a https://github.com/okx/zeknox/releases/download/v1.0.0/libblst.a
sudo cp libblst.a libzeknox.a /usr/local/lib/
```

If you want to build from source, see guide in https://github.com/okx/zeknox.

##### Enjoy GPU

`groth16.Prove(r1cs, pk, witnessData, backend.WithZeknoxAcceleration())`

```sh
go run -tags=zeknox examples/zeknox/main.go
# (place -tags before the filename)
```

##### Test
Add following code to [mimc_test.go](examples/mimc/mimc_test.go)
```go
assert.ProverSucceeded(&mimcCircuit, &Circuit{
PreImage: "16130099170765464552823636852555369511329944820189892919423002775646948828469",
Hash: "12886436712380113721405259596386800092738845035233065858332878701083870690753",
}, test.WithCurves(ecc.BN254), test.WithProverOpts(backend.WithZeknoxAcceleration()))
```

```sh
go test github.com/consensys/gnark/examples/mimc -tags=prover_checks,zeknox
```

#### Icicle Library

The following schemes and curves support experimental use of Ingonyama's Icicle GPU library for low level zk-SNARK primitives such as MSM, NTT, and polynomial operations:
Expand All @@ -178,7 +212,7 @@ You can then toggle on or off icicle acceleration by providing the `WithIcicleAc
```go
// toggle on
proofIci, err := groth16.Prove(ccs, pk, secretWitness, backend.WithIcicleAcceleration())

// toggle off
proof, err := groth16.Prove(ccs, pk, secretWitness)
```
Expand Down
13 changes: 13 additions & 0 deletions backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,19 @@ func WithProverKZGFoldingHashFunction(hFunc hash.Hash) ProverOption {
}
}

// WithZeknoxAcceleration requests to use [ZEKNOX] GPU proving backend for the
// prover. This option requires that the program is compiled with `zeknox` build
// tag and the ZEKNOX dependencies are properly installed. See [ZEKNOX] for
// installation description.
//
// [ZEKNOX]: https://github.com/okx/zeknox
func WithZeknoxAcceleration() ProverOption {
return func(pc *ProverConfig) error {
pc.Accelerator = "zeknox"
return nil
}
}

// WithIcicleAcceleration requests to use [ICICLE] GPU proving backend for the
// prover. This option requires that the program is compiled with `icicle` build
// tag and the ICICLE dependencies are properly installed. See [ICICLE] for
Expand Down
2 changes: 2 additions & 0 deletions backend/groth16/bn254/prove.go

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

2 changes: 2 additions & 0 deletions backend/groth16/bn254/zeknox/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package zeknox_bn254 implements zeknox acceleration for BN254 Groth16 backend.
package zeknox_bn254
67 changes: 67 additions & 0 deletions backend/groth16/bn254/zeknox/marshal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package zeknox_bn254_test

import (
"bytes"
"testing"

"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend/groth16"
groth16_bn254 "github.com/consensys/gnark/backend/groth16/bn254"
zeknox_bn254 "github.com/consensys/gnark/backend/groth16/bn254/zeknox"
cs_bn254 "github.com/consensys/gnark/constraint/bn254"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/frontend/cs/r1cs"
"github.com/consensys/gnark/test"
)

type circuit struct {
A, B frontend.Variable `gnark:",public"`
Res frontend.Variable
}

func (c *circuit) Define(api frontend.API) error {
api.AssertIsEqual(api.Mul(c.A, c.B), c.Res)
return nil
}

func TestMarshalNative(t *testing.T) {
assert := test.NewAssert(t)
ccs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit{})
assert.NoError(err)
tCcs := ccs.(*cs_bn254.R1CS)
nativePK := groth16_bn254.ProvingKey{}
nativeVK := groth16_bn254.VerifyingKey{}
err = groth16_bn254.Setup(tCcs, &nativePK, &nativeVK)
assert.NoError(err)

pk := groth16.NewProvingKey(ecc.BN254)
buf := new(bytes.Buffer)
_, err = nativePK.WriteTo(buf)
assert.NoError(err)
_, err = pk.ReadFrom(buf)
assert.NoError(err)
if pk.IsDifferent(&nativePK) {
t.Error("marshal output difference")
}
}

func TestMarshalZeknox(t *testing.T) {
assert := test.NewAssert(t)
ccs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit{})
assert.NoError(err)
tCcs := ccs.(*cs_bn254.R1CS)
zePK := zeknox_bn254.ProvingKey{}
VK := groth16_bn254.VerifyingKey{}
err = zeknox_bn254.Setup(tCcs, &zePK, &VK)
assert.NoError(err)

nativePK := groth16_bn254.ProvingKey{}
buf := new(bytes.Buffer)
_, err = zePK.WriteTo(buf)
assert.NoError(err)
_, err = nativePK.ReadFrom(buf)
assert.NoError(err)
if zePK.IsDifferent(&nativePK) {
t.Error("marshal output difference")
}
}
34 changes: 34 additions & 0 deletions backend/groth16/bn254/zeknox/nozeknox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//go:build !zeknox

package zeknox_bn254

import (
"fmt"

"github.com/consensys/gnark/backend"
groth16_bn254 "github.com/consensys/gnark/backend/groth16/bn254"
"github.com/consensys/gnark/backend/witness"
cs "github.com/consensys/gnark/constraint/bn254"
)

type ProvingKey struct {
groth16_bn254.ProvingKey
}

const HasZeknox = false

func Prove(r1cs *cs.R1CS, pk *ProvingKey, fullWitness witness.Witness, opts ...backend.ProverOption) (*groth16_bn254.Proof, error) {
return nil, fmt.Errorf("zeknox backend requested but program compiled without 'zeknox' build tag")
}

func Setup(r1cs *cs.R1CS, pk *ProvingKey, vk *groth16_bn254.VerifyingKey) error {
return groth16_bn254.Setup(r1cs, &pk.ProvingKey, vk)
}

func DummySetup(r1cs *cs.R1CS, pk *ProvingKey) error {
return groth16_bn254.DummySetup(r1cs, &pk.ProvingKey)
}

func (pk *ProvingKey) Free() {
// nothing to do here
}
55 changes: 55 additions & 0 deletions backend/groth16/bn254/zeknox/provingkey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//go:build zeknox

package zeknox_bn254

import (
"github.com/consensys/gnark-crypto/ecc/bn254"
groth16_bn254 "github.com/consensys/gnark/backend/groth16/bn254"
cs "github.com/consensys/gnark/constraint/bn254"
"github.com/okx/zeknox/wrappers/go/device"
)

type deviceInfo struct {
G1Device struct {
A, B, K, Z DevicePoints[bn254.G1Affine]
}
G2Device struct {
B DevicePoints[bn254.G2Affine]
}
InfinityPointIndicesK []int
}

type ProvingKey struct {
groth16_bn254.ProvingKey
*deviceInfo
}

type DevicePoints[T bn254.G1Affine | bn254.G2Affine] struct {
*device.HostOrDeviceSlice[T]
// Gnark points are in Montgomery form
// After 1 GPU MSM, points in GPU are converted to affine form
// Pass it to MSM config
Mont bool
}

func Setup(r1cs *cs.R1CS, pk *ProvingKey, vk *groth16_bn254.VerifyingKey) error {
return groth16_bn254.Setup(r1cs, &pk.ProvingKey, vk)
}

func DummySetup(r1cs *cs.R1CS, pk *ProvingKey) error {
return groth16_bn254.DummySetup(r1cs, &pk.ProvingKey)
}

// You should call this method to free the GPU memory
//
// pk := groth16.NewProvingKey(ecc.BN254)
// defer pk.(*zeknox_bn254.ProvingKey).Free()
func (pk *ProvingKey) Free() {
if pk.deviceInfo != nil {
pk.deviceInfo.G1Device.A.Free()
pk.deviceInfo.G1Device.B.Free()
pk.deviceInfo.G1Device.K.Free()
pk.deviceInfo.G1Device.Z.Free()
pk.deviceInfo.G2Device.B.Free()
}
}
Loading