Proving and Verifying an AIR

We're finally ready to take the final step--prove and verify an AIR!
Since the code is relatively short, let us present it first and then go over the details.
fn main() {
// --snip--
// Prove
let proof = prove(&[&component], channel, commitment_scheme).unwrap();
// Verify
let channel = &mut Blake2sChannel::default();
let commitment_scheme = &mut CommitmentSchemeVerifier::<Blake2sMerkleChannel>::new(config);
let sizes = component.trace_log_degree_bounds();
commitment_scheme.commit(proof.commitments[0], &sizes[0], channel);
channel.mix_u64(log_num_rows as u64);
commitment_scheme.commit(proof.commitments[1], &sizes[1], channel);
verify(&[&component], channel, commitment_scheme, proof).unwrap();
}
Prove
As you can see, there is only a single line of code added to create the proof. The prove
function performs the FRI and PoW operations under the hood, although technically, the constraint related steps in Figure 1 were not performed in the previous section and are only performed once prove
is called.
Verify
In order to verify our proof, we need to check that the constraints are satisfied using the commitments from the proof. In order to do that, we need to set up a Blake2sChannel
and CommitmentSchemeVerifier<Blake2sMerkleChannel>
, along with the same PcsConfig
that we used when creating the proof. Then, we need to recreate the running hash channel by passing the merkle tree commitments and the log_num_rows
to the CommitmentSchemeVerifier
instance by calling commit
(remember, the order is important!). Then, we can verify the proof using the verify
function.
Try setting the dummy values in the table to 1 instead of 0. Does it fail? If so, can you see why?
Congratulations! We have come full circle. We now know how to create a table, convert it to trace polynomials, commit to them, create constraints over the trace polynomials, and prove and verify the constraints (i.e. an AIR). In the following sections, we will go over some more complicated AIRs to explain Stwo's other features.