Skip to content

openvm: create verifier and fix prover#614

Open
gballet wants to merge 2 commits intomainfrom
prove-and-verify-openvm
Open

openvm: create verifier and fix prover#614
gballet wants to merge 2 commits intomainfrom
prove-and-verify-openvm

Conversation

@gballet
Copy link
Contributor

@gballet gballet commented Feb 27, 2026

No description provided.

Copilot AI review requested due to automatic review settings February 27, 2026 14:16
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements OpenVM proof verification in the openvm-glue FFI layer by deserializing a proof “receipt”, checking it against the target ELF, and invoking the OpenVM SDK verifier.

Changes:

  • Implement openvm_verify to deserialize a proof package, validate the ELF hash, and verify the proof via Sdk::verify_app_proof.
  • Add openvm-circuit dependency to access the concrete proof type (ContinuationVmProof).
  • Update lockfile to include the new dependency.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.

File Description
rust/openvm-glue/src/lib.rs Implements the verifier logic and introduces proof/VK deserialization + ELF hash check.
rust/openvm-glue/Cargo.toml Adds openvm-circuit dependency required for proof type deserialization.
rust/Cargo.lock Lockfile update reflecting the new dependency.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +216 to +228
// Deserialize the app verifying key
let app_vk: AppVerifyingKey = match bincode::deserialize(&proof_package.vk_bytes) {
Ok(k) => k,
Err(e) => {
eprintln!("openvm_verify: failed to deserialize verifying key: {}", e);
return false;
}
};

// Verify the proof using the SDK
let sdk = Sdk::new();
match sdk.verify_app_proof(&app_vk, &proof) {
Ok(_) => true,
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The verifier currently trusts vk_bytes embedded in the receipt and verifies the proof against that key. This lets a malicious prover choose verification parameters/key material (e.g., different AppConfig / security level) and still pass verification, because the verifier never derives or pins the expected verifying key/config independently. Consider deriving the expected AppVerifyingKey from a verifier-side config (or at least validating that the receipt’s config matches a verifier-side policy and that the provided VK matches the derived VK) instead of accepting the VK from the receipt.

Copilot uses AI. Check for mistakes.
Comment on lines +207 to +214
// Deserialize the continuation VM proof
let proof: ContinuationVmProof<SC> = match bincode::deserialize(&proof_package.proof_bytes) {
Ok(p) => p,
Err(e) => {
eprintln!("openvm_verify: failed to deserialize proof: {}", e);
return false;
}
};
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bincode::deserialize(&proof_package.proof_bytes) will also perform potentially unbounded allocations based on attacker-controlled contents of proof_bytes. Even if you cap the outer receipt size, a crafted payload can still request large nested allocations during proof decoding. Consider using bincode::DefaultOptions::new().with_limit(MAX_BYTES) (or another bounded decoding strategy) for the inner proof/VK deserializations as well.

Copilot uses AI. Check for mistakes.
Comment on lines +180 to +187
// Deserialize the proof package from receipt bytes
let proof_package: OpenVMProofPackage = match bincode::deserialize(receipt_slice) {
Ok(p) => p,
Err(e) => {
eprintln!("openvm_verify: failed to deserialize proof package: {}", e);
return false;
}
};
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

openvm_verify deserializes receipt_slice via bincode::deserialize with no size limits. Since receipt is untrusted FFI input, this can trigger unbounded allocations / OOM (DoS) via large Vec lengths inside the payload. Consider using bincode::DefaultOptions::new().with_limit(MAX_BYTES) (and/or validate receipt_len up front) before deserializing OpenVMProofPackage.

Copilot uses AI. Check for mistakes.
@gballet gballet force-pushed the prove-and-verify-openvm branch from e6feebf to 38069bd Compare March 6, 2026 11:23
Copilot AI review requested due to automatic review settings March 6, 2026 11:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +210 to +225
// Deserialize the continuation VM proof
let proof: ContinuationVmProof<SC> = match bincode::deserialize(&proof_package.proof_bytes) {
Ok(p) => p,
Err(e) => {
eprintln!("openvm_verify: failed to deserialize proof: {}", e);
return false;
}
};

// Deserialize the app verifying key
let app_vk: AppVerifyingKey = match bincode::deserialize(&proof_package.vk_bytes) {
Ok(k) => k,
Err(e) => {
eprintln!("openvm_verify: failed to deserialize verifying key: {}", e);
return false;
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proof and verifying key are also deserialized from attacker-controlled bytes with no explicit size/alloc limit (proof_bytes / vk_bytes). To avoid DoS via crafted receipts, cap total receipt size and/or use bounded bincode options for these deserializations too.

Copilot uses AI. Check for mistakes.
return false;
}
};

Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OpenVMProofPackage includes app_log_blowup, but openvm_verify never uses or validates it. Either remove it from the serialized package (if unnecessary) or use it to sanity-check that the receipt was created with the expected security/config parameters (and update the struct field comment accordingly).

Suggested change
// Sanity-check that the proof was generated with the expected app_log_blowup
let expected_app_log_blowup = SdkVmConfig::<SC>::default().app_log_blowup;
if proof_package.app_log_blowup != expected_app_log_blowup {
eprintln!(
"openvm_verify: app_log_blowup mismatch — expected {}, got {}",
expected_app_log_blowup, proof_package.app_log_blowup
);
return false;
}

Copilot uses AI. Check for mistakes.
Comment on lines 148 to +170
extern "C" fn openvm_verify(
_binary_path: *const u8,
_binary_path_len: usize,
_receipt: *const u8,
_receipt_len: usize,
binary_path: *const u8,
binary_path_len: usize,
receipt: *const u8,
receipt_len: usize,
) -> bool {
// TODO: Implement verification
eprintln!("OpenVM verification not yet implemented");
true
let binary_path_slice = unsafe {
if !binary_path.is_null() {
std::slice::from_raw_parts(binary_path, binary_path_len)
} else {
eprintln!("openvm_verify: binary_path is null");
return false;
}
};

let receipt_slice = unsafe {
if !receipt.is_null() {
std::slice::from_raw_parts(receipt, receipt_len)
} else {
eprintln!("openvm_verify: receipt is null");
return false;
}
};
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

openvm_verify adds a fair amount of parsing/validation logic (null checks, UTF-8 handling, bincode decode failures, ELF hash mismatch, proof verification). Please add unit tests that cover at least the negative/error paths so FFI callers get stable behavior when inputs are malformed (these can be done without generating a real proof).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants