arnaucube
arnaucube/plonky2-recursion-experimentPublic Self-hosted repository
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}