tasm_lib/verifier/challenges/
new_generic_dyn_claim.rs1use num::One;
2use triton_vm::air::challenge_id::ChallengeId;
3use triton_vm::air::cross_table_argument::CrossTableArg;
4use triton_vm::air::cross_table_argument::EvalArg;
5use triton_vm::challenges::Challenges;
6use triton_vm::prelude::*;
7use twenty_first::math::x_field_element::EXTENSION_DEGREE;
8
9use crate::hashing::algebraic_hasher::sample_scalars_static_length_static_pointer::SampleScalarsStaticLengthStaticPointer;
10use crate::prelude::*;
11use crate::verifier::challenges::shared::challenges_data_type;
12use crate::verifier::claim::shared::claim_type;
13use crate::verifier::eval_arg::compute_terminal_const_sized_static_symbols::ComputeTerminalConstSizedStaticSymbols;
14use crate::verifier::eval_arg::compute_terminal_dyn_sized_dynamic_symbols::ComputeTerminalDynSizedDynamicSymbols;
15use crate::verifier::eval_arg::compute_terminal_from_digest::ComputeTerminalFromDigestInitialIsOne;
16
17#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
19pub struct NewGenericDynClaim {
20 num_of_fiat_shamir_challenges: usize,
21 num_of_claim_derived_challenges: usize,
22
23 pub challenges_pointer: BFieldElement,
25}
26
27impl NewGenericDynClaim {
28 pub fn tvm_challenges(challenges_pointer: BFieldElement) -> Self {
31 Self {
32 num_of_fiat_shamir_challenges: Challenges::SAMPLE_COUNT,
33 num_of_claim_derived_challenges: ChallengeId::NUM_DERIVED_CHALLENGES,
34 challenges_pointer,
35 }
36 }
37
38 pub fn new(
39 num_challenges_to_sample: usize,
40 num_challenges_to_compute: usize,
41 challenges_pointer: BFieldElement,
42 ) -> Self {
43 Self {
44 num_of_fiat_shamir_challenges: num_challenges_to_sample,
45 num_of_claim_derived_challenges: num_challenges_to_compute,
46 challenges_pointer,
47 }
48 }
49
50 fn total_number_of_challenges_returned(&self) -> usize {
51 self.num_of_fiat_shamir_challenges + self.num_of_claim_derived_challenges
52 }
53
54 fn sample_scalars_snippet(&self) -> SampleScalarsStaticLengthStaticPointer {
55 SampleScalarsStaticLengthStaticPointer {
56 num_elements_to_sample: self.num_of_fiat_shamir_challenges,
57 extra_capacity: self.num_of_claim_derived_challenges,
58 scalars_pointer: self.challenges_pointer,
59 }
60 }
61}
62
63impl BasicSnippet for NewGenericDynClaim {
64 fn parameters(&self) -> Vec<(DataType, String)> {
65 vec![(DataType::StructRef(claim_type()), "*claim".to_owned())]
66 }
67
68 fn return_values(&self) -> Vec<(DataType, String)> {
69 vec![(
70 challenges_data_type(self.total_number_of_challenges_returned()),
71 "challenges".to_owned(),
72 )]
73 }
74
75 fn entrypoint(&self) -> String {
76 format!(
77 "tasmlib_verifier_challenges_new_generic_dyn_claim_{}_{}",
78 self.num_of_fiat_shamir_challenges, self.num_of_claim_derived_challenges,
79 )
80 }
81
82 fn code(&self, library: &mut Library) -> Vec<LabelledInstruction> {
83 let entrypoint = self.entrypoint();
84 let sample_scalars_snippet = self.sample_scalars_snippet();
85 let sample_scalars = library.import(Box::new(sample_scalars_snippet));
86 let compute_compressed_digest =
87 library.import(Box::new(ComputeTerminalFromDigestInitialIsOne));
88 let calculate_lookup_terminal =
89 library.import(Box::new(ComputeTerminalConstSizedStaticSymbols {
90 symbols: tip5::LOOKUP_TABLE.map(|i| BFieldElement::new(i as u64)),
91 initial: XFieldElement::one(),
92 }));
93 let calculate_io_terminal = library.import(Box::new(ComputeTerminalDynSizedDynamicSymbols));
94
95 let scalars_pointer = self.challenges_pointer;
96 let scalar_write_index = |i: ChallengeId| {
97 scalars_pointer.value() + u64::try_from(i.index() * EXTENSION_DEGREE).unwrap()
98 };
99 let scalar_read_index =
100 |i: ChallengeId| scalar_write_index(i) + u64::try_from(EXTENSION_DEGREE - 1).unwrap();
101
102 let default_initial = EvalArg::default_initial();
103
104 triton_asm!(
105 {entrypoint}:
106 call {sample_scalars}
108 push {scalar_read_index(ChallengeId::StandardOutputIndeterminate)}
112 read_mem {EXTENSION_DEGREE}
113 pop 1
114 push {default_initial.coefficients[2]}
117 push {default_initial.coefficients[1]}
118 push {default_initial.coefficients[0]}
119 dup 6
122 push 1
123 add
124 call {calculate_io_terminal}
127 push {scalar_write_index(ChallengeId::StandardOutputTerminal)}
130 write_mem {EXTENSION_DEGREE}
131 pop 1
132 push {scalar_read_index(ChallengeId::StandardInputIndeterminate)}
136 read_mem {EXTENSION_DEGREE}
137 pop 1
138 push {default_initial.coefficients[2]}
141 push {default_initial.coefficients[1]}
142 push {default_initial.coefficients[0]}
143 dup 6
146 read_mem 1
147 push 3
148 add
149 add
150 dup 0
153 swap 8
154 pop 1
155 call {calculate_io_terminal}
158 push {scalar_write_index(ChallengeId::StandardInputTerminal)}
161 write_mem {EXTENSION_DEGREE}
162 pop 1
163 read_mem 1
166 addi {1 + 1 + Digest::LEN} add
170 push {scalar_read_index(ChallengeId::CompressProgramDigestIndeterminate)}
173 read_mem {EXTENSION_DEGREE}
174 pop 1
175 dup 3
178 read_mem {Digest::LEN}
179 pop 1
180 call {compute_compressed_digest}
183 push {scalar_write_index(ChallengeId::CompressedProgramDigest)}
187 write_mem {EXTENSION_DEGREE}
188 pop 2
189 push {scalar_read_index(ChallengeId::LookupTablePublicIndeterminate)}
193 read_mem {EXTENSION_DEGREE}
194 pop 1
195 call {calculate_lookup_terminal}
198 push {scalar_write_index(ChallengeId::LookupTablePublicTerminal)}
202 write_mem {EXTENSION_DEGREE}
203 pop 1
204
205 push {scalars_pointer}
208 return
211 )
212 }
213}
214
215#[cfg(test)]
216mod tests {
217 use triton_vm::challenges::Challenges;
218 use twenty_first::math::other::random_elements;
219
220 use super::*;
221 use crate::rust_shadowing_helper_functions::array::insert_as_array;
222 use crate::rust_shadowing_helper_functions::claim::load_claim_from_memory;
223 use crate::test_prelude::*;
224 use crate::verifier::challenges::shared::conventional_challenges_pointer;
225
226 impl Procedure for NewGenericDynClaim {
227 fn rust_shadow(
228 &self,
229 stack: &mut Vec<BFieldElement>,
230 memory: &mut HashMap<BFieldElement, BFieldElement>,
231 _nondeterminism: &NonDeterminism,
232 _public_input: &[BFieldElement],
233 sponge: &mut Option<Tip5>,
234 ) -> Result<Vec<BFieldElement>, RustShadowError> {
235 let Some(sponge) = sponge.as_mut() else {
236 return Err(RustShadowError::SpongeUninitialized);
237 };
238 let claim_pointer = stack.pop().ok_or(RustShadowError::StackUnderflow)?;
239 let claim = load_claim_from_memory(claim_pointer, memory);
240 let challenges = sponge.sample_scalars(self.num_of_fiat_shamir_challenges);
241 let challenges = Challenges::new(challenges, &claim);
242
243 let challenges_pointer = self.challenges_pointer;
244 stack.push(challenges_pointer);
245
246 insert_as_array(challenges_pointer, memory, challenges.challenges.to_vec());
247
248 Ok(Vec::new())
249 }
250
251 fn pseudorandom_initial_state(
252 &self,
253 seed: [u8; 32],
254 bench_case: Option<BenchmarkCase>,
255 ) -> ProcedureInitialState {
256 let mut rng = StdRng::from_seed(seed);
257 let (input_length, output_length) = match bench_case {
258 Some(BenchmarkCase::CommonCase) => (0, 0),
259 Some(BenchmarkCase::WorstCase) => (100, 100),
260 None => (rng.random_range(0..1000), rng.random_range(0..1000)),
261 };
262
263 let claim = Claim::new(rng.random())
264 .with_input(random_elements(input_length))
265 .with_output(random_elements(output_length));
266
267 let mut memory = HashMap::default();
268
269 let claim_pointer = rng.random();
270 encode_to_memory(&mut memory, claim_pointer, &claim);
271
272 let stack = [self.init_stack_for_isolated_run(), vec![claim_pointer]].concat();
273 let sponge = Tip5 {
274 state: rng.random(),
275 };
276
277 ProcedureInitialState {
278 stack,
279 sponge: Some(sponge),
280 nondeterminism: NonDeterminism::default().with_ram(memory),
281 public_input: vec![],
282 }
283 }
284 }
285
286 #[macro_rules_attr::apply(test)]
287 fn new_challenges_pbt() {
288 ShadowedProcedure::new(NewGenericDynClaim::tvm_challenges(
289 conventional_challenges_pointer(),
290 ))
291 .test();
292 }
293}
294
295#[cfg(test)]
296mod benches {
297 use super::*;
298 use crate::test_prelude::*;
299 use crate::verifier::challenges::shared::conventional_challenges_pointer;
300
301 #[macro_rules_attr::apply(test)]
302 fn bench_for_challenges_calc_for_recufier() {
303 ShadowedProcedure::new(NewGenericDynClaim::tvm_challenges(
304 conventional_challenges_pointer(),
305 ))
306 .bench();
307 }
308}