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

support converting our rapidsnark proofs into gnark format (WIP) #1395

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
296 changes: 296 additions & 0 deletions crypto/zk/prover/prover_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package prover

import (
"encoding/hex"
"encoding/json"
"fmt"
"log"
"math/big"
"os"
"testing"

"go.vocdoni.io/dvote/util"

"github.com/consensys/gnark-crypto/ecc/bn254"
"github.com/consensys/gnark-crypto/ecc/bn254/fp"
groth16_bn254 "github.com/consensys/gnark/backend/groth16/bn254"
qt "github.com/frankban/quicktest"
)

Expand Down Expand Up @@ -135,3 +143,291 @@
err = wrongProof.Verify(vkey2)
qt.Assert(t, err, qt.IsNotNil)
}

func TestGnark(t *testing.T) {
// Generate proof
proof, _ := Prove(zkey, wasm, inputs)

t.Logf("%+v", prettyPrint(proof))

gnarkproof := ProofToGnarkProof(proof)

_ = sp1WitnessInput(inputs)

sp1proof := GnarkProofToSP1Proof(gnarkproof, WitnessInput{
"1234", // this should be the hash of the verification key (in gnark binary format) vk.hash_bn254().as_canonical_biguint()
"5678", // and this the hash of the SP1PublicValues public_values.hash_bn254()
})

t.Logf("%+v", prettyPrint(sp1proof))
}

func sp1WitnessInput(inputs []byte) WitnessInput {
witnessInput := WitnessInput{}
gnarkVK, err := parseVKForGnark(vkey)
if err != nil {
panic(err)
}
fmt.Printf("%+v", prettyPrint(gnarkVK))

witnessInput.VkeyHash = hashBN254(gnarkVK) // TODO
witnessInput.CommitedValuesDigest = hashBN254(inputs) // TODO
return witnessInput
}

func hashBN254(any) string {
return "deadcode"
}

func prettyPrint(v interface{}) string {
// Convert the struct to a pretty JSON format
prettyJSON, err := json.MarshalIndent(v, "", " ")
if err != nil {
panic(err)
}
return string(prettyJSON)
}

// Function to convert a hex string to a big.Int
func hexToBigInt(hexStr string) (*big.Int, error) {

Check failure on line 192 in crypto/zk/prover/prover_test.go

View workflow job for this annotation

GitHub Actions / job_go_checks

func hexToBigInt is unused (U1000)
data, err := hex.DecodeString(util.TrimHex(hexStr))
if err != nil {
return nil, err
}
return new(big.Int).SetBytes(data), nil
}

func ProofToGnarkProof(proof *Proof) *groth16_bn254.Proof {
gnarkproof, err := convertToGnarkProof(proof.Data)
if err != nil {
log.Fatal(err)
}
return gnarkproof
}

// Convert ProofData to gnark-compatible Groth16 proof
func convertToGnarkProof(pd ProofData) (*groth16_bn254.Proof, error) {
gnarkProof := &groth16_bn254.Proof{}

// Convert pi_a (G1) - Point A
aXBigInt, err := stringToBigInt(pd.A[0])
if err != nil {
return gnarkProof, err
}
aYBigInt, err := stringToBigInt(pd.A[1])
if err != nil {
return gnarkProof, err
}

// Initialize fr.Element for A point
var aX, aY fp.Element
aX.SetBigInt(aXBigInt)
aY.SetBigInt(aYBigInt)

gnarkProof.Ar = bn254.G1Affine{
X: aX,
Y: aY,
}

// Convert pi_b (G2) - Point B
bX0BigInt, err := stringToBigInt(pd.B[0][0])
if err != nil {
return gnarkProof, err
}
bX1BigInt, err := stringToBigInt(pd.B[0][1])
if err != nil {
return gnarkProof, err
}
bY0BigInt, err := stringToBigInt(pd.B[1][0])
if err != nil {
return gnarkProof, err
}
bY1BigInt, err := stringToBigInt(pd.B[1][1])
if err != nil {
return gnarkProof, err
}

// Initialize fr.Element for B points
var bX0, bX1, bY0, bY1 fp.Element
bX0.SetBigInt(bX0BigInt)
bX1.SetBigInt(bX1BigInt)
bY0.SetBigInt(bY0BigInt)
bY1.SetBigInt(bY1BigInt)

// Construct the G2 element for Bs (G2Affine expects fptower.E2 for both X and Y)
gnarkProof.Bs.X.A0 = bX0
gnarkProof.Bs.X.A1 = bX1
gnarkProof.Bs.Y.A0 = bY0
gnarkProof.Bs.Y.A1 = bY1

// Convert pi_c (G1) - Point C
cXBigInt, err := stringToBigInt(pd.C[0])
if err != nil {
return gnarkProof, err
}
cYBigInt, err := stringToBigInt(pd.C[1])
if err != nil {
return gnarkProof, err
}

// Initialize fr.Element for C point
var cX, cY fp.Element
cX.SetBigInt(cXBigInt)
cY.SetBigInt(cYBigInt)

gnarkProof.Krs.X = cX
gnarkProof.Krs.Y = cY

return gnarkProof, nil
}

// WitnessInput is copypasta from sp1
type WitnessInput struct {
VkeyHash string `json:"vkey_hash"`
CommitedValuesDigest string `json:"commited_values_digest"`
}

// SP1Proof is copypasta from sp1
type SP1Proof struct {
PublicInputs [2]string `json:"public_inputs"`
EncodedProof string `json:"encoded_proof"`
RawProof string `json:"raw_proof"`
}

func GnarkProofToSP1Proof(proof *groth16_bn254.Proof, witnessInput WitnessInput) SP1Proof {
var publicInputs [2]string
publicInputs[0] = witnessInput.VkeyHash
publicInputs[1] = witnessInput.CommitedValuesDigest

encodedProof := proof.MarshalSolidity()

return SP1Proof{
PublicInputs: publicInputs,
EncodedProof: hex.EncodeToString(encodedProof),
// RawProof: hex.EncodeToString(proofBytes), // this field is uninteresting AFAIU
}
}

// Verification Key

// vkJSON is the format of the verification key from go-rapidsnark, copypasta from
// ~/go/pkg/mod/github.com/iden3/go-rapidsnark/[email protected]/parser.go
type vkJSON struct {
Alpha []string `json:"vk_alpha_1"`
Beta [][]string `json:"vk_beta_2"`
Gamma [][]string `json:"vk_gamma_2"`
Delta [][]string `json:"vk_delta_2"`
IC [][]string `json:"IC"`
}

// Converts hexadecimal string to a field element (fr.Element)
func hexToFieldElement(hexStr string) (fp.Element, error) {
var elem fp.Element
bigInt, success := new(big.Int).SetString(hexStr, 10) // assuming decimal strings
if !success {
return elem, fmt.Errorf("invalid field element: %s", hexStr)
}
elem.SetBigInt(bigInt)
return elem, nil
}

// Converts a slice of string to a G1 point
func stringToG1(coords []string) (bn254.G1Affine, error) {
var p bn254.G1Affine
if len(coords) != 3 {
return p, fmt.Errorf("invalid G1 coordinates: %v", coords)
}
x, err := hexToFieldElement(coords[0])
if err != nil {
return p, err
}
y, err := hexToFieldElement(coords[1])
if err != nil {
return p, err
}
p.X = x
p.Y = y
return p, nil
}

// Converts a slice of string to a G2 point
func stringToG2(coords [][]string) (bn254.G2Affine, error) {
var p bn254.G2Affine
if len(coords) != 3 {
return p, fmt.Errorf("invalid G2 coordinates")
}

// Convert X (A0, A1)
xA0, err := hexToFieldElement(coords[0][0])
if err != nil {
return p, err
}
xA1, err := hexToFieldElement(coords[0][1])
if err != nil {
return p, err
}

// Convert Y (A0, A1)
yA0, err := hexToFieldElement(coords[1][0])
if err != nil {
return p, err
}
yA1, err := hexToFieldElement(coords[1][1])
if err != nil {
return p, err
}

p.X.A0, p.X.A1 = xA0, xA1
p.Y.A0, p.Y.A1 = yA0, yA1
return p, nil
}

