tasm_lib/arithmetic/u32/
is_odd.rs1use std::collections::HashMap;
2
3use triton_vm::prelude::*;
4
5use crate::prelude::*;
6use crate::traits::basic_snippet::Reviewer;
7use crate::traits::basic_snippet::SignOffFingerprint;
8
9#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
26pub struct IsOdd;
27
28impl BasicSnippet for IsOdd {
29 fn parameters(&self) -> Vec<(DataType, String)> {
30 vec![(DataType::U32, "value".to_string())]
31 }
32
33 fn return_values(&self) -> Vec<(DataType, String)> {
34 vec![(DataType::Bool, "value % 2".to_string())]
35 }
36
37 fn entrypoint(&self) -> String {
38 "tasmlib_arithmetic_u32_is_odd".to_string()
39 }
40
41 fn code(&self, _: &mut Library) -> Vec<LabelledInstruction> {
42 triton_asm!(
43 {self.entrypoint()}:
46 push 2
47 pick 1
48 div_mod
49 pick 1
50 pop 1
51 return
52 )
53 }
54
55 fn sign_offs(&self) -> HashMap<Reviewer, SignOffFingerprint> {
56 let mut sign_offs = HashMap::new();
57 sign_offs.insert(Reviewer("ferdinand"), 0xa573894027409e47.into());
58 sign_offs
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use crate::test_prelude::*;
66
67 impl Closure for IsOdd {
68 type Args = u32;
69
70 fn rust_shadow(&self, stack: &mut Vec<BFieldElement>) -> Result<(), RustShadowError> {
71 let v = pop_encodable::<Self::Args>(stack)?;
72 let is_odd = v % 2 == 1;
73 push_encodable(stack, &is_odd);
74 Ok(())
75 }
76
77 fn pseudorandom_args(
78 &self,
79 seed: [u8; 32],
80 bench_case: Option<BenchmarkCase>,
81 ) -> Self::Args {
82 match bench_case {
83 Some(BenchmarkCase::CommonCase) => 1 << 16,
84 Some(BenchmarkCase::WorstCase) => u32::MAX,
85 None => StdRng::from_seed(seed).random(),
86 }
87 }
88
89 fn corner_case_args(&self) -> Vec<Self::Args> {
90 (0..32).chain(u32::MAX - 32..=u32::MAX).collect_vec()
91 }
92 }
93
94 #[macro_rules_attr::apply(test)]
95 fn rust_shadow() {
96 ShadowedClosure::new(IsOdd).test();
97 }
98}
99
100#[cfg(test)]
101mod benches {
102 use super::*;
103 use crate::test_prelude::*;
104
105 #[macro_rules_attr::apply(test)]
106 fn benchmark() {
107 ShadowedClosure::new(IsOdd).bench();
108 }
109}