tasm_lib/hashing/algebraic_hasher/
sample_scalar_one.rs

1use triton_vm::prelude::*;
2
3use crate::prelude::*;
4
5/// Sample a single scalar from the sponge state
6#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
7pub struct SampleScalarOne;
8
9impl BasicSnippet for SampleScalarOne {
10    fn inputs(&self) -> Vec<(DataType, String)> {
11        vec![]
12    }
13
14    fn outputs(&self) -> Vec<(DataType, String)> {
15        vec![(DataType::Xfe, "scalar".to_owned())]
16    }
17
18    fn entrypoint(&self) -> String {
19        "tasmlib_hashing_algebraic_hasher_sample_scalar_one".to_owned()
20    }
21
22    fn code(&self, _: &mut Library) -> Vec<LabelledInstruction> {
23        let entrypoint = self.entrypoint();
24
25        triton_asm!(
26            {entrypoint}:
27                // _
28
29                sponge_squeeze
30                // _ r9 r8 r7 r6 r5 r4 r3 r2 r1 r0
31
32                swap 7
33                pop 1
34                swap 7
35                pop 1
36                swap 7
37                // _ r2 r1 r0 r6 r5 r4 r3 r9
38
39                pop 5
40                // _ r2 r1 r0
41
42                return
43        )
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use twenty_first::math::x_field_element::EXTENSION_DEGREE;
50    use twenty_first::util_types::sponge::Sponge;
51
52    use super::*;
53    use crate::test_prelude::*;
54
55    #[test]
56    fn sample_scalar_one_test() {
57        ShadowedProcedure::new(SampleScalarOne).test();
58    }
59
60    impl Procedure for SampleScalarOne {
61        fn rust_shadow(
62            &self,
63            stack: &mut Vec<BFieldElement>,
64            _memory: &mut HashMap<BFieldElement, BFieldElement>,
65            _nondeterminism: &NonDeterminism,
66            _public_input: &[BFieldElement],
67            sponge: &mut Option<Tip5>,
68        ) -> Vec<BFieldElement> {
69            let vals = sponge.as_mut().unwrap().squeeze();
70
71            for word in vals.iter().take(EXTENSION_DEGREE).rev() {
72                stack.push(*word)
73            }
74
75            vec![]
76        }
77
78        fn pseudorandom_initial_state(
79            &self,
80            _seed: [u8; 32],
81            _bench_case: Option<BenchmarkCase>,
82        ) -> ProcedureInitialState {
83            ProcedureInitialState {
84                stack: self.init_stack_for_isolated_run(),
85                nondeterminism: NonDeterminism::default(),
86                public_input: vec![],
87                sponge: Some(Tip5 {
88                    state: rand::random(),
89                }),
90            }
91        }
92    }
93}