tasm_lib/verifier/fri/
collinearity_check_x.rs1use triton_vm::prelude::*;
2
3use crate::field;
4use crate::prelude::*;
5use crate::verifier::fri::verify::FriVerify;
6
7#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
9pub struct GetCollinearityCheckX;
10
11impl BasicSnippet for GetCollinearityCheckX {
12 fn parameters(&self) -> Vec<(DataType, String)> {
13 vec![
14 (DataType::VoidPointer, "*fri_verify".to_string()),
15 (DataType::U32, "index".to_string()),
16 (DataType::U32, "round".to_string()),
17 ]
18 }
19
20 fn return_values(&self) -> Vec<(DataType, String)> {
21 vec![(DataType::Xfe, "evaluation_argument".to_string())]
22 }
23
24 fn entrypoint(&self) -> String {
25 "tasmlib_verifier_collinearity_check_x".to_string()
26 }
27
28 fn code(&self, _: &mut Library) -> Vec<LabelledInstruction> {
29 let entrypoint = self.entrypoint();
30 let domain_offset = field!(FriVerify::domain_offset);
31 let domain_generator = field!(FriVerify::domain_generator);
32
33 triton_asm! {
34 {entrypoint}:
37 dup 2 {&domain_generator} read_mem 1 pop 1 dup 2 swap 1 pow dup 3 {&domain_offset} read_mem 1 pop 1 mul dup 1 push 2 pow swap 1 pow swap 3 pop 3 push 0 push 0 swap 2
54 return
56 }
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use num_traits::Zero;
63
64 use super::*;
65 use crate::empty_stack;
66 use crate::test_prelude::*;
67
68 impl Function for GetCollinearityCheckX {
69 fn rust_shadow(
70 &self,
71 stack: &mut Vec<BFieldElement>,
72 memory: &mut HashMap<BFieldElement, BFieldElement>,
73 ) -> Result<(), RustShadowError> {
74 let round = stack.pop().ok_or(RustShadowError::StackUnderflow)?.value() as usize;
76 let index = stack.pop().ok_or(RustShadowError::StackUnderflow)?.value() as u32;
77 let fri_verify_address = stack.pop().ok_or(RustShadowError::StackUnderflow)?;
78
79 let fri_verify = FriVerify::decode_from_memory(memory, fri_verify_address)
81 .map_err(|_| RustShadowError::DecodingError)?;
82
83 let x = fri_verify.get_collinearity_check_x(index, round);
85
86 stack.push(x.coefficients[2]);
88 stack.push(x.coefficients[1]);
89 stack.push(x.coefficients[0]);
90 Ok(())
91 }
92
93 fn pseudorandom_initial_state(
94 &self,
95 seed: [u8; 32],
96 bench_case: Option<BenchmarkCase>,
97 ) -> FunctionInitialState {
98 let mut rng = StdRng::from_seed(seed);
99 let round = if let Some(case) = bench_case {
100 match case {
101 BenchmarkCase::CommonCase => 10,
102 BenchmarkCase::WorstCase => 20,
103 }
104 } else {
105 rng.random_range(0..10)
106 };
107 let fri_domain_length = if let Some(case) = bench_case {
108 match case {
109 BenchmarkCase::CommonCase => 1 << 20,
110 BenchmarkCase::WorstCase => 1 << 25,
111 }
112 } else {
113 1 << (rng.random_range(0..5) + round)
114 };
115 let index = rng.random_range(0..fri_domain_length);
116
117 let fri_verify = FriVerify::new(rng.random(), fri_domain_length, 4, 40);
118
119 let mut memory = HashMap::<BFieldElement, BFieldElement>::new();
120 let fri_verify_address = BFieldElement::zero();
121 encode_to_memory(&mut memory, fri_verify_address, &fri_verify);
122
123 let mut stack = empty_stack();
124 stack.push(fri_verify_address);
125 stack.push(BFieldElement::new(index as u64));
126 stack.push(BFieldElement::new(round as u64));
127
128 FunctionInitialState { stack, memory }
129 }
130 }
131
132 #[macro_rules_attr::apply(test)]
133 fn test() {
134 ShadowedFunction::new(GetCollinearityCheckX).test();
135 }
136}
137
138#[cfg(test)]
139mod bench {
140 use super::*;
141 use crate::test_prelude::*;
142
143 #[macro_rules_attr::apply(test)]
144 fn bench() {
145 ShadowedFunction::new(GetCollinearityCheckX).bench();
146 }
147}