openvm_bigint_guest/
utils.rs
1#[cfg(not(target_os = "zkvm"))]
2use num_bigint::BigInt;
3
4#[inline]
5#[cfg(not(target_os = "zkvm"))]
6#[allow(dead_code)]
7pub(super) fn bigint_to_limbs<const NUM_LIMBS: usize>(x: &BigInt) -> [u8; NUM_LIMBS] {
9 let mut sm = x.to_signed_bytes_le();
10 let mut ext = 0;
11 if let Some(last) = sm.last() {
12 if (*last as i8) < 0 {
13 ext = u8::MAX;
14 }
15 }
16 sm.resize(NUM_LIMBS, ext);
17 sm.try_into().unwrap()
18}
19
20#[macro_export]
34macro_rules! impl_bin_op {
35 ($struct_name:ty, $trait_name:ident,
36 $trait_assign_name:ident, $trait_fn:ident,
37 $trait_assign_fn:ident, $opcode:expr,
38 $func3:expr, $func7:expr, $op_sym:tt,
39 $rust_expr:expr) => {
40 impl<'a> $trait_assign_name<&'a $struct_name> for $struct_name {
41 #[inline(always)]
42 fn $trait_assign_fn(&mut self, rhs: &'a $struct_name) {
43 #[cfg(target_os = "zkvm")]
44 custom_insn_r!(
45 opcode = $opcode,
46 funct3 = $func3,
47 funct7 = $func7,
48 rd = In self as *mut Self,
49 rs1 = In self as *const Self,
50 rs2 = In rhs as *const Self
51 );
52 #[cfg(not(target_os = "zkvm"))]
53 {
54 *self = $rust_expr(self, rhs);
55 }
56 }
57 }
58
59 impl $trait_assign_name<$struct_name> for $struct_name {
60 #[inline(always)]
61 fn $trait_assign_fn(&mut self, rhs: $struct_name) {
62 *self $op_sym &rhs;
63 }
64 }
65
66 impl<'a> $trait_name<&'a $struct_name> for &$struct_name {
67 type Output = $struct_name;
68 #[inline(always)]
69 fn $trait_fn(self, rhs: &'a $struct_name) -> Self::Output {
70 #[cfg(target_os = "zkvm")]
71 {
72 let mut uninit: MaybeUninit<$struct_name> = MaybeUninit::uninit();
73 custom_insn_r!(
74 opcode = $opcode,
75 funct3 = $func3,
76 funct7 = $func7,
77 rd = In uninit.as_mut_ptr(),
78 rs1 = In self as *const $struct_name,
79 rs2 = In rhs as *const $struct_name
80 );
81 unsafe { uninit.assume_init() }
82 }
83 #[cfg(not(target_os = "zkvm"))]
84 return $rust_expr(self, rhs);
85 }
86 }
87
88 impl<'a> $trait_name<&'a $struct_name> for $struct_name {
89 type Output = $struct_name;
90 #[inline(always)]
91 fn $trait_fn(mut self, rhs: &'a $struct_name) -> Self::Output {
92 self $op_sym rhs;
93 self
94 }
95 }
96
97 impl $trait_name<$struct_name> for $struct_name {
98 type Output = $struct_name;
99 #[inline(always)]
100 fn $trait_fn(mut self, rhs: $struct_name) -> Self::Output {
101 self $op_sym &rhs;
102 self
103 }
104 }
105
106 impl $trait_name<$struct_name> for &$struct_name {
107 type Output = $struct_name;
108 #[inline(always)]
109 fn $trait_fn(self, mut rhs: $struct_name) -> Self::Output {
110 rhs $op_sym self;
111 rhs
112 }
113 }
114 };
115}