Skip to content

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

@Koukyosyumei

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.

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