Skip to content

The termination check is under-constrained due to incomplete check of "public_values.next_pc == 0". #205

Description

@Koukyosyumei

The verifier determines whether execution properly invoked the halt syscall by checking if public_values.next_pc == 0, as implemented here:

for (i, shard_proof) in proof.0.iter().enumerate() {
let public_values = PublicValues::from_vec(&shard_proof.public_values);
// Verify shard transitions
if i == 0 {
// If it's the first shard, index should be 1.
if public_values.shard != BabyBear::one() {
return Err(MachineVerificationError::InvalidPublicValues(
"first shard not 1",
));
}
if public_values.start_pc != vk.vk.pc_start {
return Err(MachineVerificationError::InvalidPublicValues(
"wrong pc_start",
));
}
} else {
let prev_shard_proof = &proof.0[i - 1];
let prev_public_values = PublicValues::from_vec(&prev_shard_proof.public_values);
// For non-first shards, the index should be the previous index + 1.
if public_values.shard != prev_public_values.shard + BabyBear::one() {
return Err(MachineVerificationError::InvalidPublicValues(
"non incremental shard index",
));
}
// Start pc should be what the next pc declared in the previous shard was.
if public_values.start_pc != prev_public_values.next_pc {
return Err(MachineVerificationError::InvalidPublicValues("pc mismatch"));
}
// Digests and exit code should be the same in all shards.
if public_values.committed_value_digest != prev_public_values.committed_value_digest
|| public_values.deferred_proofs_digest
!= prev_public_values.deferred_proofs_digest
|| public_values.exit_code != prev_public_values.exit_code
{
return Err(MachineVerificationError::InvalidPublicValues(
"digest or exit code mismatch",
));
}
// The last shard should be halted. Halt is signaled with next_pc == 0.
if i == proof.0.len() - 1 && public_values.next_pc != BabyBear::zero() {
return Err(MachineVerificationError::InvalidPublicValues(

However, this check is located inside the else branch for i = 0, and is therefore skipped entirely when the proof contains only one shard.

This issue is disclosed with the permission of @johnchandlerburnham.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions