diff --git a/batcher/build.rs b/batcher/build.rs index 4f35ad7f4c..53f7c57042 100644 --- a/batcher/build.rs +++ b/batcher/build.rs @@ -1,7 +1,8 @@ use std::{env, path::PathBuf, process::Command}; const GO_SRC: &str = "./gnark/verifier.go"; -const GO_OUT: &str = "libgo.a"; +const GO_OUT: &str = "libverifier.a"; +const GO_LIB: &str = "verifier"; fn main() { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); @@ -20,5 +21,15 @@ fn main() { "cargo:rustc-link-search=native={}", out_dir.to_str().unwrap() ); - println!("cargo:rustc-link-lib=static=go"); + + if cfg!(target_os = "linux") { + println!("cargo:rustc-link-lib=dylib=dl"); + println!("cargo:rustc-link-lib=dylib=rt"); + println!("cargo:rustc-link-lib=dylib=m"); + println!("cargo:rustc-link-lib=dylib=ssl"); + println!("cargo:rustc-link-lib=dylib=crypto"); + println!("cargo:rustc-link-arg=-Wl,--allow-multiple-definition"); + } + + println!("cargo:rustc-link-lib=static={}", GO_LIB); } diff --git a/batcher/gnark/go.mod b/batcher/gnark/go.mod index 0197ac684c..bce1eefb41 100644 --- a/batcher/gnark/go.mod +++ b/batcher/gnark/go.mod @@ -6,3 +6,25 @@ require ( github.com/consensys/gnark v0.10.0 github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e ) + +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/ingonyama-zk/icicle v0.0.0-20230928131117-97f0079e5c71 // indirect + github.com/ingonyama-zk/iciclegnark v0.1.0 // 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/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 +) diff --git a/batcher/gnark/go.sum b/batcher/gnark/go.sum index e85fa890a7..c06612d603 100644 --- a/batcher/gnark/go.sum +++ b/batcher/gnark/go.sum @@ -1,4 +1,72 @@ -github.com/consensys/gnark v0.9.0/go.mod h1:Sy9jJjIaGJFfNeupyNOR9Ei2IbAB6cfCO78DfG27YvM= +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.10.0 h1:yhi6ThoeFP7WrH8zQDaO56WVXe9iJEBSkfrZ9PZxabw= github.com/consensys/gnark v0.10.0/go.mod h1:VJU5JrrhZorbfDH+EUjcuFWr2c5z19tHPh8D6KVQksU= -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/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/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/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/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +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/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +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/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/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +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= diff --git a/batcher/gnark/verifier.go b/batcher/gnark/verifier.go index 43d360680b..4acba01a8a 100644 --- a/batcher/gnark/verifier.go +++ b/batcher/gnark/verifier.go @@ -1,34 +1,55 @@ package main +/* +#include +#include + +typedef struct ListRef { + const uint8_t *ptr; + uintptr_t len; +} ListRef; + + +*/ +import "C" + import ( - "C" "bytes" "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark/backend/groth16" "github.com/consensys/gnark/backend/plonk" "github.com/consensys/gnark/backend/witness" "log" + "unsafe" ) +func listRefToBytes(listRef C.ListRef) []byte { + return C.GoBytes(unsafe.Pointer(listRef.ptr), C.int(listRef.len)) +} + func main() {} //export VerifyPlonkProofBLS12_381 -func VerifyPlonkProofBLS12_381(proofBytes []byte, pubInputBytes []byte, verificationKeyBytes []byte) bool { +func VerifyPlonkProofBLS12_381(proofBytes C.ListRef, pubInputBytes C.ListRef, verificationKeyBytes C.ListRef) bool { return verifyPlonkProof(proofBytes, pubInputBytes, verificationKeyBytes, ecc.BLS12_381) } //export VerifyPlonkProofBN254 -func VerifyPlonkProofBN254(proofBytes []byte, pubInputBytes []byte, verificationKeyBytes []byte) bool { +func VerifyPlonkProofBN254(proofBytes C.ListRef, pubInputBytes C.ListRef, verificationKeyBytes C.ListRef) bool { return verifyPlonkProof(proofBytes, pubInputBytes, verificationKeyBytes, ecc.BN254) } //export VerifyGroth16ProofBN254 -func VerifyGroth16ProofBN254(proofBytes []byte, pubInputBytes []byte, verificationKeyBytes []byte) bool { +func VerifyGroth16ProofBN254(proofBytes C.ListRef, pubInputBytes C.ListRef, verificationKeyBytes C.ListRef) bool { return verifyGroth16Proof(proofBytes, pubInputBytes, verificationKeyBytes, ecc.BN254) } // verifyPlonkProof contains the common proof verification logic. -func verifyPlonkProof(proofBytes []byte, pubInputBytes []byte, verificationKeyBytes []byte, curve ecc.ID) bool { +func verifyPlonkProof(proofBytesRef C.ListRef, pubInputBytesRef C.ListRef, verificationKeyBytesRef C.ListRef, curve ecc.ID) bool { + proofBytes := listRefToBytes(proofBytesRef) + pubInputBytes := listRefToBytes(pubInputBytesRef) + verificationKeyBytes := listRefToBytes(verificationKeyBytesRef) + proofReader := bytes.NewReader(proofBytes) proof := plonk.NewProof(curve) if _, err := proof.ReadFrom(proofReader); err != nil { @@ -59,7 +80,11 @@ func verifyPlonkProof(proofBytes []byte, pubInputBytes []byte, verificationKeyBy } // verifyGroth16Proof contains the common proof verification logic. -func verifyGroth16Proof(proofBytes []byte, pubInputBytes []byte, verificationKeyBytes []byte, curve ecc.ID) bool { +func verifyGroth16Proof(proofBytesRef C.ListRef, pubInputBytesRef C.ListRef, verificationKeyBytesRef C.ListRef, curve ecc.ID) bool { + proofBytes := listRefToBytes(proofBytesRef) + pubInputBytes := listRefToBytes(pubInputBytesRef) + verificationKeyBytes := listRefToBytes(verificationKeyBytesRef) + proofReader := bytes.NewReader(proofBytes) proof := groth16.NewProof(curve) if _, err := proof.ReadFrom(proofReader); err != nil { @@ -74,14 +99,14 @@ func verifyGroth16Proof(proofBytes []byte, pubInputBytes []byte, verificationKey return false } if _, err = pubInput.ReadFrom(pubInputReader); err != nil { - log.Printf("Could not read PLONK public input: %v", err) + log.Printf("Could not read Groth16 public input: %v", err) return false } verificationKeyReader := bytes.NewReader(verificationKeyBytes) verificationKey := groth16.NewVerifyingKey(curve) if _, err = verificationKey.ReadFrom(verificationKeyReader); err != nil { - log.Printf("Could not read PLONK verifying key from bytes: %v", err) + log.Printf("Could not read Groth16 verifying key from bytes: %v", err) return false } diff --git a/batcher/src/gnark/mod.rs b/batcher/src/gnark/mod.rs index 5247f578ed..6c9f4b4d0b 100644 --- a/batcher/src/gnark/mod.rs +++ b/batcher/src/gnark/mod.rs @@ -1,52 +1,51 @@ use crate::types::ProvingSystemId; +#[derive(Copy, Clone, Debug)] #[repr(C)] -pub struct GoSlice { +pub struct ListRef { data: *const u8, len: usize, - cap: usize, } -impl From> for GoSlice { +impl From> for ListRef { fn from(v: Vec) -> Self { - Self::from(&v) + Self::from(v.as_slice()) } } -impl From<&Vec> for GoSlice { +impl From<&Vec> for ListRef { fn from(v: &Vec) -> Self { Self::from(v.as_slice()) } } -impl From<&[u8]> for GoSlice { +impl From<&[u8]> for ListRef { fn from(v: &[u8]) -> Self { let len = v.len(); - let cap = v.len(); - let data = v.as_ptr(); - GoSlice { data, len, cap } + let data = v.as_ptr().cast(); + ListRef{data, len} } } pub fn verify_gnark( proving_system: &ProvingSystemId, - proof: &[u8], - public_input: &[u8], - verification_key: &[u8], + proof: &Vec, + public_input: &Vec, + verification_key: &Vec, ) -> bool { - let proof = GoSlice::from(proof); - let public_input = GoSlice::from(public_input); - let verification_key = GoSlice::from(verification_key); + let proof = proof.into(); + let public_input = public_input.into(); + let verification_key = verification_key.into(); match proving_system { ProvingSystemId::GnarkPlonkBn254 => unsafe { - VerifyPlonkProofBN254(&proof, &public_input, &verification_key) + VerifyPlonkProofBN254(proof, public_input, verification_key) }, ProvingSystemId::GnarkPlonkBls12_381 => unsafe { - VerifyPlonkProofBLS12_381(&proof, &public_input, &verification_key) + VerifyPlonkProofBLS12_381(proof, public_input, verification_key) }, ProvingSystemId::Groth16Bn254 => unsafe { - VerifyGroth16ProofBN254(&proof, &public_input, &verification_key) + VerifyGroth16ProofBN254(proof, public_input, verification_key) }, _ => panic!("Unsupported proving system"), } @@ -54,18 +53,18 @@ pub fn verify_gnark( extern "C" { pub fn VerifyPlonkProofBLS12_381( - proof: &GoSlice, - public_input: &GoSlice, - verification_key: &GoSlice, + proof: ListRef, + public_input: ListRef, + verification_key: ListRef, ) -> bool; pub fn VerifyPlonkProofBN254( - proof: &GoSlice, - public_input: &GoSlice, - verification_key: &GoSlice, + proof: ListRef, + public_input: ListRef, + verification_key: ListRef, ) -> bool; pub fn VerifyGroth16ProofBN254( - proof: &GoSlice, - public_input: &GoSlice, - verification_key: &GoSlice, + proof: ListRef, + public_input: ListRef, + verification_key: ListRef, ) -> bool; } diff --git a/batcher/src/types/mod.rs b/batcher/src/types/mod.rs index 5baae81116..a3e568d6d6 100644 --- a/batcher/src/types/mod.rs +++ b/batcher/src/types/mod.rs @@ -59,12 +59,12 @@ impl VerificationData { ProvingSystemId::GnarkPlonkBls12_381 | ProvingSystemId::GnarkPlonkBn254 | ProvingSystemId::Groth16Bn254 => { - let vk = &self + let vk = self .verification_key .as_ref() .expect("Verification key is required"); - let pub_input = &self.pub_input.as_ref().expect("Public input is required"); + let pub_input = self.pub_input.as_ref().expect("Public input is required"); let is_valid = verify_gnark(&self.proving_system, &self.proof, pub_input, vk); debug!("Gnark proof is valid: {}", is_valid); is_valid