jf_plonk/transcript/
rescue.rs
1use super::PlonkTranscript;
9use crate::{
10 errors::PlonkError,
11 proof_system::structs::{PlookupEvaluations, ProofEvaluations, VerifyingKey},
12};
13use ark_ec::{
14 pairing::Pairing,
15 short_weierstrass::{Affine, SWCurveConfig as SWParam},
16};
17use ark_std::vec::Vec;
18use jf_crhf::CRHF;
19use jf_pcs::prelude::Commitment;
20use jf_relation::gadgets::ecc::{SWToTEConParam, TEPoint};
21use jf_rescue::{crhf::VariableLengthRescueCRHF, RescueParameter, STATE_SIZE};
22use jf_utils::{bytes_to_field_elements, field_switching, fq_to_fr_with_mask};
23
24pub struct RescueTranscript<F>
38where
39 F: RescueParameter,
40{
41 transcript: Vec<F>,
42 state: [F; STATE_SIZE],
43}
44
45impl<F> PlonkTranscript<F> for RescueTranscript<F>
46where
47 F: RescueParameter + SWToTEConParam,
48{
49 fn new(_label: &'static [u8]) -> Self {
51 RescueTranscript {
52 transcript: Vec::new(),
53 state: [F::zero(); STATE_SIZE],
54 }
55 }
56
57 fn append_vk_and_pub_input<E, P>(
58 &mut self,
59 vk: &VerifyingKey<E>,
60 pub_input: &[E::ScalarField],
61 ) -> Result<(), PlonkError>
62 where
63 E: Pairing<BaseField = F, G1Affine = Affine<P>>,
64 P: SWParam<BaseField = F>,
65 {
66 for com in vk.selector_comms.iter() {
75 let te_point: TEPoint<F> = com.0.into();
77 self.transcript.push(te_point.get_x());
78 self.transcript.push(te_point.get_y());
79 }
80 for com in vk.sigma_comms.iter() {
82 let te_point: TEPoint<F> = com.0.into();
84 self.transcript.push(te_point.get_x());
85 self.transcript.push(te_point.get_y());
86 }
87 for e in pub_input {
89 self.transcript.push(field_switching(e))
90 }
91
92 Ok(())
93 }
94
95 fn append_message(&mut self, _label: &'static [u8], msg: &[u8]) -> Result<(), PlonkError> {
98 let mut f = bytes_to_field_elements(msg);
101 self.transcript.append(&mut f);
102 Ok(())
103 }
104
105 fn append_commitment<E, P>(
108 &mut self,
109 _label: &'static [u8],
110 comm: &Commitment<E>,
111 ) -> Result<(), PlonkError>
112 where
113 E: Pairing<BaseField = F, G1Affine = Affine<P>>,
114 P: SWParam<BaseField = F>,
115 {
116 let te_point: TEPoint<F> = comm.0.into();
118 self.transcript.push(te_point.get_x());
122 self.transcript.push(te_point.get_y());
123 Ok(())
124 }
125
126 fn append_field_elem<E>(
127 &mut self,
128 _label: &'static [u8],
129 challenge: &E::ScalarField,
130 ) -> Result<(), PlonkError>
131 where
132 E: Pairing<BaseField = F>,
133 {
134 self.transcript.push(field_switching(challenge));
135 Ok(())
136 }
137
138 fn append_proof_evaluations<E: Pairing>(
139 &mut self,
140 evals: &ProofEvaluations<E::ScalarField>,
141 ) -> Result<(), PlonkError> {
142 for e in &evals.wires_evals {
143 self.transcript.push(field_switching(e))
144 }
145 for e in &evals.wire_sigma_evals {
146 self.transcript.push(field_switching(e))
147 }
148 self.transcript.push(field_switching(&evals.perm_next_eval));
149 Ok(())
150 }
151
152 fn append_plookup_evaluations<E: Pairing>(
153 &mut self,
154 evals: &PlookupEvaluations<E::ScalarField>,
155 ) -> Result<(), PlonkError> {
156 for eval in evals.evals_vec().iter() {
157 self.transcript.push(field_switching(eval));
158 }
159 for next_eval in evals.next_evals_vec().iter() {
160 self.transcript.push(field_switching(next_eval));
161 }
162 Ok(())
163 }
164
165 fn get_challenge<E>(&mut self, _label: &'static [u8]) -> Result<E::ScalarField, PlonkError>
168 where
169 E: Pairing<BaseField = F>,
170 {
171 let input = [self.state.as_ref(), self.transcript.as_ref()].concat();
176 let tmp: [F; STATE_SIZE] = VariableLengthRescueCRHF::evaluate(&input)?;
177 let challenge = fq_to_fr_with_mask::<F, E::ScalarField>(&tmp[0]);
178 self.state.copy_from_slice(&tmp);
179 self.transcript = Vec::new();
180
181 Ok(challenge)
182 }
183}