vsss_rs/element/
prime_field.rs1use 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
16pub type ValuePrimeField<F> = IdentifierPrimeField<F>;
18
19#[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 pub const ZERO: Self = Self(F::ZERO);
261 pub const ONE: Self = Self(F::ONE);
263}