plonky2-recursion-experiment/src/example_innercircuit.rs
src/example_innercircuit.rsRaw
1/// This file contains a simple example implementing the InnerCircuit trait, by a circuit that
2/// checks a signature over the given msg.
3use anyhow::Result;
4use plonky2::iop::target::BoolTarget;
5use plonky2::iop::witness::PartialWitness;
6use plonky2::plonk::circuit_builder::CircuitBuilder;
7
8use sch::schnorr::*;
9use sch::schnorr_prover::*;
10
11use super::tree_recursion::{selector_gate, InnerCircuit};
12use super::{C, D, F};
13
14pub struct ExampleGadgetInput {
15 pub pk: SchnorrPublicKey,
16 pub sig: SchnorrSignature,
17}
18
19pub struct ExampleGadgetTargets {
20 pub pk_targ: SchnorrPublicKeyTarget,
21 pub sig_targ: SchnorrSignatureTarget,
22}
23
24/// The logic of this gadget verifies the given signature if `selector==0`.
25///
26/// It implements the InnerCircuit trait, so it contains the methods to `add_targets` (ie. create
27/// the targets, the logic of the circuit), and `set_targets` (ie. set the specific values to be
28/// used for the previously created targets).
29pub struct ExampleGadget {}
30
31impl InnerCircuit for ExampleGadget {
32 type Input = ExampleGadgetInput;
33 type Targets = ExampleGadgetTargets;
34
35 fn add_targets(
36 mut builder: &mut CircuitBuilder<F, D>,
37 selector_booltarg: &BoolTarget,
38 msg_targ: &MessageTarget,
39 ) -> Result<Self::Targets> {
40 // signature verification:
41 let sb: SchnorrBuilder = SchnorrBuilder {};
42 let pk_targ = SchnorrPublicKeyTarget::new_virtual(&mut builder);
43 let sig_targ = SchnorrSignatureTarget::new_virtual(&mut builder);
44 let sig_verif_targ = sb.verify_sig::<C>(&mut builder, &sig_targ, &msg_targ, &pk_targ);
45
46 // if selector==0: verify the signature; else: don't check it. ie:
47 // if selector=0: check that sig_verif==1
48 // if selector=1: check that one==1
49 let one = builder.one();
50 let expected = selector_gate(
51 builder,
52 sig_verif_targ.target,
53 one,
54 selector_booltarg.target,
55 );
56 let one_2 = builder.one();
57 builder.connect(expected, one_2);
58
59 Ok(Self::Targets { pk_targ, sig_targ })
60 }
61
62 fn set_targets(
63 pw: &mut PartialWitness<F>,
64 targets: &Self::Targets,
65 pod: &Self::Input,
66 ) -> Result<()> {
67 // set signature related values:
68 targets.pk_targ.set_witness(pw, &pod.pk).unwrap();
69 targets.sig_targ.set_witness(pw, &pod.sig).unwrap();
70
71 Ok(())
72 }
73}