Verifying

Verifying a linked proof looks just like proving one. You'll call the same methods on the LinkedProofVerificationBuilder that you did on the LinkedProofBuilder, in the same order, but instead of supplying the private values, you'll supply the public ones. Then you'll specify the proof, ZKP program, and any public or constant inputs, as we did for the unlinked ZKP programs.

use sunscreen::{
    bulletproofs::BulletproofsBackend,
    fhe_program,
    linked::{LinkedProof, LinkedProofBuilder},
    types::{
        bfv::Signed,
        zkp::{
            AsFieldElement, BfvSigned, BulletproofsField, ConstrainCmp, ConstrainFresh, Field,
            FieldSpec,
        },
        Cipher,
    },
    zkp_program, zkp_var, Ciphertext, CompiledFheProgram, CompiledZkpProgram, Compiler, Error,
    FheProgramInput, FheRuntime, FheZkpApplication, FheZkpRuntime, Params, PrivateKey, PublicKey,
    Result, ZkpProgramInput,
};

#[fhe_program(scheme = "bfv")]
fn increase_by_factor(x: Signed, scale: Cipher<Signed>) -> Cipher<Signed> {
    x * scale
}

#[zkp_program]
fn is_greater_than_one<F: FieldSpec>(#[linked] scale: BfvSigned<F>) {
    scale
        .into_field_elem()
        .constrain_gt_bounded(zkp_var!(1), 64);
}
fn main() -> Result<(), Error> {
let app = Compiler::new()
    .fhe_program(increase_by_factor)
    .zkp_backend::<BulletproofsBackend>()
    .zkp_program(is_greater_than_one)
    .compile()?;
let runtime = FheZkpRuntime::new(app.params(), &BulletproofsBackend::new())?;
let (public_key, private_key) = runtime.generate_keys()?;

let mut proof_builder = runtime.linkedproof_builder();

let (ct, link) = proof_builder.encrypt_returning_link(&Signed::from(2), &public_key)?;
let proof = proof_builder
    .zkp_program(app.get_zkp_program(is_greater_than_one).unwrap())?
    .linked_input(link)
    .build()?;

let mut verify_builder = runtime.linkedproof_verification_builder();
verify_builder.encrypt_returning_link::<Signed>(&ct, &public_key)?;
verify_builder
    .proof(proof)
    .zkp_program(app.get_zkp_program(is_greater_than_one).unwrap())?
    .verify()?;
    Ok(())
}