plonky2-crypto-gadgets/ecgfp5/src/circuit.rs
ecgfp5/src/circuit.rsRaw
1//! For LICENSE check out https://github.com/0xPARC/plonky2-crypto-gadgets/blob/main/LICENSE
2
3use plonky2::{
4 field::extension::Extendable, hash::hash_types::RichField, iop::witness::PartialWitness,
5 plonk::circuit_builder::CircuitBuilder,
6};
7use pod2::backends::plonky2::{
8 basetypes::{D, F},
9 primitives::ec::{
10 bits::{BigUInt320Target, CircuitBuilderBits},
11 curve::{CircuitBuilderElliptic, Point, PointTarget, WitnessWriteCurve},
12 },
13};
14
15use crate::ECGFP5SecretKey;
16
17/// EcGFp5 secret key target type
18pub struct ECGFP5SecretKeyTarget(pub BigUInt320Target);
19
20/// EcGFp5 public key (point) type alias
21pub type PublicKeyTarget = PointTarget;
22
23pub trait CircuitBuilderECGFP5PublicKey<F: RichField + Extendable<D>, const D: usize> {
24 /// Adds secret key target
25 fn add_secret_key(&mut self) -> ECGFP5SecretKeyTarget;
26
27 /// Derives public key from secret key
28 fn public_key(&mut self, sk: &ECGFP5SecretKeyTarget) -> PublicKeyTarget;
29}
30
31impl CircuitBuilderECGFP5PublicKey<F, D> for CircuitBuilder<F, D> {
32 fn add_secret_key(&mut self) -> ECGFP5SecretKeyTarget {
33 ECGFP5SecretKeyTarget(self.add_virtual_biguint320_target())
34 }
35
36 fn public_key(&mut self, sk: &ECGFP5SecretKeyTarget) -> PublicKeyTarget {
37 let generator = self.constant_point(Point::generator());
38 self.multiply_point(&sk.0.bits, &generator)
39 }
40}
41
42pub trait PartialWitnessECGFP5PublicKey {
43 /// Sets EcGFp5 secret key witnesses
44 fn set_secret_key_target(
45 &mut self,
46 target: &ECGFP5SecretKeyTarget,
47 value: &ECGFP5SecretKey,
48 ) -> anyhow::Result<()>;
49}
50
51impl PartialWitnessECGFP5PublicKey for PartialWitness<F> {
52 fn set_secret_key_target(
53 &mut self,
54 target: &ECGFP5SecretKeyTarget,
55 value: &ECGFP5SecretKey,
56 ) -> anyhow::Result<()> {
57 self.set_biguint320_target(&target.0, &value.0)
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use plonky2::{
64 iop::witness::PartialWitness,
65 plonk::{
66 circuit_builder::CircuitBuilder, circuit_data::CircuitConfig,
67 config::PoseidonGoldilocksConfig,
68 },
69 };
70 use pod2::backends::plonky2::{
71 basetypes::{D, F},
72 primitives::ec::curve::WitnessWriteCurve,
73 };
74
75 use crate::{
76 ECGFP5SecretKey,
77 circuit::{CircuitBuilderECGFP5PublicKey, PartialWitnessECGFP5PublicKey},
78 };
79
80 #[test]
81 fn public_key_calculation() -> anyhow::Result<()> {
82 let config = CircuitConfig::standard_recursion_config();
83 let mut builder = CircuitBuilder::<F, D>::new(config);
84
85 let sk_target = builder.add_secret_key();
86 let pk_target = builder.public_key(&sk_target);
87
88 let data = builder.build::<PoseidonGoldilocksConfig>();
89 (0..10).try_for_each(|_| {
90 let sk = ECGFP5SecretKey::rand();
91 let pk = sk.public_key();
92
93 let mut pw = PartialWitness::new();
94 pw.set_secret_key_target(&sk_target, &sk)?;
95 pw.set_point_target(&pk_target, &pk)?;
96
97 let proof = data.prove(pw)?;
98 data.verify(proof)
99 })
100 }
101}