schnorr/src/schnorr_prover.rs
src/schnorr_prover.rsRaw
1use anyhow::Result;
2use plonky2::field::extension::{Extendable, FieldExtension};
3use plonky2::field::types::Field;
4use plonky2::field::goldilocks_field::GoldilocksField;
5use plonky2::hash::hash_types::RichField;
6use plonky2::hash::poseidon::PoseidonHash;
7use plonky2::iop::target::{BoolTarget, Target};
8use plonky2::iop::witness::{PartialWitness, WitnessWrite};
9use plonky2::plonk::circuit_builder::CircuitBuilder;
10use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, CommonCircuitData, VerifierCircuitData, VerifierOnlyCircuitData};
11use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
12use plonky2::plonk::proof::ProofWithPublicInputs;
13
14pub struct SchnorrSignatureTarget {
15 s: Target,
16 e: Target,
17}
18
19pub struct SchnorrPublicKeyTarget {
20 pk: Target,
21}
22
23pub struct SchnorrBuilder {
24
25}
26
27impl SchnorrBuilder {
28 // the output Target is constrained to equal x^a
29 // here we assume that
30
31 // waaait, maybe I can use their built in thing
32 fn prove_power<
33 F: RichField + Extendable<D>,
34 C: GenericConfig<D, F = F>,
35 const D: usize
36 > (builder: &mut CircuitBuilder::<F, D>, x: Target, a: Target, num_bits: usize) -> Target {
37 let bits: Vec<BoolTarget> = builder.split_le(a, num_bits);
38 // make a sequence of targets x_i
39 // where x_0 = 1
40 // x_{num_bits} = x^a
41 // and in between:
42 // x_i = x_{i-1}**2 * (bits[num_bits+1-i] ? 1 : x)
43
44 }
45
46 fn constrain_sig <
47 C: GenericConfig<2, F = GoldilocksField>,
48 > (
49 builder: &mut CircuitBuilder::<GoldilocksField, 2>,
50 sig: &SchnorrSignatureTarget,
51 msg: &Vec<Target>,
52 pk: &SchnorrPublicKeyTarget,
53 ) -> () {
54 let PRIME_GROUP_GEN: Target = builder.constant(GoldilocksField::from_canonical_u64(6612579038192137166));
55 const num_bits_exp: usize = 32;
56
57 /*
58 let r: GoldilocksField = Self::pow(self.PRIME_GROUP_GEN, sig.s)
59 * Self::pow(pk.pk, sig.e);
60 let e_v: u64 = self.hash_insecure(&r, msg);
61 e_v == sig.e */
62
63 let gs: Target = builder.exp(PRIME_GROUP_GEN, sig.s, num_bits_exp);
64 let pe: Target = builder.exp(pk.pk, sig.e, num_bits_exp);
65 let r: Target = builder.mul(gs, pe);
66
67 // compute hash
68 let hash_input: Vec<Target> = std::iter::once(r)
69 .chain(msg.iter().cloned())
70 .collect();
71 let e: Target = builder.hash_n_to_hash_no_pad::<PoseidonHash>(
72 hash_input,
73 ).elements[0];
74
75 // verify equality
76 builder.connect(e, sig.e);
77
78 }
79}