tasm_lib/arithmetic/u32/
is_u32.rs1use std::collections::HashMap;
2use triton_vm::prelude::*;
3
4use crate::prelude::*;
5use crate::traits::basic_snippet::{Reviewer, SignOffFingerprint};
6
7#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
24pub struct IsU32;
25
26impl BasicSnippet for IsU32 {
27 fn inputs(&self) -> Vec<(DataType, String)> {
28 vec![(DataType::U32, "value".to_string())]
29 }
30
31 fn outputs(&self) -> Vec<(DataType, String)> {
32 vec![(DataType::Bool, "value < 2^32".to_string())]
33 }
34
35 fn entrypoint(&self) -> String {
36 "tasmlib_arithmetic_u32_is_u32".to_string()
37 }
38
39 fn code(&self, _: &mut Library) -> Vec<LabelledInstruction> {
40 triton_asm!(
41 {self.entrypoint()}:
42 split pop 1 push 0 eq return
48 )
49 }
50
51 fn sign_offs(&self) -> HashMap<Reviewer, SignOffFingerprint> {
52 let mut sign_offs = HashMap::new();
53 sign_offs.insert(Reviewer("ferdinand"), 0x95dae6d2fe11abda.into());
54 sign_offs
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61 use crate::test_prelude::*;
62
63 impl Closure for IsU32 {
64 type Args = BFieldElement;
65
66 fn rust_shadow(&self, stack: &mut Vec<BFieldElement>) {
67 let value = stack.pop().unwrap();
68 let is_u32 = u32::try_from(value).is_ok();
69 push_encodable(stack, &is_u32);
70 }
71
72 fn pseudorandom_args(
73 &self,
74 seed: [u8; 32],
75 bench_case: Option<BenchmarkCase>,
76 ) -> Self::Args {
77 match bench_case {
78 Some(BenchmarkCase::CommonCase) => bfe!(1 << 16),
79 Some(BenchmarkCase::WorstCase) => bfe!(u32::MAX),
80 None => StdRng::from_seed(seed).random(),
81 }
82 }
83
84 fn corner_case_args(&self) -> Vec<Self::Args> {
85 bfe_vec![0, u32::MAX, u64::from(u32::MAX) + 1, BFieldElement::MAX]
86 }
87 }
88
89 #[test]
90 fn rust_shadow() {
91 ShadowedClosure::new(IsU32).test();
92 }
93}
94
95#[cfg(test)]
96mod benches {
97 use super::*;
98 use crate::test_prelude::*;
99
100 #[test]
101 fn is_u32_benchmark() {
102 ShadowedClosure::new(IsU32).bench();
103 }
104}