Consensys / gnark

gnark is a fast zk-SNARK library that offers a high-level API to design circuits. The library is open source and developed under the Apache 2.0 license
https://hackmd.io/@gnark
Apache License 2.0
1.45k stars 380 forks source link

Update ICICLE integration to use v3 ICICLE #1318

Open jeremyfelder opened 1 week ago

jeremyfelder commented 1 week ago

Description

This PR updates the ICICLE integration to use v3 of ICICLE.

Fixes #1166

Type of change

How has this been tested?

package main

import (
    "fmt"
    "time"

    "github.com/consensys/gnark-crypto/ecc"
    "github.com/consensys/gnark/backend"
    "github.com/consensys/gnark/backend/groth16"
    "github.com/consensys/gnark/frontend"
    "github.com/consensys/gnark/frontend/cs/r1cs"
)

// CubicCircuit defines a simple circuit
// x**3 + x + 5 == y
type CubicCircuit struct {
    // struct tags on a variable is optional
    // default uses variable name and secret visibility.
    X frontend.Variable `gnark:"x"`
    Y frontend.Variable `gnark:",public"`
}

// Define declares the circuit constraints
// x**3 + x + 5 == y
func (circuit *CubicCircuit) Define(api frontend.API) error {
    x3 := api.Mul(circuit.X, circuit.X, circuit.X)
    for i := 0; i < 1000000; i++ {
        api.AssertIsEqual(circuit.Y, api.Add(x3, circuit.X, 5))
    }
    return nil
}

func main() {
    // compiles our circuit into a R1CS
    var circuit CubicCircuit
    ccs, _ := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit)

    // groth16 zkSNARK: Setup
    pk, vk, _ := groth16.Setup(ccs)

    // witness definition
    assignment := CubicCircuit{X: 3, Y: 35}
    witness, _ := frontend.NewWitness(&assignment, ecc.BN254.ScalarField())
    publicWitness, _ := witness.Public()
    // groth16: Prove & Verify
    icicleTimeStart := time.Now()
    proof, err := groth16.Prove(ccs, pk, witness, backend.WithIcicleAcceleration())
    fmt.Println("Icicle proof time:", time.Since(icicleTimeStart))

    if err != nil {
        fmt.Println(err)
    }

    if err = groth16.Verify(proof, vk, publicWitness); err != nil {
        panic("Failed verification")
    }

    gnarkTimeStart := time.Now()
    proofNoIcicle, err := groth16.Prove(ccs, pk, witness)
    fmt.Println("Gnark CPU proof time:", time.Since(gnarkTimeStart))

    if err != nil {
        fmt.Println(err)
    }

    if err = groth16.Verify(proofNoIcicle, vk, publicWitness); err != nil {
        panic("Failed verification")
    }
}

How has this been benchmarked?

Checklist:

p4u commented 6 days ago

hey @jeremyfelder, can you try with bls12377 ?

Because I managed to make it work on bn254, but the same code on bls12377, icicle acceleration is just ignored.

I'm compiling the Go icicle wrapper with ./build -curves=all so it should be available (acually I see the compilation traces on the bls12377).

jeremyfelder commented 5 days ago

hey @jeremyfelder, can you try with bls12377 ?

Because I managed to make it work on bn254, but the same code on bls12377, icicle acceleration is just ignored.

I'm compiling the Go icicle wrapper with ./build -curves=all so it should be available (acually I see the compilation traces on the bls12377).

Great to hear that you got bn254 working 🔥! Right now the gnark<>ICICLE integration only includes bn254. It should be relatively simple to add all the curves/fields that ICICLE supports though I didn't want to bloat this PR with something that should be designed better to stay updated as @ivokub and I have discussed in the past.

ivokub commented 5 days ago

hey @jeremyfelder, can you try with bls12377 ? Because I managed to make it work on bn254, but the same code on bls12377, icicle acceleration is just ignored. I'm compiling the Go icicle wrapper with ./build -curves=all so it should be available (acually I see the compilation traces on the bls12377).

Great to hear that you got bn254 working 🔥! Right now the gnark<>ICICLE integration only includes bn254. It should be relatively simple to add all the curves/fields that ICICLE supports though I didn't want to bloat this PR with something that should be designed better to stay updated as @ivokub and I have discussed in the past.

Yep - I'll try to review and merge this PR promptly and then figure out a bit better to switch between accelerated and non-accelerated implementations. Or see if the current approach scales to different curves nicely.