vsss_rs/element/
primitive.rs

1use core::{
2    fmt::{self, Display, Formatter},
3    ops::{Deref, DerefMut},
4};
5use rand_core::{CryptoRng, RngCore};
6use subtle::Choice;
7#[cfg(feature = "zeroize")]
8use zeroize::*;
9
10use super::*;
11use crate::*;
12
13/// A share identifier represented as u8
14pub type IdentifierU8 = IdentifierPrimitive<u8, 1>;
15/// A share value represented as u8
16pub type ValueU8 = IdentifierU8;
17/// A share identifier represented as u16
18pub type IdentifierU16 = IdentifierPrimitive<u16, 2>;
19/// A share value represented as u16
20pub type ValueU16 = IdentifierU16;
21/// A share identifier represented as u32
22pub type IdentifierU32 = IdentifierPrimitive<u32, 4>;
23/// A share value represented as u32
24pub type ValueU32 = IdentifierU32;
25/// A share identifier represented as u64
26pub type IdentifierU64 = IdentifierPrimitive<u64, 8>;
27/// A share value represented as u64
28pub type ValueU64 = IdentifierU64;
29#[cfg(target_pointer_width = "64")]
30/// A share identifier represent as u128
31pub type IdentifierU128 = IdentifierPrimitive<u128, 16>;
32#[cfg(target_pointer_width = "64")]
33/// A share value represent as u128
34pub type ValueU128 = IdentifierU128;
35/// A share identifier represented as usize
36pub type IdentifierUsize = IdentifierPrimitive<usize, USIZE_BYTES>;
37/// A share value represented as usize
38pub type ValueUsize = IdentifierUsize;
39/// A share identifier represented as i8
40pub type IdentifierI8 = IdentifierPrimitive<i8, 1>;
41/// A share value represented as i8
42pub type ValueI8 = IdentifierI8;
43/// A share identifier represented as i16
44pub type IdentifierI16 = IdentifierPrimitive<i16, 2>;
45/// A share identifier represented as i16
46pub type ValueI16 = IdentifierI16;
47/// A share identifier represented as i32
48pub type IdentifierI32 = IdentifierPrimitive<i32, 4>;
49/// A share value represented as i32
50pub type ValueI32 = IdentifierI32;
51/// A share identifier represented as i64
52pub type IdentifierI64 = IdentifierPrimitive<i64, 8>;
53/// A share value represented as i64
54pub type ValueI64 = IdentifierI64;
55#[cfg(target_pointer_width = "64")]
56/// A share identifier represented as i128
57pub type IdentifierI128 = IdentifierPrimitive<i128, 16>;
58#[cfg(target_pointer_width = "64")]
59/// A share value represented as i128
60pub type ValueI128 = IdentifierI128;
61/// A share identifier represented as isize
62pub type IdentifierIsize = IdentifierPrimitive<isize, ISIZE_BYTES>;
63/// A share value represented as isize
64pub type ValueIsize = IdentifierIsize;
65
66/// A share identifier represented as a primitive integer.
67#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
68#[repr(transparent)]
69pub struct IdentifierPrimitive<P: Primitive<BYTES>, const BYTES: usize>(pub P);
70
71impl<P: Primitive<BYTES>, const BYTES: usize> Display for IdentifierPrimitive<P, BYTES> {
72    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
73        for b in &self.0.to_fixed_array() {
74            write!(f, "{:02x}", b)?;
75        }
76        Ok(())
77    }
78}
79
80impl<P: Primitive<BYTES>, const BYTES: usize> Deref for IdentifierPrimitive<P, BYTES> {
81    type Target = P;
82
83    fn deref(&self) -> &Self::Target {
84        &self.0
85    }
86}
87
88impl<P: Primitive<BYTES>, const BYTES: usize> DerefMut for IdentifierPrimitive<P, BYTES> {
89    fn deref_mut(&mut self) -> &mut Self::Target {
90        &mut self.0
91    }
92}
93
94impl<P: Primitive<BYTES>, const BYTES: usize> AsRef<P> for IdentifierPrimitive<P, BYTES> {
95    fn as_ref(&self) -> &P {
96        &self.0
97    }
98}
99
100impl<P: Primitive<BYTES>, const BYTES: usize> AsMut<P> for IdentifierPrimitive<P, BYTES> {
101    fn as_mut(&mut self) -> &mut P {
102        &mut self.0
103    }
104}
105
106impl<P: Primitive<BYTES>, const BYTES: usize> From<P> for IdentifierPrimitive<P, BYTES> {
107    fn from(value: P) -> Self {
108        Self(value)
109    }
110}
111
112#[cfg(feature = "zeroize")]
113impl<P: Primitive<BYTES>, const BYTES: usize> DefaultIsZeroes for IdentifierPrimitive<P, BYTES> {}
114
115impl<P: Primitive<BYTES>, const BYTES: usize> ShareElement for IdentifierPrimitive<P, BYTES> {
116    type Serialization = [u8; BYTES];
117    type Inner = P;
118
119    fn random(mut rng: impl RngCore + CryptoRng) -> Self {
120        let mut repr = [0u8; BYTES];
121        rng.fill_bytes(repr.as_mut());
122        Self(P::from_fixed_array(&repr))
123    }
124
125    fn zero() -> Self {
126        Self(P::ZERO)
127    }
128
129    fn one() -> Self {
130        Self(P::ONE)
131    }
132
133    fn is_zero(&self) -> Choice {
134        Choice::from(if self.0.is_zero() { 1 } else { 0 })
135    }
136
137    fn serialize(&self) -> Self::Serialization {
138        self.0.to_fixed_array()
139    }
140
141    fn deserialize(serialized: &Self::Serialization) -> VsssResult<Self> {
142        Self::from_slice(&serialized[..])
143    }
144
145    fn from_slice(slice: &[u8]) -> VsssResult<Self> {
146        if slice.len() != BYTES {
147            return Err(Error::InvalidShareElement);
148        }
149        let repr: [u8; BYTES] = slice.try_into().unwrap();
150        Ok(Self(P::from_fixed_array(&repr)))
151    }
152
153    #[cfg(any(feature = "alloc", feature = "std"))]
154    fn to_vec(&self) -> Vec<u8> {
155        self.serialize().to_vec()
156    }
157}
158
159impl<P: Primitive<BYTES>, const BYTES: usize> ShareIdentifier for IdentifierPrimitive<P, BYTES> {
160    fn inc(&mut self, increment: &Self) {
161        self.0 = self.0.saturating_add(increment.0);
162    }
163
164    fn invert(&self) -> VsssResult<Self> {
165        P::ONE
166            .checked_div(&self.0)
167            .map(Self)
168            .ok_or(Error::InvalidShareElement)
169    }
170}
171
172impl<P: Primitive<BYTES>, const BYTES: usize> IdentifierPrimitive<P, BYTES> {
173    /// Returns the additive identity element.
174    pub const ZERO: Self = Self(P::ZERO);
175    /// Returns the multiplicative identity element.
176    pub const ONE: Self = Self(P::ONE);
177}
178
179#[cfg(feature = "serde")]
180macro_rules! impl_serde {
181    ($($identifier:ident => $primitive:ty),+$(,)*) => {
182        $(
183            impl serde::Serialize for $identifier {
184                fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
185                    self.0.serialize(s)
186                }
187            }
188
189            impl<'de> serde::Deserialize<'de> for $identifier {
190                fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
191                    <$primitive>::deserialize(d).map(IdentifierPrimitive)
192                }
193            }
194        )+
195    };
196}
197
198#[cfg(feature = "serde")]
199impl_serde!(
200    IdentifierU8 => u8,
201    IdentifierU16 => u16,
202    IdentifierU32 => u32,
203    IdentifierU64 => u64,
204    IdentifierI8 => i8,
205    IdentifierI16 => i16,
206    IdentifierI32 => i32,
207    IdentifierI64 => i64,
208);
209
210#[cfg(all(feature = "serde", target_pointer_width = "64"))]
211impl_serde!(
212    IdentifierU128 => u128,
213    IdentifierI128 => i128,
214);
215#[cfg(all(feature = "serde", target_pointer_width = "32"))]
216pub use serde_32::*;
217
218#[cfg(all(feature = "serde", target_pointer_width = "64"))]
219mod serde_64 {
220    use super::*;
221    use serde::*;
222
223    impl Serialize for IdentifierUsize {
224        fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
225            (self.0 as u64).serialize(s)
226        }
227    }
228
229    impl<'de> Deserialize<'de> for IdentifierUsize {
230        fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
231            <u64>::deserialize(d).map(|x| IdentifierPrimitive(x as usize))
232        }
233    }
234
235    impl Serialize for IdentifierIsize {
236        fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
237            (self.0 as i64).serialize(s)
238        }
239    }
240
241    impl<'de> Deserialize<'de> for IdentifierIsize {
242        fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
243            <i64>::deserialize(d).map(|x| IdentifierPrimitive(x as isize))
244        }
245    }
246}
247
248#[cfg(all(feature = "serde", target_pointer_width = "32"))]
249mod serde_32 {
250    use super::*;
251    use serde::*;
252
253    impl Serialize for IdentifierUsize {
254        fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
255            (self.0 as u32).serialize(s)
256        }
257    }
258
259    impl<'de> Deserialize<'de> for IdentifierUsize {
260        fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
261            <u32>::deserialize(d).map(|x| IdentifierPrimitive(x as usize))
262        }
263    }
264
265    impl Serialize for IdentifierIsize {
266        fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
267            (self.0 as i32).serialize(s)
268        }
269    }
270
271    impl<'de> Deserialize<'de> for IdentifierIsize {
272        fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
273            <i32>::deserialize(d).map(|x| IdentifierPrimitive(x as isize))
274        }
275    }
276}