arnaucube
arnaucube/schnorrPublic Self-hosted repository
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}