tasm_lib/arithmetic/u64/
wrapping_sub.rs1use std::collections::HashMap;
2
3use triton_vm::prelude::*;
4
5use crate::arithmetic::u64::overflowing_sub::OverflowingSub;
6use crate::prelude::*;
7use crate::traits::basic_snippet::Reviewer;
8use crate::traits::basic_snippet::SignOffFingerprint;
9
10#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
31pub struct WrappingSub;
32
33impl BasicSnippet for WrappingSub {
34 fn parameters(&self) -> Vec<(DataType, String)> {
35 OverflowingSub.parameters()
36 }
37
38 fn return_values(&self) -> Vec<(DataType, String)> {
39 vec![(DataType::U64, "wrapped_difference".to_string())]
40 }
41
42 fn entrypoint(&self) -> String {
43 "tasmlib_arithmetic_u64_wrapping_sub".to_string()
44 }
45
46 fn code(&self, _: &mut Library) -> Vec<LabelledInstruction> {
47 triton_asm! {
48 {self.entrypoint()}:
49 {&OverflowingSub::common_subtraction_code()}
50 addi {1_u64 << 32}
53 split
54 place 2
57 pop 1
58 return
61 }
62 }
63
64 fn sign_offs(&self) -> HashMap<Reviewer, SignOffFingerprint> {
65 let mut sign_offs = HashMap::new();
66 sign_offs.insert(Reviewer("ferdinand"), 0xb2c7f4ea33410d67.into());
67 sign_offs
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::test_prelude::*;
75
76 impl Closure for WrappingSub {
77 type Args = <OverflowingSub as Closure>::Args;
78
79 fn rust_shadow(&self, stack: &mut Vec<BFieldElement>) -> Result<(), RustShadowError> {
80 let minuend = pop_encodable::<u64>(stack)?;
81 let subtrahend = pop_encodable::<u64>(stack)?;
82 let difference = minuend.wrapping_sub(subtrahend);
83 push_encodable(stack, &difference);
84 Ok(())
85 }
86
87 fn pseudorandom_args(
88 &self,
89 seed: [u8; 32],
90 bench_case: Option<BenchmarkCase>,
91 ) -> Self::Args {
92 OverflowingSub.pseudorandom_args(seed, bench_case)
93 }
94
95 fn corner_case_args(&self) -> Vec<Self::Args> {
96 OverflowingSub.corner_case_args()
97 }
98 }
99
100 #[macro_rules_attr::apply(test)]
101 fn rust_shadow() {
102 ShadowedClosure::new(WrappingSub).test()
103 }
104}
105
106#[cfg(test)]
107mod benches {
108 use super::*;
109 use crate::test_prelude::*;
110
111 #[macro_rules_attr::apply(test)]
112 fn benchmark() {
113 ShadowedClosure::new(WrappingSub).bench()
114 }
115}