tasm_lib/arithmetic/u64/
wrapping_mul.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)]
10pub struct WrappingMul;
11
12impl BasicSnippet for WrappingMul {
13 fn inputs(&self) -> Vec<(DataType, String)> {
14 ["rhs", "lhs"]
15 .map(|side| (DataType::U64, side.to_string()))
16 .to_vec()
17 }
18
19 fn outputs(&self) -> Vec<(DataType, String)> {
20 vec![(DataType::U64, "product".to_string())]
21 }
22
23 fn entrypoint(&self) -> String {
24 "tasmlib_arithmetic_u64_wrapping_mul".to_string()
25 }
26
27 fn code(&self, _: &mut Library) -> Vec<LabelledInstruction> {
28 triton_asm!(
29 {self.entrypoint()}:
32 dup 0
34 dup 3
35 mul
36 swap 4
40 mul
41 swap 2
45 mul
46 split
51 pick 1
52 pop 1
53 pick 1
56 split
57 pick 1
58 pop 1
59 pick 2
62 split
63 place 3
67 add
68 add
69 split
72 pick 1
73 pop 1
74 place 1
78 return
79 )
80 }
81
82 fn sign_offs(&self) -> HashMap<Reviewer, SignOffFingerprint> {
83 let mut sign_offs = HashMap::new();
84 sign_offs.insert(Reviewer("ferdinand"), 0x98526c7c401009ed.into());
85 sign_offs
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92 use crate::test_prelude::*;
93
94 impl Closure for WrappingMul {
95 type Args = (u64, u64);
96
97 fn rust_shadow(&self, stack: &mut Vec<BFieldElement>) {
98 let (right, left) = pop_encodable::<Self::Args>(stack);
99 push_encodable(stack, &left.wrapping_mul(right));
100 }
101
102 fn pseudorandom_args(
103 &self,
104 seed: [u8; 32],
105 bench_case: Option<BenchmarkCase>,
106 ) -> Self::Args {
107 match bench_case {
108 Some(BenchmarkCase::CommonCase) => (1 << 31, (1 << 25) - 1),
109 Some(BenchmarkCase::WorstCase) => (1 << 53, (1 << 33) - 1),
110 None => StdRng::from_seed(seed).random(),
111 }
112 }
113 }
114
115 #[test]
116 fn rust_shadow() {
117 ShadowedClosure::new(WrappingMul).test();
118 }
119}
120
121#[cfg(test)]
122mod benches {
123 use super::*;
124 use crate::test_prelude::*;
125
126 #[test]
127 fn benchmark() {
128 ShadowedClosure::new(WrappingMul).bench();
129 }
130}