diff --git a/batcher/aligned-batcher/gnark/verifier.go b/batcher/aligned-batcher/gnark/verifier.go index 4acba01a8a..7e4fe547ff 100644 --- a/batcher/aligned-batcher/gnark/verifier.go +++ b/batcher/aligned-batcher/gnark/verifier.go @@ -15,15 +15,21 @@ import "C" import ( "bytes" + "log" + "unsafe" + "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 { + + if listRef.len == 0 { + return []byte{} + } + return C.GoBytes(unsafe.Pointer(listRef.ptr), C.int(listRef.len)) } diff --git a/operator/halo2ipa/halo2ipa.go b/operator/halo2ipa/halo2ipa.go index 6e178f2ffc..6df49b0514 100644 --- a/operator/halo2ipa/halo2ipa.go +++ b/operator/halo2ipa/halo2ipa.go @@ -10,9 +10,9 @@ import "C" import "unsafe" func VerifyHalo2IpaProof( - proofBuffer []byte, proofLen uint32, - paramsBuffer []byte, paramsLen uint32, - publicInputBuffer []byte, publicInputLen uint32, + proofBuffer []byte, + paramsBuffer []byte, + publicInputBuffer []byte, ) bool { /* For Halo2 the `paramsBuffer` contains the serialized cs, vk, and params with there respective sizes serialized as u32 values (4 bytes) => 3 * 4 bytes = 12 followed by the concatenated variable length buffers: @@ -28,8 +28,8 @@ func VerifyHalo2IpaProof( publicInputPtr := (*C.uchar)(unsafe.Pointer(&publicInputBuffer[0])) return (bool)(C.verify_halo2_ipa_proof_ffi( - proofPtr, (C.uint32_t)(proofLen), - paramsPtr, (C.uint32_t)(paramsLen), - publicInputPtr, (C.uint32_t)(publicInputLen), + proofPtr, (C.uint32_t)(len(proofBuffer)), + paramsPtr, (C.uint32_t)(len(paramsBuffer)), + publicInputPtr, (C.uint32_t)(len(publicInputBuffer)), )) } diff --git a/operator/halo2ipa/halo2ipa_test.go b/operator/halo2ipa/halo2ipa_test.go index 13ed42385d..68044505ac 100644 --- a/operator/halo2ipa/halo2ipa_test.go +++ b/operator/halo2ipa/halo2ipa_test.go @@ -7,12 +7,6 @@ import ( "github.com/yetanotherco/aligned_layer/operator/halo2ipa" ) -const MaxProofSize = 8 * 1024 - -const MaxParamsSize = 8 * 1024 - -const MaxPublicInputSize = 4 * 1024 - const ProofFilePath = "../../scripts/test_files/halo2_ipa/proof.bin" const PublicInputPath = "../../scripts/test_files/halo2_ipa/pub_input.bin" @@ -20,42 +14,25 @@ const PublicInputPath = "../../scripts/test_files/halo2_ipa/pub_input.bin" const ParamsFilePath = "../../scripts/test_files/halo2_ipa/params.bin" func TestHalo2IpaProofVerifies(t *testing.T) { - proofFile, err := os.Open(ProofFilePath) + proofBytes, err := os.ReadFile(ProofFilePath) if err != nil { t.Errorf("could not open proof file: %s", err) } - proofBytes := make([]byte, MaxProofSize) - nReadProofBytes, err := proofFile.Read(proofBytes) - if err != nil { - t.Errorf("could not read bytes from file") - } - defer proofFile.Close() - paramsFile, err := os.Open(ParamsFilePath) + paramsBytes, err := os.ReadFile(ParamsFilePath) if err != nil { - t.Errorf("could not open proof file: %s", err) + t.Errorf("could not open params file: %s", err) } - paramsBytes := make([]byte, MaxParamsSize) - nReadParamsBytes, err := paramsFile.Read(paramsBytes) - if err != nil { - t.Errorf("could not read bytes from file") - } - defer paramsFile.Close() - publicInputFile, err := os.Open(PublicInputPath) - if err != nil { - t.Errorf("could not open proof file: %s", err) - } - publicInputBytes := make([]byte, MaxPublicInputSize) - nReadPublicInputBytes, err := publicInputFile.Read(publicInputBytes) + publicInputBytes, err := os.ReadFile(PublicInputPath) if err != nil { - t.Errorf("could not read bytes from file") + t.Errorf("could not open public input file: %s", err) } if !halo2ipa.VerifyHalo2IpaProof( - ([]byte)(proofBytes), uint32(nReadProofBytes), - ([]byte)(paramsBytes), uint32(nReadParamsBytes), - ([]byte)(publicInputBytes), uint32(nReadPublicInputBytes), + ([]byte)(proofBytes), + ([]byte)(paramsBytes), + ([]byte)(publicInputBytes), ) { t.Errorf("proof did not verify") } diff --git a/operator/halo2kzg/halo2kzg.go b/operator/halo2kzg/halo2kzg.go index 20330b7c4a..0f2f83a327 100644 --- a/operator/halo2kzg/halo2kzg.go +++ b/operator/halo2kzg/halo2kzg.go @@ -9,9 +9,9 @@ import "C" import "unsafe" func VerifyHalo2KzgProof( - proofBuffer []byte, proofLen uint32, - paramsBuffer []byte, paramsLen uint32, - publicInputBuffer []byte, publicInputLen uint32, + proofBuffer []byte, + paramsBuffer []byte, + publicInputBuffer []byte, ) bool { /* For Halo2 the `paramsBuffer` contains the serialized cs, vk, and params with there respective sizes serialized as u32 values (4 bytes) => 3 * 4 bytes = 12 followed by the concatenated variable length buffers: @@ -27,8 +27,8 @@ func VerifyHalo2KzgProof( publicInputPtr := (*C.uchar)(unsafe.Pointer(&publicInputBuffer[0])) return (bool)(C.verify_halo2_kzg_proof_ffi( - proofPtr, (C.uint32_t)(proofLen), - paramsPtr, (C.uint32_t)(paramsLen), - publicInputPtr, (C.uint32_t)(publicInputLen), + proofPtr, (C.uint32_t)(len(proofBuffer)), + paramsPtr, (C.uint32_t)(len(paramsBuffer)), + publicInputPtr, (C.uint32_t)(len(publicInputBuffer)), )) } diff --git a/operator/halo2kzg/halo2kzg_test.go b/operator/halo2kzg/halo2kzg_test.go index 5a06577899..a1ad8c1a02 100644 --- a/operator/halo2kzg/halo2kzg_test.go +++ b/operator/halo2kzg/halo2kzg_test.go @@ -7,15 +7,6 @@ import ( "github.com/yetanotherco/aligned_layer/operator/halo2kzg" ) -// MaxProofSize 4KB -const MaxProofSize = 8 * 1024 - -// MaxProofSize 4KB -const MaxParamsSize = 8 * 1024 - -// MaxPublicInputSize 4KB -const MaxPublicInputSize = 4 * 1024 - const ProofFilePath = "../../scripts/test_files/halo2_kzg/proof.bin" const PublicInputPath = "../../scripts/test_files/halo2_kzg/pub_input.bin" @@ -23,42 +14,25 @@ const PublicInputPath = "../../scripts/test_files/halo2_kzg/pub_input.bin" const ParamsFilePath = "../../scripts/test_files/halo2_kzg/params.bin" func TestHalo2KzgProofVerifies(t *testing.T) { - proofFile, err := os.Open(ProofFilePath) + proofBytes, err := os.ReadFile(ProofFilePath) if err != nil { t.Errorf("could not open proof file: %s", err) } - proofBytes := make([]byte, MaxProofSize) - nReadProofBytes, err := proofFile.Read(proofBytes) - if err != nil { - t.Errorf("could not read bytes from file") - } - defer proofFile.Close() - paramsFile, err := os.Open(ParamsFilePath) + paramsBytes, err := os.ReadFile(ParamsFilePath) if err != nil { - t.Errorf("could not open proof file: %s", err) + t.Errorf("could not open params file: %s", err) } - paramsBytes := make([]byte, MaxParamsSize) - nReadParamsBytes, err := paramsFile.Read(paramsBytes) - if err != nil { - t.Errorf("could not read bytes from file") - } - defer paramsFile.Close() - publicInputFile, err := os.Open(PublicInputPath) - if err != nil { - t.Errorf("could not open proof file: %s", err) - } - publicInputBytes := make([]byte, MaxPublicInputSize) - nReadPublicInputBytes, err := publicInputFile.Read(publicInputBytes) + publicInputBytes, err := os.ReadFile(PublicInputPath) if err != nil { - t.Errorf("could not read bytes from file") + t.Errorf("could not open public input file: %s", err) } if !halo2kzg.VerifyHalo2KzgProof( - ([]byte)(proofBytes), uint32(nReadProofBytes), - ([]byte)(paramsBytes), uint32(nReadParamsBytes), - ([]byte)(publicInputBytes), uint32(nReadPublicInputBytes), + ([]byte)(proofBytes), + ([]byte)(paramsBytes), + ([]byte)(publicInputBytes), ) { t.Errorf("proof did not verify") } diff --git a/operator/merkle_tree/lib/test_files/merkle_root.bin b/operator/merkle_tree/lib/test_files/merkle_root.bin index 7d46ceeae5..623903edd1 100644 --- a/operator/merkle_tree/lib/test_files/merkle_root.bin +++ b/operator/merkle_tree/lib/test_files/merkle_root.bin @@ -1 +1 @@ -e0a3761a514a2a7873350869e699bbd87c9cbf53ba963caae0a232cb6d698b1b \ No newline at end of file +715181f01c095618472a72cd06e384d92f02eadc4ea28bf097181b17fdc57f28 \ No newline at end of file diff --git a/operator/merkle_tree/lib/test_files/merkle_tree_batch.bin b/operator/merkle_tree/lib/test_files/merkle_tree_batch.bin index 7238a17a14..733703c543 100644 Binary files a/operator/merkle_tree/lib/test_files/merkle_tree_batch.bin and b/operator/merkle_tree/lib/test_files/merkle_tree_batch.bin differ diff --git a/operator/merkle_tree/merkle_tree.go b/operator/merkle_tree/merkle_tree.go index 7eb40772da..9b6562481d 100644 --- a/operator/merkle_tree/merkle_tree.go +++ b/operator/merkle_tree/merkle_tree.go @@ -9,12 +9,12 @@ package merkle_tree import "C" import "unsafe" -func VerifyMerkleTreeBatch(batchBuffer []byte, batchLen uint, merkleRootBuffer [32]byte) bool { +func VerifyMerkleTreeBatch(batchBuffer []byte, merkleRootBuffer [32]byte) bool { if len(batchBuffer) == 0 { return false } batchPtr := (*C.uchar)(unsafe.Pointer(&batchBuffer[0])) merkleRootPtr := (*C.uchar)(unsafe.Pointer(&merkleRootBuffer[0])) - return (bool)(C.verify_merkle_tree_batch_ffi(batchPtr, (C.uint)(batchLen), merkleRootPtr)) + return (bool)(C.verify_merkle_tree_batch_ffi(batchPtr, (C.uint)(len(batchBuffer)), merkleRootPtr)) } diff --git a/operator/merkle_tree/merkle_tree_test.go b/operator/merkle_tree/merkle_tree_test.go index 0faa5f49ae..539391929b 100644 --- a/operator/merkle_tree/merkle_tree_test.go +++ b/operator/merkle_tree/merkle_tree_test.go @@ -3,28 +3,21 @@ package merkle_tree import ( "encoding/hex" "fmt" - "io" "os" "testing" ) -func TestVerifyMerkleTreeBatch(t *testing.T) { - batchFile, err := os.Open("lib/test_files/merkle_tree_batch.bin") - if err != nil { - t.Fatalf("Error opening batch file: %v", err) - } +const BatchFilePath = "lib/test_files/merkle_tree_batch.bin" - batchByteValue, err := io.ReadAll(batchFile) - if err != nil { - t.Fatalf("Error reading batch file: %v", err) - } +const RootFilePath = "lib/test_files/merkle_root.bin" - rootFile, err := os.Open("lib/test_files/merkle_root.bin") +func TestVerifyMerkleTreeBatch(t *testing.T) { + batchByteValue, err := os.ReadFile(BatchFilePath) if err != nil { - t.Fatalf("Error opening batch file: %v", err) + t.Fatalf("Error reading batch file: %v", err) } - rootByteValue, err := io.ReadAll(rootFile) + rootByteValue, err := os.ReadFile(RootFilePath) if err != nil { t.Fatalf("Error reading batch file: %v", err) } @@ -39,7 +32,7 @@ func TestVerifyMerkleTreeBatch(t *testing.T) { var merkleRoot [32]byte copy(merkleRoot[:], merkle_root) - if !VerifyMerkleTreeBatch(batchByteValue, uint(len(batchByteValue)), merkleRoot) { + if !VerifyMerkleTreeBatch(batchByteValue, merkleRoot) { t.Errorf("Batch did not verify Merkle Root") } diff --git a/operator/merkle_tree_old/merkle_tree_old.go b/operator/merkle_tree_old/merkle_tree_old.go index 80fb227e3e..d97d48e698 100644 --- a/operator/merkle_tree_old/merkle_tree_old.go +++ b/operator/merkle_tree_old/merkle_tree_old.go @@ -9,12 +9,12 @@ package merkle_tree_old import "C" import "unsafe" -func VerifyMerkleTreeBatchOld(batchBuffer []byte, batchLen uint, merkleRootBuffer [32]byte) bool { +func VerifyMerkleTreeBatchOld(batchBuffer []byte, merkleRootBuffer [32]byte) bool { if len(batchBuffer) == 0 { return false } batchPtr := (*C.uchar)(unsafe.Pointer(&batchBuffer[0])) merkleRootPtr := (*C.uchar)(unsafe.Pointer(&merkleRootBuffer[0])) - return (bool)(C.verify_merkle_tree_batch_ffi_old(batchPtr, (C.uint)(batchLen), merkleRootPtr)) + return (bool)(C.verify_merkle_tree_batch_ffi_old(batchPtr, (C.uint)(len(batchBuffer)), merkleRootPtr)) } diff --git a/operator/merkle_tree_old/merkle_tree_old_test.go b/operator/merkle_tree_old/merkle_tree_old_test.go index 3d7f97a87c..0f4e2a8f6a 100644 --- a/operator/merkle_tree_old/merkle_tree_old_test.go +++ b/operator/merkle_tree_old/merkle_tree_old_test.go @@ -3,30 +3,23 @@ package merkle_tree_old import ( "encoding/hex" "fmt" - "io" "os" "testing" ) -func TestVerifyMerkleTreeBatchOld(t *testing.T) { - batchFile, err := os.Open("lib/test_files/merkle_tree_batch.bin") - if err != nil { - t.Fatalf("Error opening batch file: %v", err) - } +const BatchFilePath = "lib/test_files/merkle_tree_batch.bin" - batchByteValue, err := io.ReadAll(batchFile) - if err != nil { - t.Fatalf("Error reading batch file: %v", err) - } +const RootFilePath = "lib/test_files/merkle_root.bin" - rootFile, err := os.Open("lib/test_files/merkle_root.bin") +func TestVerifyMerkleTreeBatchOld(t *testing.T) { + batchByteValue, err := os.ReadFile(BatchFilePath) if err != nil { t.Fatalf("Error opening batch file: %v", err) } - rootByteValue, err := io.ReadAll(rootFile) + rootByteValue, err := os.ReadFile(RootFilePath) if err != nil { - t.Fatalf("Error reading batch file: %v", err) + t.Fatalf("Error opening batch file: %v", err) } merkle_root := make([]byte, hex.DecodedLen(len(rootByteValue))) @@ -39,7 +32,7 @@ func TestVerifyMerkleTreeBatchOld(t *testing.T) { var merkleRoot [32]byte copy(merkleRoot[:], merkle_root) - if !VerifyMerkleTreeBatchOld(batchByteValue, uint(len(batchByteValue)), merkleRoot) { + if !VerifyMerkleTreeBatchOld(batchByteValue, merkleRoot) { t.Errorf("Batch did not verify Merkle Root") } diff --git a/operator/pkg/operator.go b/operator/pkg/operator.go index 558f728782..922b2c099c 100644 --- a/operator/pkg/operator.go +++ b/operator/pkg/operator.go @@ -37,20 +37,20 @@ import ( ) type Operator struct { - Config config.OperatorConfig - Address ethcommon.Address - Socket string - Timeout time.Duration - PrivKey *ecdsa.PrivateKey - KeyPair *bls.KeyPair - OperatorId eigentypes.OperatorId - avsSubscriber chainio.AvsSubscriber + Config config.OperatorConfig + Address ethcommon.Address + Socket string + Timeout time.Duration + PrivKey *ecdsa.PrivateKey + KeyPair *bls.KeyPair + OperatorId eigentypes.OperatorId + avsSubscriber chainio.AvsSubscriber NewTaskCreatedChanV2 chan *servicemanager.ContractAlignedLayerServiceManagerNewBatchV2 NewTaskCreatedChanV3 chan *servicemanager.ContractAlignedLayerServiceManagerNewBatchV3 - Logger logging.Logger - aggRpcClient AggregatorRpcClient - metricsReg *prometheus.Registry - metrics *metrics.Metrics + Logger logging.Logger + aggRpcClient AggregatorRpcClient + metricsReg *prometheus.Registry + metrics *metrics.Metrics //Socket string //Timeout time.Duration } @@ -110,16 +110,16 @@ func NewOperatorFromConfig(configuration config.OperatorConfig) (*Operator, erro operatorMetrics := metrics.NewMetrics(configuration.Operator.MetricsIpPortAddress, reg, logger) operator := &Operator{ - Config: configuration, - Logger: logger, - avsSubscriber: *avsSubscriber, - Address: address, + Config: configuration, + Logger: logger, + avsSubscriber: *avsSubscriber, + Address: address, NewTaskCreatedChanV2: newTaskCreatedChanV2, NewTaskCreatedChanV3: newTaskCreatedChanV3, - aggRpcClient: *rpcClient, - OperatorId: operatorId, - metricsReg: reg, - metrics: operatorMetrics, + aggRpcClient: *rpcClient, + OperatorId: operatorId, + metricsReg: reg, + metrics: operatorMetrics, // Timeout // Socket } @@ -127,7 +127,6 @@ func NewOperatorFromConfig(configuration config.OperatorConfig) (*Operator, erro return operator, nil } - func (o *Operator) SubscribeToNewTasksV2() (chan error, error) { return o.avsSubscriber.SubscribeToNewTasksV2(o.NewTaskCreatedChanV2) } @@ -206,10 +205,10 @@ func (o *Operator) handleNewBatchLogV2(newBatchLog *servicemanager.ContractAlign signedTaskResponse := types.SignedTaskResponse{ BatchIdentifierHash: batchIdentifierHash, - BatchMerkleRoot: newBatchLog.BatchMerkleRoot, - SenderAddress: newBatchLog.SenderAddress, - BlsSignature: *responseSignature, - OperatorId: o.OperatorId, + BatchMerkleRoot: newBatchLog.BatchMerkleRoot, + SenderAddress: newBatchLog.SenderAddress, + BlsSignature: *responseSignature, + OperatorId: o.OperatorId, } o.Logger.Infof("Signed Task Response to send: BatchIdentifierHash=%s, BatchMerkleRoot=%s, SenderAddress=%s", hex.EncodeToString(signedTaskResponse.BatchIdentifierHash[:]), @@ -277,10 +276,10 @@ func (o *Operator) handleNewBatchLogV3(newBatchLog *servicemanager.ContractAlign signedTaskResponse := types.SignedTaskResponse{ BatchIdentifierHash: batchIdentifierHash, - BatchMerkleRoot: newBatchLog.BatchMerkleRoot, - SenderAddress: newBatchLog.SenderAddress, - BlsSignature: *responseSignature, - OperatorId: o.OperatorId, + BatchMerkleRoot: newBatchLog.BatchMerkleRoot, + SenderAddress: newBatchLog.SenderAddress, + BlsSignature: *responseSignature, + OperatorId: o.OperatorId, } o.Logger.Infof("Signed Task Response to send: BatchIdentifierHash=%s, BatchMerkleRoot=%s, SenderAddress=%s", hex.EncodeToString(signedTaskResponse.BatchIdentifierHash[:]), @@ -348,48 +347,37 @@ func (o *Operator) verify(verificationData VerificationData, results chan bool) case common.Groth16Bn254: verificationResult := o.verifyGroth16ProofBN254(verificationData.Proof, verificationData.PubInput, verificationData.VerificationKey) - o.Logger.Infof("GROTH16 BN254 proof verification result: %t", verificationResult) + results <- verificationResult case common.SP1: - proofLen := (uint32)(len(verificationData.Proof)) - elfLen := (uint32)(len(verificationData.VmProgramCode)) - verificationResult := sp1.VerifySp1Proof(verificationData.Proof, proofLen, verificationData.VmProgramCode, elfLen) + verificationResult := sp1.VerifySp1Proof(verificationData.Proof, verificationData.VmProgramCode) o.Logger.Infof("SP1 proof verification result: %t", verificationResult) results <- verificationResult case common.Halo2IPA: - proofLen := (uint32)(len(verificationData.Proof)) - paramsLen := (uint32)(len(verificationData.VerificationKey)) - publicInputLen := (uint32)(len(verificationData.PubInput)) verificationResult := halo2ipa.VerifyHalo2IpaProof( - verificationData.Proof, proofLen, - verificationData.VerificationKey, paramsLen, - verificationData.PubInput, publicInputLen) + verificationData.Proof, + verificationData.VerificationKey, + verificationData.PubInput) o.Logger.Infof("Halo2-IPA proof verification result: %t", verificationResult) results <- verificationResult case common.Halo2KZG: - proofLen := (uint32)(len(verificationData.Proof)) - paramsLen := (uint32)(len(verificationData.VerificationKey)) - publicInputLen := (uint32)(len(verificationData.PubInput)) verificationResult := halo2kzg.VerifyHalo2KzgProof( - verificationData.Proof, proofLen, - verificationData.VerificationKey, paramsLen, - verificationData.PubInput, publicInputLen) + verificationData.Proof, + verificationData.VerificationKey, + verificationData.PubInput) o.Logger.Infof("Halo2-KZG proof verification result: %t", verificationResult) results <- verificationResult case common.Risc0: - proofLen := (uint32)(len(verificationData.Proof)) - imageIdLen := (uint32)(len(verificationData.VmProgramCode)) - pubInputLen := (uint32)(len(verificationData.PubInput)) - verificationResult := risc_zero.VerifyRiscZeroReceipt(verificationData.Proof, proofLen, - verificationData.VmProgramCode, imageIdLen, verificationData.PubInput, pubInputLen) + verificationResult := risc_zero.VerifyRiscZeroReceipt(verificationData.Proof, + verificationData.VmProgramCode, verificationData.PubInput) o.Logger.Infof("Risc0 proof verification result: %t", verificationResult) results <- verificationResult diff --git a/operator/pkg/s3.go b/operator/pkg/s3.go index 157cd66748..836429016f 100644 --- a/operator/pkg/s3.go +++ b/operator/pkg/s3.go @@ -92,11 +92,11 @@ func (o *Operator) getBatchFromDataService(ctx context.Context, batchURL string, // Checks if downloaded merkle root is the same as the expected one o.Logger.Infof("Verifying batch merkle tree...") - merkle_root_check := merkle_tree.VerifyMerkleTreeBatch(batchBytes, uint(len(batchBytes)), expectedMerkleRoot) + merkle_root_check := merkle_tree.VerifyMerkleTreeBatch(batchBytes, expectedMerkleRoot) if !merkle_root_check { // try old merkle tree o.Logger.Infof("Batch merkle tree verification failed. Trying old merkle tree...") - merkle_root_check = merkle_tree_old.VerifyMerkleTreeBatchOld(batchBytes, uint(len(batchBytes)), expectedMerkleRoot) + merkle_root_check = merkle_tree_old.VerifyMerkleTreeBatchOld(batchBytes, expectedMerkleRoot) if !merkle_root_check { return nil, fmt.Errorf("merkle root check failed") } diff --git a/operator/risc_zero/lib/src/lib.rs b/operator/risc_zero/lib/src/lib.rs index 9bf8c48947..13be1cafc8 100644 --- a/operator/risc_zero/lib/src/lib.rs +++ b/operator/risc_zero/lib/src/lib.rs @@ -1,5 +1,5 @@ -use risc0_zkvm::{InnerReceipt, Receipt}; use log::error; +use risc0_zkvm::{InnerReceipt, Receipt}; #[no_mangle] pub extern "C" fn verify_risc_zero_receipt_ffi( @@ -20,13 +20,11 @@ pub extern "C" fn verify_risc_zero_receipt_ffi( return false; } - let mut public_input: *const u8 = public_input; - let mut public_input_len: u32 = public_input_len; - if public_input.is_null() || public_input_len == 0 { - // set public input to pointer to empty slice - let empty_slice: &[u8] = &[]; - public_input = empty_slice.as_ptr(); - public_input_len = 0; + //NOTE: We allow the public input for risc0 to be empty. + let mut public_input_slice: &[u8] = &[]; + if !public_input.is_null() && public_input_len > 0 { + public_input_slice = + unsafe { std::slice::from_raw_parts(public_input, public_input_len as usize) }; } let inner_receipt_bytes = @@ -34,14 +32,11 @@ pub extern "C" fn verify_risc_zero_receipt_ffi( let image_id = unsafe { std::slice::from_raw_parts(image_id, image_id_len as usize) }; - let public_input = - unsafe { std::slice::from_raw_parts(public_input, public_input_len as usize) }; - let mut image_id_array = [0u8; 32]; image_id_array.copy_from_slice(image_id); if let Ok(inner_receipt) = bincode::deserialize::(inner_receipt_bytes) { - let receipt = Receipt::new(inner_receipt, public_input.to_vec()); + let receipt = Receipt::new(inner_receipt, public_input_slice.to_vec()); return receipt.verify(image_id_array).is_ok(); } @@ -93,4 +88,21 @@ mod tests { ); assert!(!result) } + + #[test] + fn verify_risc_zero_input_valid() { + let receipt_bytes = RECEIPT.as_ptr(); + let image_id = IMAGE_ID.as_ptr(); + let public_input = [].as_ptr(); + + let result = verify_risc_zero_receipt_ffi( + receipt_bytes, + (RECEIPT.len() - 1) as u32, + image_id, + IMAGE_ID.len() as u32, + public_input, + 0, + ); + assert!(!result) + } } diff --git a/operator/risc_zero/risc_zero.go b/operator/risc_zero/risc_zero.go index 35a143e3bf..92716ae021 100644 --- a/operator/risc_zero/risc_zero.go +++ b/operator/risc_zero/risc_zero.go @@ -11,7 +11,7 @@ import ( "unsafe" ) -func VerifyRiscZeroReceipt(innerReceiptBuffer []byte, innerReceiptLen uint32, imageIdBuffer []byte, imageIdLen uint32, publicInput []byte, publicInputLen uint32) bool { +func VerifyRiscZeroReceipt(innerReceiptBuffer []byte, imageIdBuffer []byte, publicInputBuffer []byte) bool { if len(innerReceiptBuffer) == 0 || len(imageIdBuffer) == 0 { return false } @@ -19,10 +19,10 @@ func VerifyRiscZeroReceipt(innerReceiptBuffer []byte, innerReceiptLen uint32, im receiptPtr := (*C.uchar)(unsafe.Pointer(&innerReceiptBuffer[0])) imageIdPtr := (*C.uchar)(unsafe.Pointer(&imageIdBuffer[0])) - if len(publicInput) == 0 { // allow empty public input - return (bool)(C.verify_risc_zero_receipt_ffi(receiptPtr, (C.uint32_t)(innerReceiptLen), imageIdPtr, (C.uint32_t)(imageIdLen), nil, (C.uint32_t)(0))) + if len(publicInputBuffer) == 0 { // allow empty public input + return (bool)(C.verify_risc_zero_receipt_ffi(receiptPtr, (C.uint32_t)(len(innerReceiptBuffer)), imageIdPtr, (C.uint32_t)(len(imageIdBuffer)), nil, (C.uint32_t)(0))) } - publicInputPtr := (*C.uchar)(unsafe.Pointer(&publicInput[0])) - return (bool)(C.verify_risc_zero_receipt_ffi(receiptPtr, (C.uint32_t)(innerReceiptLen), imageIdPtr, (C.uint32_t)(imageIdLen), publicInputPtr, (C.uint32_t)(publicInputLen))) + publicInputPtr := (*C.uchar)(unsafe.Pointer(&publicInputBuffer[0])) + return (bool)(C.verify_risc_zero_receipt_ffi(receiptPtr, (C.uint32_t)(len(innerReceiptBuffer)), imageIdPtr, (C.uint32_t)(len(imageIdBuffer)), publicInputPtr, (C.uint32_t)(len(publicInputBuffer)))) } diff --git a/operator/risc_zero/risc_zero_test.go b/operator/risc_zero/risc_zero_test.go index b175ff5584..454cc00448 100644 --- a/operator/risc_zero/risc_zero_test.go +++ b/operator/risc_zero/risc_zero_test.go @@ -7,6 +7,12 @@ import ( "github.com/yetanotherco/aligned_layer/operator/risc_zero" ) +const ProofFilePath = "../../scripts/test_files/halo2_kzg/proof.bin" + +const PublicInputPath = "../../scripts/test_files/halo2_kzg/pub_input.bin" + +const ParamsFilePath = "../../scripts/test_files/halo2_kzg/params.bin" + func TestFibonacciRiscZeroProofVerifies(t *testing.T) { innerReceiptBytes, err := os.ReadFile("../../scripts/test_files/risc_zero/fibonacci_proof_generator/risc_zero_fibonacci.proof") if err != nil { @@ -23,7 +29,7 @@ func TestFibonacciRiscZeroProofVerifies(t *testing.T) { t.Errorf("could not open public input file: %s", err) } - if !risc_zero.VerifyRiscZeroReceipt(innerReceiptBytes, uint32(len(innerReceiptBytes)), imageIdBytes, uint32(len(imageIdBytes)), publicInputBytes, uint32(len(publicInputBytes))) { + if !risc_zero.VerifyRiscZeroReceipt(innerReceiptBytes, imageIdBytes, publicInputBytes) { t.Errorf("proof did not verify") } } diff --git a/operator/sp1/lib/src/lib.rs b/operator/sp1/lib/src/lib.rs index cf8ee348c8..c3145a00c9 100644 --- a/operator/sp1/lib/src/lib.rs +++ b/operator/sp1/lib/src/lib.rs @@ -1,7 +1,6 @@ use lazy_static::lazy_static; -use sp1_sdk::ProverClient; -use std::slice; use log::error; +use sp1_sdk::ProverClient; lazy_static! { static ref PROVER_CLIENT: ProverClient = ProverClient::new(); @@ -24,9 +23,9 @@ pub extern "C" fn verify_sp1_proof_ffi( return false; } - let proof_bytes = unsafe { slice::from_raw_parts(proof_bytes, proof_len as usize) }; + let proof_bytes = unsafe { std::slice::from_raw_parts(proof_bytes, proof_len as usize) }; - let elf_bytes = unsafe { slice::from_raw_parts(elf_bytes, elf_len as usize) }; + let elf_bytes = unsafe { std::slice::from_raw_parts(elf_bytes, elf_len as usize) }; if let Ok(proof) = bincode::deserialize(proof_bytes) { let (_pk, vk) = PROVER_CLIENT.setup(elf_bytes); diff --git a/operator/sp1/sp1.go b/operator/sp1/sp1.go index 4340e9a474..64b310844d 100644 --- a/operator/sp1/sp1.go +++ b/operator/sp1/sp1.go @@ -9,7 +9,7 @@ package sp1 import "C" import "unsafe" -func VerifySp1Proof(proofBuffer []byte, proofLen uint32, elfBuffer []byte, elfLen uint32) bool { +func VerifySp1Proof(proofBuffer []byte, elfBuffer []byte) bool { if len(proofBuffer) == 0 || len(elfBuffer) == 0 { return false } @@ -17,5 +17,5 @@ func VerifySp1Proof(proofBuffer []byte, proofLen uint32, elfBuffer []byte, elfLe proofPtr := (*C.uchar)(unsafe.Pointer(&proofBuffer[0])) elfPtr := (*C.uchar)(unsafe.Pointer(&elfBuffer[0])) - return (bool)(C.verify_sp1_proof_ffi(proofPtr, (C.uint32_t)(proofLen), elfPtr, (C.uint32_t)(elfLen))) + return (bool)(C.verify_sp1_proof_ffi(proofPtr, (C.uint32_t)(len(proofBuffer)), elfPtr, (C.uint32_t)(len(elfBuffer)))) } diff --git a/operator/sp1/sp1_test.go b/operator/sp1/sp1_test.go index d1593225e6..d342751bd5 100644 --- a/operator/sp1/sp1_test.go +++ b/operator/sp1/sp1_test.go @@ -7,32 +7,22 @@ import ( "github.com/yetanotherco/aligned_layer/operator/sp1" ) -const MaxProofSize = 2 * 1024 * 1024 -const MaxElfSize = 2 * 1024 * 1024 +const ProofFilePath = "../../scripts/test_files/sp1/sp1_fibonacci.proof" -func TestFibonacciSp1ProofVerifies(t *testing.T) { - proofFile, err := os.Open("../../scripts/test_files/sp1/sp1_fibonacci.proof") - if err != nil { - t.Errorf("could not open proof file: %s", err) - } - proofBytes := make([]byte, MaxProofSize) - nReadProofBytes, err := proofFile.Read(proofBytes) - if err != nil { - t.Errorf("could not read bytes from file") - } +const ElfFilePath = "../../scripts/test_files/sp1/sp1_fibonacci.elf" - elfFile, err := os.Open("../../scripts/test_files/sp1/sp1_fibonacci.elf") +func TestFibonacciSp1ProofVerifies(t *testing.T) { + proofBytes, err := os.ReadFile(ProofFilePath) if err != nil { t.Errorf("could not open proof file: %s", err) } - elfBytes := make([]byte, MaxElfSize) - nReadElfBytes, err := elfFile.Read(elfBytes) + elfBytes, err := os.ReadFile(ElfFilePath) if err != nil { - t.Errorf("could not read bytes from file") + t.Errorf("could not open elf file: %s", err) } - if !sp1.VerifySp1Proof(proofBytes, uint32(nReadProofBytes), elfBytes, uint32(nReadElfBytes)) { + if !sp1.VerifySp1Proof(proofBytes, elfBytes) { t.Errorf("proof did not verify") } }