1pub(crate) mod rescue;
11pub(crate) mod solidity;
12pub(crate) mod standard;
13
14pub use rescue::RescueTranscript;
15pub use solidity::SolidityTranscript;
16pub use standard::StandardTranscript;
17
18use crate::{
19 errors::PlonkError,
20 proof_system::structs::{PlookupEvaluations, ProofEvaluations, VerifyingKey},
21};
22use ark_ec::{
23 pairing::Pairing,
24 short_weierstrass::{Affine, SWCurveConfig as SWParam},
25};
26use ark_ff::PrimeField;
27use ark_std::vec::Vec;
28use jf_pcs::prelude::Commitment;
29use jf_utils::to_bytes;
30
31pub trait PlonkTranscript<F> {
42 fn new(label: &'static [u8]) -> Self;
44
45 fn append_vk_and_pub_input<E, P>(
47 &mut self,
48 vk: &VerifyingKey<E>,
49 pub_input: &[E::ScalarField],
50 ) -> Result<(), PlonkError>
51 where
52 E: Pairing<BaseField = F, G1Affine = Affine<P>>,
53 P: SWParam<BaseField = F>,
54 {
55 self.append_message(
56 b"field size in bits",
57 E::ScalarField::MODULUS_BIT_SIZE.to_le_bytes().as_ref(),
58 )?;
59 <Self as PlonkTranscript<F>>::append_message(
60 self,
61 b"domain size",
62 vk.domain_size.to_le_bytes().as_ref(),
63 )?;
64 <Self as PlonkTranscript<F>>::append_message(
65 self,
66 b"input size",
67 vk.num_inputs.to_le_bytes().as_ref(),
68 )?;
69
70 <Self as PlonkTranscript<F>>::append_message(
73 self,
74 b"SRS G2 element",
75 &to_bytes!(&vk.open_key.powers_of_h[1])?,
76 )?;
77
78 self.append_field_elems::<E>(b"wire subsets separators", &vk.k)?;
79 self.append_commitments(b"selector commitments", &vk.selector_comms)?;
80 self.append_commitments(b"sigma commitments", &vk.sigma_comms)?;
81 self.append_field_elems::<E>(b"public input", pub_input)?;
82
83 Ok(())
84 }
85
86 fn append_message(&mut self, label: &'static [u8], msg: &[u8]) -> Result<(), PlonkError>;
88
89 fn append_commitments<E, P>(
91 &mut self,
92 label: &'static [u8],
93 comms: &[Commitment<E>],
94 ) -> Result<(), PlonkError>
95 where
96 E: Pairing<BaseField = F, G1Affine = Affine<P>>,
97 P: SWParam<BaseField = F>,
98 {
99 for comm in comms.iter() {
100 self.append_commitment(label, comm)?;
101 }
102 Ok(())
103 }
104
105 fn append_commitment<E, P>(
107 &mut self,
108 label: &'static [u8],
109 comm: &Commitment<E>,
110 ) -> Result<(), PlonkError>
111 where
112 E: Pairing<BaseField = F, G1Affine = Affine<P>>,
113 P: SWParam<BaseField = F>,
114 {
115 <Self as PlonkTranscript<F>>::append_message(self, label, &to_bytes!(comm)?)
116 }
117
118 fn append_field_elem<E>(
120 &mut self,
121 label: &'static [u8],
122 field: &E::ScalarField,
123 ) -> Result<(), PlonkError>
124 where
125 E: Pairing<BaseField = F>,
126 {
127 <Self as PlonkTranscript<F>>::append_message(self, label, &to_bytes!(field)?)
128 }
129
130 fn append_field_elems<E>(
132 &mut self,
133 label: &'static [u8],
134 fields: &[E::ScalarField],
135 ) -> Result<(), PlonkError>
136 where
137 E: Pairing<BaseField = F>,
138 {
139 for f in fields {
140 self.append_field_elem::<E>(label, f)?;
141 }
142 Ok(())
143 }
144
145 fn append_proof_evaluations<E: Pairing<BaseField = F>>(
147 &mut self,
148 evals: &ProofEvaluations<E::ScalarField>,
149 ) -> Result<(), PlonkError> {
150 self.append_field_elems::<E>(b"wire_evals", &evals.wires_evals)?;
151 self.append_field_elems::<E>(b"wire_sigma_evals", &evals.wire_sigma_evals)?;
152 self.append_field_elem::<E>(b"perm_next_eval", &evals.perm_next_eval)
153 }
154
155 fn append_plookup_evaluations<E: Pairing<BaseField = F>>(
157 &mut self,
158 evals: &PlookupEvaluations<E::ScalarField>,
159 ) -> Result<(), PlonkError> {
160 self.append_field_elem::<E>(b"lookup_table_eval", &evals.range_table_eval)?;
161 self.append_field_elem::<E>(b"h_1_eval", &evals.h_1_eval)?;
162 self.append_field_elem::<E>(b"prod_next_eval", &evals.prod_next_eval)?;
163 self.append_field_elem::<E>(b"lookup_table_next_eval", &evals.range_table_next_eval)?;
164 self.append_field_elem::<E>(b"h_1_next_eval", &evals.h_1_next_eval)?;
165 self.append_field_elem::<E>(b"h_2_next_eval", &evals.h_2_next_eval)
166 }
167
168 fn get_challenge<E>(&mut self, label: &'static [u8]) -> Result<E::ScalarField, PlonkError>
170 where
171 E: Pairing<BaseField = F>;
172
173 fn get_n_challenges<E>(
179 &mut self,
180 labels: &[&'static [u8]],
181 ) -> Result<Vec<E::ScalarField>, PlonkError>
182 where
183 E: Pairing<BaseField = F>,
184 {
185 let mut challenges = Vec::new();
186 for label in labels {
187 challenges.push(self.get_challenge::<E>(label)?);
188 }
189 Ok(challenges)
190 }
191}