tasm_lib/verifier/eval_arg/
compute_terminal_from_digest.rs

1use triton_vm::prelude::*;
2
3use crate::prelude::*;
4
5#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
6pub struct ComputeTerminalFromDigestInitialIsOne;
7
8impl BasicSnippet for ComputeTerminalFromDigestInitialIsOne {
9    fn inputs(&self) -> Vec<(DataType, String)> {
10        vec![
11            (DataType::Xfe, "challenge".to_owned()),
12            (DataType::Digest, "digest".to_owned()),
13        ]
14    }
15
16    fn outputs(&self) -> Vec<(DataType, String)> {
17        vec![(DataType::Xfe, "terminal".to_owned())]
18    }
19
20    fn entrypoint(&self) -> String {
21        "tasmlib_verifier_eval_arg_compute_terminal_from_digest".to_owned()
22    }
23
24    fn code(&self, _library: &mut Library) -> Vec<LabelledInstruction> {
25        let entrypoint = self.entrypoint();
26
27        triton_asm!(
28            {entrypoint}:
29                // _ [challenge] d4 d3 d2 d1 d0
30
31                dup 7
32                dup 7
33                dup 7
34                // _ [challenge] d4 d3 d2 d1 d0 c2 c1 c0
35
36                dup 3
37                add
38                // _ [challenge] d4 d3 d2 d1 d0 [challenge + d0]
39
40                dup 10
41                dup 10
42                dup 10
43                xx_mul
44                // _ [challenge] d4 d3 d2 d1 d0 [(challenge + d0) * challenge]
45
46                dup 4
47                add
48                // _ [challenge] d4 d3 d2 d1 d0 [(challenge + d0) * challenge + d1]
49
50                dup 10
51                dup 10
52                dup 10
53                xx_mul
54                // _ [challenge] d4 d3 d2 d1 d0 [((challenge + d0) * challenge + d1) * challenge]
55
56                dup 5
57                add
58                // _ [challenge] d4 d3 d2 d1 d0 [((challenge + d0) * challenge + d1) * challenge + d2]
59
60                dup 10
61                dup 10
62                dup 10
63                xx_mul
64                dup 6
65                add
66                // _ [challenge] d4 d3 d2 d1 d0 [running_eval_3]
67
68                dup 10
69                dup 10
70                dup 10
71                xx_mul
72                dup 7
73                add
74                // _ [challenge] d4 d3 d2 d1 d0 [terminal]
75
76                swap 8
77                pop 1
78                swap 8
79                pop 1
80                swap 8
81                pop 1
82                // _ [terminal] d4 d3 d2 d1 d0
83
84                pop 5
85                // _ [terminal]
86
87                return
88        )
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use triton_vm::air::cross_table_argument::CrossTableArg;
95    use triton_vm::air::cross_table_argument::EvalArg;
96
97    use super::*;
98    use crate::test_prelude::*;
99
100    impl Closure for ComputeTerminalFromDigestInitialIsOne {
101        type Args = (XFieldElement, Digest);
102
103        fn rust_shadow(&self, stack: &mut Vec<BFieldElement>) {
104            let (challenge, digest) = pop_encodable::<Self::Args>(stack);
105            let terminal =
106                EvalArg::compute_terminal(&digest.0, EvalArg::default_initial(), challenge);
107            push_encodable(stack, &terminal);
108        }
109
110        fn pseudorandom_args(&self, seed: [u8; 32], _: Option<BenchmarkCase>) -> Self::Args {
111            StdRng::from_seed(seed).random()
112        }
113    }
114
115    #[test]
116    fn rust_shadow() {
117        ShadowedClosure::new(ComputeTerminalFromDigestInitialIsOne).test();
118    }
119}
120
121#[cfg(test)]
122mod benches {
123    use super::*;
124    use crate::test_prelude::*;
125
126    #[test]
127    fn benchmark() {
128        ShadowedClosure::new(ComputeTerminalFromDigestInitialIsOne).bench()
129    }
130}