Skip to content

Commit

Permalink
feat: implement Plonk Bn254 proof verification for Solidity format
Browse files Browse the repository at this point in the history
- Introduced a new `VerifySolidity` function in `verify.go` for proof verification with Solidity, complete with unmarshalling of solidity proof, public witness creation, and proof verification
- Created a new function `verify_plonk_bn254_solidity` in `native.rs` to handle plonk bn254 verification for solidity
- Incorporated a new function `VerifyPlonkBn254Solidity` in `main.go` for Plonk Bn254 proofs verification for Solidity
  • Loading branch information
huitseeker committed Sep 11, 2024
1 parent f51436f commit bfaf106
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
15 changes: 15 additions & 0 deletions recursion/gnark-ffi/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,21 @@ func VerifyPlonkBn254(dataDir *C.char, proof *C.char, vkeyHash *C.char, commited
return nil
}

//export VerifyPlonkBn254Solidity
func VerifyPlonkBn254Solidity(dataDir *C.char, proof *C.char, vkeyHash *C.char, commitedValuesDigest *C.char) *C.char {
dataDirString := C.GoString(dataDir)
proofString := C.GoString(proof)
vkeyHashString := C.GoString(vkeyHash)
commitedValuesDigestString := C.GoString(commitedValuesDigest)

err := sp1.VerifySolidity(dataDirString, proofString, vkeyHashString, commitedValuesDigestString)
if err != nil {
return C.CString(err.Error())
}
return nil
}


var testMutex = &sync.Mutex{}

//export TestPlonkBn254
Expand Down
59 changes: 59 additions & 0 deletions recursion/gnark-ffi/go/sp1/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"os"

"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark-crypto/ecc/bn254/fr"
"github.com/consensys/gnark/backend/plonk"
plonk_bn254 "github.com/consensys/gnark/backend/plonk/bn254"
"github.com/consensys/gnark/frontend"
"github.com/succinctlabs/sp1-recursion-gnark/sp1/babybear"
)
Expand Down Expand Up @@ -56,3 +58,60 @@ func Verify(verifyCmdDataDir string, verifyCmdProof string, verifyCmdVkeyHash st
err = plonk.Verify(proof, vk, publicWitness)
return err
}

func VerifySolidity(verifyCmdDataDir string, verifyCmdProof string, verifyCmdVkeyHash string, verifyCmdCommitedValuesDigest string) error {
// Sanity check the required arguments have been provided.
if verifyCmdDataDir == "" {
panic("--data is required")
}

// Decode the proof.
proofDecodedBytes, err := hex.DecodeString(verifyCmdProof)
if err != nil {
panic(err)
}

// Proof contains 768 bytes worth of initial elements, followed by 32 bytes x nbCommits, followed by 64 bytes x nbCommits
nbCommits := (len(proofDecodedBytes) - 768) / 32 / 3;

proof_bn254 := plonk_bn254.UnmarshalSolidity(proofDecodedBytes, nbCommits)

// Read the verifier key.
vkFile, err := os.Open(verifyCmdDataDir + "/" + vkPath)
if err != nil {
panic(err)
}
var vk plonk_bn254.VerifyingKey
_, err = vk.ReadFrom(vkFile)
if err != nil {
panic(err)
}

// Compute the public witness.
circuit := Circuit{
Vars: []frontend.Variable{},
Felts: []babybear.Variable{},
Exts: []babybear.ExtensionVariable{},
VkeyHash: verifyCmdVkeyHash,
CommitedValuesDigest: verifyCmdCommitedValuesDigest,
}
witness, err := frontend.NewWitness(&circuit, ecc.BN254.ScalarField())
if err != nil {
panic(err)
}
publicWitness, err := witness.Public()
if err != nil {
panic(err)
}

var witness_vec fr.Vector
if value, ok := publicWitness.Vector().(fr.Vector); ok {
witness_vec = value
} else {
panic("witness is not a vector")
}

// Verify proof.
err = plonk_bn254.Verify(&proof_bn254, &vk, witness_vec)
return err
}
29 changes: 29 additions & 0 deletions recursion/gnark-ffi/src/ffi/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,35 @@ pub fn verify_plonk_bn254(
}
}

pub fn verify_plonk_bn254_solidity(
data_dir: &str,
proof: &str,
vkey_hash: &str,
committed_values_digest: &str,
) -> Result<(), String> {
let data_dir = CString::new(data_dir).expect("CString::new failed");
let proof = CString::new(proof).expect("CString::new failed");
let vkey_hash = CString::new(vkey_hash).expect("CString::new failed");
let committed_values_digest =
CString::new(committed_values_digest).expect("CString::new failed");

let err_ptr = unsafe {
VerifyPlonkBn254Solidity(
data_dir.as_ptr() as *mut c_char,
proof.as_ptr() as *mut c_char,
vkey_hash.as_ptr() as *mut c_char,
committed_values_digest.as_ptr() as *mut c_char,
)
};
if err_ptr.is_null() {
Ok(())
} else {
// Safety: The error message is returned from the go code and is guaranteed to be valid.
let err = unsafe { CString::from_raw(err_ptr) };
Err(err.into_string().unwrap())
}
}

pub fn test_plonk_bn254(witness_json: &str, constraints_json: &str) {
unsafe {
let witness_json = CString::new(witness_json).expect("CString::new failed");
Expand Down

0 comments on commit bfaf106

Please sign in to comment.