group_math/
int.rs

1//! Group of an integer which defines addition as integer (wrapping) addition
2//!
3//! - Associative operation: Integer wrapping addition, `$(a + b) \mod 2^N$`
4//! - Identity element: 0
5//! - Inverse element: `-x`
6
7use std::mem::size_of;
8use std::ops::{Add, AddAssign};
9
10use crate::Group;
11
12macro_rules! decl_int_group {
13    ($t:ty, $t_impl:ident) => {
14        /// See [`self`]
15        #[derive(Debug, Clone, PartialEq, Eq)]
16        pub struct $t_impl(pub $t);
17
18        impl Add for $t_impl {
19            type Output = Self;
20
21            fn add(self, rhs: Self) -> Self::Output {
22                $t_impl(self.0.wrapping_add(rhs.0))
23            }
24        }
25
26        impl AddAssign for $t_impl {
27            fn add_assign(&mut self, rhs: Self) {
28                self.0 = self.0.wrapping_add(rhs.0);
29            }
30        }
31
32        impl<const LAMBDA: usize> Group<LAMBDA> for $t_impl {
33            fn zero() -> Self {
34                $t_impl(0)
35            }
36
37            fn add_inverse(self) -> Self {
38                $t_impl(self.0.wrapping_neg())
39            }
40        }
41
42        impl<const LAMBDA: usize> From<[u8; LAMBDA]> for $t_impl {
43            fn from(value: [u8; LAMBDA]) -> Self {
44                if cfg!(not(feature = "int-be")) {
45                    $t_impl(<$t>::from_le_bytes(
46                        (&value[..size_of::<$t>()]).clone().try_into().unwrap(),
47                    ))
48                } else {
49                    $t_impl(<$t>::from_be_bytes(
50                        (&value[..size_of::<$t>()]).clone().try_into().unwrap(),
51                    ))
52                }
53            }
54        }
55
56        impl<const LAMBDA: usize> From<$t_impl> for [u8; LAMBDA] {
57            fn from(value: $t_impl) -> Self {
58                let mut bs = [0; LAMBDA];
59                if cfg!(not(feature = "int-be")) {
60                    bs[..size_of::<$t>()].copy_from_slice(&value.0.to_le_bytes());
61                } else {
62                    bs[..size_of::<$t>()].copy_from_slice(&value.0.to_be_bytes());
63                }
64                bs
65            }
66        }
67    };
68}
69
70decl_int_group!(u8, U8Group);
71decl_int_group!(u16, U16Group);
72decl_int_group!(u32, U32Group);
73decl_int_group!(u64, U64Group);
74decl_int_group!(u128, U128Group);
75decl_int_group!(usize, UsizeGroup);
76
77decl_int_group!(i8, I8Group);
78decl_int_group!(i16, I16Group);
79decl_int_group!(i32, I32Group);
80decl_int_group!(i64, I64Group);
81decl_int_group!(i128, I128Group);
82decl_int_group!(isize, IsizeGroup);