vsss_rs/element/
prime_field.rs

1use super::*;
2use crate::*;
3use core::{
4    cmp::Ordering,
5    fmt::{self, Display, Formatter},
6    hash::{Hash, Hasher},
7    ops::{Deref, DerefMut, Mul},
8};
9#[cfg(feature = "bigint")]
10use crypto_bigint::{modular::constant_mod::ResidueParams, ArrayEncoding, Uint};
11#[cfg(feature = "bigint")]
12use elliptic_curve::ops::Reduce;
13
14use elliptic_curve::{scalar::IsHigh, Field, PrimeField};
15
16/// A share value represented as a [`PrimeField`].
17pub type ValuePrimeField<F> = IdentifierPrimeField<F>;
18
19/// A share identifier represented as a prime field element.
20#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22#[repr(transparent)]
23pub struct IdentifierPrimeField<F: PrimeField>(
24    #[cfg_attr(feature = "serde", serde(with = "elliptic_curve_tools::prime_field"))] pub F,
25);
26
27impl<F: PrimeField> Display for IdentifierPrimeField<F> {
28    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
29        for &b in self.0.to_repr().as_ref() {
30            write!(f, "{:02x}", b)?;
31        }
32        Ok(())
33    }
34}
35
36impl<F: PrimeField> Hash for IdentifierPrimeField<F> {
37    fn hash<H: Hasher>(&self, state: &mut H) {
38        self.0.to_repr().as_ref().hash(state);
39    }
40}
41
42#[allow(clippy::non_canonical_partial_ord_impl)]
43impl<F: PrimeField + IsHigh> PartialOrd for IdentifierPrimeField<F> {
44    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
45        match (self.0.is_high().unwrap_u8(), other.0.is_high().unwrap_u8()) {
46            (1, 1) => Some(other.0.to_repr().as_ref().cmp(self.0.to_repr().as_ref())),
47            (0, 0) => Some(self.0.to_repr().as_ref().cmp(other.0.to_repr().as_ref())),
48            (1, 0) => Some(Ordering::Less),
49            (0, 1) => Some(Ordering::Greater),
50            (_, _) => None,
51        }
52    }
53}
54
55impl<F: PrimeField + IsHigh> Ord for IdentifierPrimeField<F> {
56    fn cmp(&self, other: &Self) -> Ordering {
57        self.partial_cmp(other).expect("invalid share identifier")
58    }
59}
60
61impl<F: PrimeField> Deref for IdentifierPrimeField<F> {
62    type Target = F;
63
64    fn deref(&self) -> &Self::Target {
65        &self.0
66    }
67}
68
69impl<F: PrimeField> DerefMut for IdentifierPrimeField<F> {
70    fn deref_mut(&mut self) -> &mut Self::Target {
71        &mut self.0
72    }
73}
74
75impl<F: PrimeField> AsRef<F> for IdentifierPrimeField<F> {
76    fn as_ref(&self) -> &F {
77        &self.0
78    }
79}
80
81impl<F: PrimeField> AsMut<F> for IdentifierPrimeField<F> {
82    fn as_mut(&mut self) -> &mut F {
83        &mut self.0
84    }
85}
86
87impl<F: PrimeField> From<F> for IdentifierPrimeField<F> {
88    fn from(value: F) -> Self {
89        Self(value)
90    }
91}
92
93impl<F: PrimeField> From<&IdentifierPrimeField<F>> for IdentifierPrimeField<F> {
94    fn from(value: &IdentifierPrimeField<F>) -> Self {
95        *value
96    }
97}
98
99#[cfg(feature = "primitive")]
100impl<F: PrimeField, P: Primitive<BYTES>, const BYTES: usize> From<&IdentifierPrimitive<P, BYTES>>
101    for IdentifierPrimeField<F>
102{
103    fn from(value: &IdentifierPrimitive<P, BYTES>) -> Self {
104        #[cfg(target_pointer_width = "64")]
105        {
106            if BYTES * 8 <= 64 {
107                Self(F::from(value.0.to_u64().expect("invalid share identifier")))
108            } else {
109                Self(F::from_u128(
110                    value.0.to_u128().expect("invalid share identifier"),
111                ))
112            }
113        }
114        #[cfg(target_pointer_width = "32")]
115        {
116            Self(F::from(value.0.to_u64().expect("invalid share identifier")))
117        }
118    }
119}
120
121#[cfg(feature = "bigint")]
122impl<F: PrimeField + Reduce<Uint<LIMBS>>, const LIMBS: usize> From<&IdentifierUint<LIMBS>>
123    for IdentifierPrimeField<F>
124where
125    Uint<LIMBS>: ArrayEncoding,
126{
127    fn from(value: &IdentifierUint<LIMBS>) -> Self {
128        if LIMBS * 8 != F::Repr::default().as_ref().len() {
129            panic!("cannot convert from IdentifierUint to IdentifierPrimeField with different limb size");
130        }
131        Self(F::reduce(value.0 .0))
132    }
133}
134
135#[cfg(feature = "bigint")]
136impl<F: PrimeField + Reduce<Uint<LIMBS>>, MOD: ResidueParams<LIMBS>, const LIMBS: usize>
137    From<&IdentifierResidue<MOD, LIMBS>> for IdentifierPrimeField<F>
138where
139    Uint<LIMBS>: ArrayEncoding,
140{
141    fn from(value: &IdentifierResidue<MOD, LIMBS>) -> Self {
142        let t = value.0.retrieve();
143        Self(F::reduce(t))
144    }
145}
146
147impl<F: PrimeField> Mul<&IdentifierPrimeField<F>> for IdentifierPrimeField<F> {
148    type Output = IdentifierPrimeField<F>;
149
150    fn mul(self, rhs: &IdentifierPrimeField<F>) -> Self::Output {
151        Self(self.0 * rhs.0)
152    }
153}
154
155#[cfg(feature = "primitive")]
156impl<F: PrimeField, P: Primitive<BYTES>, const BYTES: usize> Mul<&IdentifierPrimitive<P, BYTES>>
157    for IdentifierPrimeField<F>
158{
159    type Output = IdentifierPrimeField<F>;
160
161    fn mul(self, rhs: &IdentifierPrimitive<P, BYTES>) -> Self::Output {
162        let rhs = IdentifierPrimeField::<F>::from(rhs);
163        Self(self.0 * rhs.0)
164    }
165}
166
167#[cfg(feature = "bigint")]
168impl<F: PrimeField + Reduce<Uint<LIMBS>>, const LIMBS: usize> Mul<&IdentifierUint<LIMBS>>
169    for IdentifierPrimeField<F>
170where
171    Uint<LIMBS>: ArrayEncoding,
172{
173    type Output = IdentifierPrimeField<F>;
174
175    fn mul(self, rhs: &IdentifierUint<LIMBS>) -> Self::Output {
176        let rhs = IdentifierPrimeField::<F>::from(rhs);
177        Self(self.0 * rhs.0)
178    }
179}
180
181#[cfg(feature = "bigint")]
182impl<F: PrimeField + Reduce<Uint<LIMBS>>, MOD: ResidueParams<LIMBS>, const LIMBS: usize>
183    Mul<&IdentifierResidue<MOD, LIMBS>> for IdentifierPrimeField<F>
184where
185    Uint<LIMBS>: ArrayEncoding,
186{
187    type Output = IdentifierPrimeField<F>;
188
189    fn mul(self, rhs: &IdentifierResidue<MOD, LIMBS>) -> Self::Output {
190        let rhs = IdentifierPrimeField::<F>::from(rhs);
191        Self(self.0 * rhs.0)
192    }
193}
194
195#[cfg(feature = "zeroize")]
196impl<F: PrimeField + zeroize::DefaultIsZeroes> zeroize::DefaultIsZeroes
197    for IdentifierPrimeField<F>
198{
199}
200
201impl<F: PrimeField> ShareElement for IdentifierPrimeField<F> {
202    type Serialization = F::Repr;
203    type Inner = F;
204
205    fn random(rng: impl RngCore + CryptoRng) -> Self {
206        Self(F::random(rng))
207    }
208
209    fn zero() -> Self {
210        Self(<F as Field>::ZERO)
211    }
212
213    fn one() -> Self {
214        Self(<F as Field>::ONE)
215    }
216
217    fn is_zero(&self) -> Choice {
218        F::is_zero(self)
219    }
220
221    fn serialize(&self) -> Self::Serialization {
222        self.to_repr()
223    }
224
225    fn deserialize(serialized: &Self::Serialization) -> VsssResult<Self> {
226        Option::from(F::from_repr(*serialized).map(Self)).ok_or(Error::InvalidShareElement)
227    }
228
229    fn from_slice(vec: &[u8]) -> VsssResult<Self> {
230        let mut repr = F::Repr::default();
231        if vec.len() != repr.as_ref().len() {
232            return Err(Error::InvalidShareElement);
233        }
234        repr.as_mut().copy_from_slice(vec);
235        Option::from(F::from_repr(repr))
236            .map(Self)
237            .ok_or(Error::InvalidShareElement)
238    }
239
240    #[cfg(any(feature = "alloc", feature = "std"))]
241    fn to_vec(&self) -> Vec<u8> {
242        self.to_repr().as_ref().to_vec()
243    }
244}
245
246impl<F: PrimeField> ShareIdentifier for IdentifierPrimeField<F> {
247    fn inc(&mut self, increment: &Self) {
248        self.0 += increment.0;
249    }
250
251    fn invert(&self) -> VsssResult<Self> {
252        Option::from(self.0.invert())
253            .map(Self)
254            .ok_or(Error::InvalidShareElement)
255    }
256}
257
258impl<F: PrimeField> IdentifierPrimeField<F> {
259    /// Returns additive identity.
260    pub const ZERO: Self = Self(F::ZERO);
261    /// Returns multiplicative identity.
262    pub const ONE: Self = Self(F::ONE);
263}