tasm_lib/arithmetic/u64/
and.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, Copy, Clone, Eq, PartialEq, Hash)]
29pub struct And;
30
31impl BasicSnippet for And {
32 fn inputs(&self) -> Vec<(DataType, String)> {
33 ["rhs", "lhs"]
34 .map(|side| (DataType::U64, side.to_string()))
35 .to_vec()
36 }
37
38 fn outputs(&self) -> Vec<(DataType, String)> {
39 vec![(DataType::U64, "(lhs & rhs)".to_string())]
40 }
41
42 fn entrypoint(&self) -> String {
43 "tasmlib_arithmetic_u64_and".to_string()
44 }
45
46 fn code(&self, _: &mut Library) -> Vec<LabelledInstruction> {
47 triton_asm!(
48 {self.entrypoint()}:
51 pick 2
52 and
53 place 2
56 and
57 pick 1
58 return
62 )
63 }
64
65 fn sign_offs(&self) -> HashMap<Reviewer, SignOffFingerprint> {
66 let mut sign_offs = HashMap::new();
67 sign_offs.insert(Reviewer("ferdinand"), 0xfd2a6e206fb3abab.into());
68 sign_offs
69 }
70}
71
72#[cfg(test)]
73pub(crate) mod tests {
74 use super::*;
75 use crate::test_prelude::*;
76
77 impl Closure for And {
78 type Args = (u64, u64);
79
80 fn rust_shadow(&self, stack: &mut Vec<BFieldElement>) {
81 let (right, left) = pop_encodable::<Self::Args>(stack);
82 push_encodable(stack, &(left & right));
83 }
84
85 fn pseudorandom_args(
86 &self,
87 seed: [u8; 32],
88 bench_case: Option<BenchmarkCase>,
89 ) -> Self::Args {
90 match bench_case {
91 Some(BenchmarkCase::CommonCase) => (u32::MAX.into(), 1 << 10),
92 Some(BenchmarkCase::WorstCase) => (u64::MAX, u64::MAX - 1),
93 None => StdRng::from_seed(seed).random(),
94 }
95 }
96
97 fn corner_case_args(&self) -> Vec<Self::Args> {
98 let edge_points = [1, 1 << 32, u64::MAX - 1]
99 .into_iter()
100 .flat_map(|p| [p - 1, p, p + 1]);
101
102 edge_points.clone().cartesian_product(edge_points).collect()
103 }
104 }
105
106 #[test]
107 fn rust_shadow() {
108 ShadowedClosure::new(And).test();
109 }
110}
111
112#[cfg(test)]
113mod benches {
114 use super::*;
115 use crate::test_prelude::*;
116
117 #[test]
118 fn benchmark() {
119 ShadowedClosure::new(And).bench();
120 }
121}