// Parses the vkJSON into gnark's groth16.VerifyingKey
func parseVKForGnark(vkjson []byte) (*groth16_bn254.VerifyingKey, error) {
var vkStr vkJSON
err := json.Unmarshal(vkjson, &vkStr)
if err != nil {
return nil, fmt.Errorf("Error parsing verification key JSON: %w", err)
}

vk := new(groth16_bn254.VerifyingKey)

// Parse Alpha (G1 point)
alpha, err := stringToG1(vkStr.Alpha)
if err != nil {
return nil, err
}
vk.G1.Alpha = alpha

// Parse Beta (G2 point)
beta, err := stringToG2(vkStr.Beta)
if err != nil {
return nil, err
}
vk.G2.Beta = beta

// Parse Gamma (G2 point)
gamma, err := stringToG2(vkStr.Gamma)
if err != nil {
return nil, err
}
vk.G2.Gamma = gamma

// Parse Delta (G2 point)
delta, err := stringToG2(vkStr.Delta)
if err != nil {
return nil, err
}
vk.G2.Delta = delta

// Parse IC (G1 points array)
for _, icCoords := range vkStr.IC {
icPoint, err := stringToG1(icCoords)
if err != nil {
return nil, err
}
vk.G1.K = append(vk.G1.K, icPoint)
}

return vk, nil
}
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ require (
github.com/cometbft/cometbft v1.0.0-alpha.1
github.com/cometbft/cometbft-db v0.9.1
github.com/cometbft/cometbft/api v1.0.0-alpha.1
github.com/consensys/gnark v0.10.0
github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e
github.com/ethereum/go-ethereum v1.14.7
github.com/fatih/color v1.16.0
github.com/frankban/quicktest v1.14.6
Expand Down Expand Up @@ -88,7 +90,6 @@ require (
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.12.1 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cosmos/gogoproto v1.5.0 // indirect
Expand All @@ -115,6 +116,7 @@ require (
github.com/flynn/noise v1.1.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.5.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/go-chi/chi v4.1.2+incompatible // indirect
Expand Down Expand Up @@ -301,6 +303,7 @@ require (
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 // indirect
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
Expand Down
14 changes: 12 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,11 @@ github.com/cometbft/cometbft/api v1.0.0-alpha.1/go.mod h1:5vJTKMdvGufLjyQ0fqSfZ1
github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ=
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.10.0 h1:yhi6ThoeFP7WrH8zQDaO56WVXe9iJEBSkfrZ9PZxabw=
github.com/consensys/gnark v0.10.0/go.mod h1:VJU5JrrhZorbfDH+EUjcuFWr2c5z19tHPh8D6KVQksU=
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q=
github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M=
github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY=
github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e h1:MKdOuCiy2DAX1tMp2YsmtNDaqdigpY6B5cZQDJ9BvEo=
github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e/go.mod h1:wKqwsieaKPThcFkHe0d0zMsbHEUWFmZcG7KBCse210o=
github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
Expand Down Expand Up @@ -378,6 +380,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
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/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
Expand Down Expand Up @@ -665,6 +669,10 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
github.com/ingonyama-zk/icicle v0.0.0-20230928131117-97f0079e5c71 h1:YxI1RTPzpFJ3MBmxPl3Bo0F7ume7CmQEC1M9jL6CT94=
github.com/ingonyama-zk/icicle v0.0.0-20230928131117-97f0079e5c71/go.mod h1:kAK8/EoN7fUEmakzgZIYdWy1a2rBnpCaZLqSHwZWxEk=
github.com/ingonyama-zk/iciclegnark v0.1.0 h1:88MkEghzjQBMjrYRJFxZ9oR9CTIpB8NG2zLeCJSvXKQ=
github.com/ingonyama-zk/iciclegnark v0.1.0/go.mod h1:wz6+IpyHKs6UhMMoQpNqz1VY+ddfKqC/gRwR/64W6WU=
github.com/ipfs-shipyard/nopfs v0.0.12 h1:mvwaoefDF5VI9jyvgWCmaoTJIJFAfrbyQV5fJz35hlk=
github.com/ipfs-shipyard/nopfs v0.0.12/go.mod h1:mQyd0BElYI2gB/kq/Oue97obP4B3os4eBmgfPZ+hnrE=
github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7UynTbtdlt+w08ggb1UGLGaGjp1mMaZhoTZSctpn5Ak=
Expand Down Expand Up @@ -1506,6 +1514,8 @@ github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
Expand Down
Loading