1use std::ops::{Add, AddAssign, Neg};
7
8pub mod byte;
9pub mod int;
10pub mod int_prime;
11
12pub trait Group<const BLEN: usize>
19where
20 Self: Add<Output = Self>
21 + AddAssign
22 + Neg<Output = Self>
23 + PartialEq
24 + Eq
25 + Clone
26 + Sync
27 + Send
28 + From<[u8; BLEN]>,
29{
30 fn zero() -> Self;
43
44 fn neg_if(self, t: bool) -> Self {
48 if t {
49 -self
50 } else {
51 self
52 }
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 #[macro_export]
59 macro_rules! test_group_axioms {
60 ($test:ident, $t_impl:ty, $blen:literal) => {
61 #[test]
62 fn $test() {
63 arbtest::arbtest(|u| {
64 let a_bs: [u8; $blen] = u.arbitrary()?;
65 let a: $t_impl = a_bs.into();
66 let b_bs: [u8; $blen] = u.arbitrary()?;
67 let b: $t_impl = b_bs.into();
68 let c_bs: [u8; $blen] = u.arbitrary()?;
69 let c: $t_impl = c_bs.into();
70 let e: $t_impl = crate::group::Group::<$blen>::zero();
71 let a_inv = -a.clone();
72
73 let l = a.clone() + (b.clone() + c.clone());
74 let r = (a.clone() + b.clone()) + c.clone();
75 assert_eq!(l, r, "associativity");
76
77 let l0 = a.clone() + e.clone();
78 let r0 = a.clone();
79 assert_eq!(l0, r0, "identity element");
80 let l1 = e.clone() + a.clone();
81 let r1 = a.clone();
82 assert_eq!(l1, r1, "identity element");
83
84 let l0 = a.clone() + a_inv.clone();
85 let r0 = e.clone();
86 assert_eq!(l0, r0, "inverse element");
87 let l1 = a_inv.clone() + a.clone();
88 let r1 = e.clone();
89 assert_eq!(l1, r1, "inverse element");
90
91 Ok(())
92 });
93 }
94 };
95 }
96}