tasm_lib/verifier/
own_program_digest.rs

1use triton_vm::prelude::*;
2
3use crate::prelude::*;
4
5/// Return own program digest. Must be called with a clean stack.
6///
7/// Move own program digest to the top of the stack
8/// Must be called as the first function in the program, as
9/// it assumes that the bottom of the stack (stack[15..=11])
10/// contains the digest of the running program
11#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
12pub struct OwnProgramDigest;
13
14impl BasicSnippet for OwnProgramDigest {
15    fn inputs(&self) -> Vec<(DataType, String)> {
16        vec![]
17    }
18
19    fn outputs(&self) -> Vec<(DataType, String)> {
20        vec![(DataType::Digest, "own_program_digest".to_owned())]
21    }
22
23    fn entrypoint(&self) -> String {
24        "tasmlib_verifier_own_program_digest".to_owned()
25    }
26
27    fn code(&self, _library: &mut Library) -> Vec<LabelledInstruction> {
28        triton_asm!(
29            {self.entrypoint()}:
30                dup 15
31                dup 15
32                dup 15
33                dup 15
34                dup 15
35
36                return
37        )
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44    use crate::execute_with_terminal_state;
45
46    #[derive(Debug, Clone, Eq, PartialEq)]
47    struct ProgramSetup {
48        program: Program,
49        program_digest: Digest,
50        init_stack: Vec<BFieldElement>,
51    }
52
53    fn test_program() -> ProgramSetup {
54        let snippet = OwnProgramDigest;
55        let program = Program::new(&snippet.link_for_isolated_run());
56        let program_digest = program.hash();
57        let init_stack = snippet.init_stack_for_isolated_run();
58
59        ProgramSetup {
60            program,
61            program_digest,
62            init_stack,
63        }
64    }
65
66    #[test]
67    fn positive_test() {
68        let test_setup = test_program();
69
70        let vm_end_state = execute_with_terminal_state(
71            test_setup.program,
72            &[],
73            &test_setup.init_stack,
74            &NonDeterminism::default(),
75            None,
76        )
77        .unwrap();
78
79        let expected_stack = [
80            test_setup.init_stack.clone(),
81            test_setup.init_stack[..Digest::LEN].to_vec(),
82        ]
83        .concat();
84        assert_eq!(expected_stack, vm_end_state.op_stack.stack);
85        assert!(vm_end_state.jump_stack.is_empty());
86    }
87}