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 inputs(&self) -> Vec<(DataType, String)> {
65 vec![(DataType::StructRef(claim_type()), "*claim".to_owned())]
66 }
67
68 fn outputs(&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 ) -> Vec<BFieldElement> {
235 let sponge = sponge.as_mut().expect("sponge must be initialized");
236 let claim_pointer = stack.pop().unwrap();
237 let claim = load_claim_from_memory(claim_pointer, memory);
238 let challenges = sponge.sample_scalars(self.num_of_fiat_shamir_challenges);
239 let challenges = Challenges::new(challenges, &claim);
240
241 let challenges_pointer = self.challenges_pointer;
242 stack.push(challenges_pointer);
243
244 insert_as_array(challenges_pointer, memory, challenges.challenges.to_vec());
245
246 vec![]
247 }
248
249 fn pseudorandom_initial_state(
250 &self,
251 seed: [u8; 32],
252 bench_case: Option<BenchmarkCase>,
253 ) -> ProcedureInitialState {
254 let mut rng = StdRng::from_seed(seed);
255 let (input_length, output_length) = match bench_case {
256 Some(BenchmarkCase::CommonCase) => (0, 0),
257 Some(BenchmarkCase::WorstCase) => (100, 100),
258 None => (rng.random_range(0..1000), rng.random_range(0..1000)),
259 };
260
261 let claim = Claim::new(rng.random())
262 .with_input(random_elements(input_length))
263 .with_output(random_elements(output_length));
264
265 let mut memory = HashMap::default();
266
267 let claim_pointer = rng.random();
268 encode_to_memory(&mut memory, claim_pointer, &claim);
269
270 let stack = [self.init_stack_for_isolated_run(), vec![claim_pointer]].concat();
271 let sponge = Tip5 {
272 state: rng.random(),
273 };
274
275 ProcedureInitialState {
276 stack,
277 sponge: Some(sponge),
278 nondeterminism: NonDeterminism::default().with_ram(memory),
279 public_input: vec![],
280 }
281 }
282 }
283
284 #[test]
285 fn new_challenges_pbt() {
286 ShadowedProcedure::new(NewGenericDynClaim::tvm_challenges(
287 conventional_challenges_pointer(),
288 ))
289 .test();
290 }
291}
292
293#[cfg(test)]
294mod benches {
295 use super::*;
296 use crate::test_prelude::*;
297 use crate::verifier::challenges::shared::conventional_challenges_pointer;
298
299 #[test]
300 fn bench_for_challenges_calc_for_recufier() {
301 ShadowedProcedure::new(NewGenericDynClaim::tvm_challenges(
302 conventional_challenges_pointer(),
303 ))
304 .bench();
305 }
306}