1use core::iter::{Product, Sum};
2use core::ops::{
3 Add, AddAssign, Deref, DerefMut, Mul, MulAssign, Neg, ShlAssign, ShrAssign, Sub, SubAssign,
4};
5
6use primeorder::elliptic_curve::ops::Invert;
7use subtle::{ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, CtOption};
8
9use crate::bigint::{Encoding, Uint, U256};
10use crate::elliptic_curve::{
11 self,
12 scalar::{FromUintUnchecked, IsHigh, ScalarPrimitive},
13 Field, PrimeField,
14};
15use crate::generic_array::GenericArray;
16use crate::typenum;
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
23pub struct W<F>(F);
24
25impl<F> W<F> {
26 pub const fn new(n: F) -> Self {
28 Self(n)
29 }
30}
31
32impl<F> Deref for W<F> {
33 type Target = F;
34 fn deref(&self) -> &Self::Target {
35 &self.0
36 }
37}
38
39impl<F> DerefMut for W<F> {
40 fn deref_mut(&mut self) -> &mut Self::Target {
41 &mut self.0
42 }
43}
44
45impl<F: PrimeField> W<F> {
46 pub fn to_be_bytes(&self) -> F::Repr {
48 self.0.to_repr()
49 }
50
51 pub fn to_le_bytes(&self) -> F::Repr {
53 let mut bytes = self.to_be_bytes();
54 bytes.as_mut().reverse();
55 bytes
56 }
57
58 pub fn from_be_bytes(bytes: F::Repr) -> CtOption<Self> {
62 F::from_repr(bytes).map(Self)
63 }
64
65 pub fn from_le_bytes(mut bytes: F::Repr) -> CtOption<Self> {
69 bytes.as_mut().reverse();
70 Self::from_be_bytes(bytes)
71 }
72
73 pub fn from_be_bytes_mod_order(bytes: &[u8]) -> Self {
77 Self(
78 bytes
79 .iter()
80 .fold(F::ZERO, |s, b| s * F::from(256) + F::from(u64::from(*b))),
81 )
82 }
83
84 pub fn from_le_bytes_mod_order(bytes: &[u8]) -> Self {
88 Self(
89 bytes
90 .iter()
91 .rev()
92 .fold(F::ZERO, |s, b| s * F::from(256) + F::from(u64::from(*b))),
93 )
94 }
95
96 pub fn from_uint_mod_order(uint: &U256) -> Self {
100 Self::from_be_bytes_mod_order(&uint.to_be_bytes())
101 }
102}
103
104impl<F: PrimeField> W<F>
105where
106 [u8; 32]: From<F::Repr>,
107{
108 pub fn to_uint(&self) -> U256 {
110 U256::from_be_bytes(self.to_be_bytes().into())
111 }
112}
113
114impl<F> AsRef<W<F>> for W<F> {
115 fn as_ref(&self) -> &W<F> {
116 self
117 }
118}
119
120impl<F: From<u64>> From<u64> for W<F> {
121 fn from(n: u64) -> Self {
122 Self(F::from(n))
123 }
124}
125
126impl<F: PrimeField, const LIMBS: usize> From<W<F>> for Uint<LIMBS>
127where
128 Uint<LIMBS>: Encoding,
129 <Uint<LIMBS> as Encoding>::Repr: From<F::Repr>,
130{
131 fn from(s: W<F>) -> Self {
132 Uint::from_be_bytes(s.to_be_bytes().into())
133 }
134}
135
136impl<F: PrimeField> FromUintUnchecked for W<F> {
137 type Uint = U256;
138
139 fn from_uint_unchecked(uint: Self::Uint) -> Self {
140 let bytes_be = uint.to_be_bytes();
141 Self::from_be_bytes_mod_order(&bytes_be)
142 }
143}
144
145impl<F: ConditionallySelectable> ConditionallySelectable for W<F> {
146 fn conditional_select(a: &Self, b: &Self, choice: subtle::Choice) -> Self {
147 Self(F::conditional_select(&a.0, &b.0, choice))
148 }
149}
150
151impl<F: ConstantTimeEq> ConstantTimeEq for W<F> {
152 fn ct_eq(&self, other: &Self) -> subtle::Choice {
153 self.0.ct_eq(&other.0)
154 }
155}
156
157impl<F: Sum> Sum for W<F> {
158 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
159 Self(iter.map(|f| f.0).sum())
160 }
161}
162
163impl<'f, F: Sum<&'f F>> Sum<&'f W<F>> for W<F> {
164 fn sum<I: Iterator<Item = &'f W<F>>>(iter: I) -> Self {
165 Self(iter.map(|f| &f.0).sum())
166 }
167}
168
169impl<F: Product> Product for W<F> {
170 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
171 Self(iter.map(|f| f.0).product())
172 }
173}
174
175impl<'f, F: Product<&'f F>> Product<&'f W<F>> for W<F> {
176 fn product<I: Iterator<Item = &'f W<F>>>(iter: I) -> Self {
177 Self(iter.map(|f| &f.0).product())
178 }
179}
180
181impl<F: Add<Output = F>> Add for W<F> {
182 type Output = Self;
183
184 fn add(self, rhs: Self) -> Self::Output {
185 Self(self.0 + rhs.0)
186 }
187}
188
189impl<F: Sub<Output = F>> Sub for W<F> {
190 type Output = W<F>;
191
192 fn sub(self, rhs: Self) -> Self::Output {
193 Self(self.0 - rhs.0)
194 }
195}
196
197impl<F: Mul<Output = F>> Mul for W<F> {
198 type Output = W<F>;
199
200 fn mul(self, rhs: Self) -> Self::Output {
201 Self(self.0 * rhs.0)
202 }
203}
204
205impl<F: Neg<Output = F>> Neg for W<F> {
206 type Output = W<F>;
207
208 fn neg(self) -> Self::Output {
209 Self(-self.0)
210 }
211}
212
213impl<'r, F: Add<&'r F, Output = F>> Add<&'r W<F>> for W<F> {
214 type Output = W<F>;
215
216 fn add(self, rhs: &'r W<F>) -> Self::Output {
217 Self(self.0 + &rhs.0)
218 }
219}
220
221impl<'r, F: Mul<&'r F, Output = F>> Mul<&'r W<F>> for W<F> {
222 type Output = W<F>;
223
224 fn mul(self, rhs: &'r W<F>) -> Self::Output {
225 Self(self.0 * &rhs.0)
226 }
227}
228
229impl<'r, F: Sub<&'r F, Output = F>> Sub<&'r W<F>> for W<F> {
230 type Output = W<F>;
231
232 fn sub(self, rhs: &'r W<F>) -> Self::Output {
233 Self(self.0 - &rhs.0)
234 }
235}
236
237impl<F: MulAssign> MulAssign for W<F> {
238 fn mul_assign(&mut self, rhs: Self) {
239 self.0 *= rhs.0
240 }
241}
242
243impl<F: AddAssign> AddAssign for W<F> {
244 fn add_assign(&mut self, rhs: Self) {
245 self.0 += rhs.0
246 }
247}
248
249impl<F: SubAssign> SubAssign for W<F> {
250 fn sub_assign(&mut self, rhs: Self) {
251 self.0 -= rhs.0
252 }
253}
254
255impl<'r, F: MulAssign<&'r F>> MulAssign<&'r W<F>> for W<F> {
256 fn mul_assign(&mut self, rhs: &'r W<F>) {
257 self.0 *= &rhs.0
258 }
259}
260
261impl<'r, F: AddAssign<&'r F>> AddAssign<&'r W<F>> for W<F> {
262 fn add_assign(&mut self, rhs: &'r W<F>) {
263 self.0 += &rhs.0
264 }
265}
266
267impl<'r, F: SubAssign<&'r F>> SubAssign<&'r W<F>> for W<F> {
268 fn sub_assign(&mut self, rhs: &'r W<F>) {
269 self.0 -= &rhs.0
270 }
271}
272
273impl<F: ShlAssign<usize>> ShlAssign<usize> for W<F> {
274 fn shl_assign(&mut self, rhs: usize) {
275 self.0 <<= rhs
276 }
277}
278
279impl<F> ShrAssign<usize> for W<F>
280where
281 [u8; 32]: From<F::Repr>,
282 F: PrimeField,
283{
284 fn shr_assign(&mut self, rhs: usize) {
285 let n = self.to_uint();
286 *self = Self::from_uint_mod_order(&(n >> rhs))
287 }
288}
289
290impl<F: Field> Invert for W<F> {
291 type Output = CtOption<Self>;
292
293 fn invert(&self) -> Self::Output {
294 self.0.invert().map(Self)
295 }
296}
297
298impl<F> elliptic_curve::ops::Reduce<U256> for W<F>
299where
300 F: PrimeField,
301 W<F>: PrimeField,
302{
303 type Bytes = <W<F> as PrimeField>::Repr;
304
305 fn reduce(n: U256) -> Self {
306 Self::from_be_bytes_mod_order(&n.to_be_bytes())
307 }
308
309 fn reduce_bytes(bytes: &Self::Bytes) -> Self {
310 Self::from_be_bytes_mod_order(bytes.as_ref())
311 }
312}
313
314impl<F: Field> Field for W<F> {
315 const ZERO: Self = W(F::ZERO);
316 const ONE: Self = W(F::ONE);
317
318 fn random(rng: impl crate::rand_core::RngCore) -> Self {
319 Self(F::random(rng))
320 }
321
322 fn square(&self) -> Self {
323 Self(self.0.square())
324 }
325
326 fn double(&self) -> Self {
327 Self(self.0.double())
328 }
329
330 fn invert(&self) -> CtOption<Self> {
331 self.0.invert().map(Self)
332 }
333
334 fn sqrt(&self) -> CtOption<Self> {
335 self.0.sqrt().map(Self)
336 }
337
338 fn sqrt_ratio(num: &Self, div: &Self) -> (subtle::Choice, Self) {
339 let (choice, res) = F::sqrt_ratio(num, div);
340 (choice, Self(res))
341 }
342}
343
344impl<F> PrimeField for W<F>
345where
346 F: PrimeField,
347 F::Repr: From<GenericArray<u8, typenum::U32>>,
348 GenericArray<u8, typenum::U32>: From<F::Repr>,
349{
350 type Repr = GenericArray<u8, typenum::U32>;
351
352 const MODULUS: &'static str = F::MODULUS;
353 const NUM_BITS: u32 = F::NUM_BITS;
354 const CAPACITY: u32 = F::CAPACITY;
355 const TWO_INV: Self = Self(F::TWO_INV);
356 const MULTIPLICATIVE_GENERATOR: Self = Self(F::MULTIPLICATIVE_GENERATOR);
357 const S: u32 = F::S;
358 const ROOT_OF_UNITY: Self = Self(F::ROOT_OF_UNITY);
359 const ROOT_OF_UNITY_INV: Self = Self(F::ROOT_OF_UNITY_INV);
360 const DELTA: Self = Self(F::DELTA);
361
362 fn from_repr(repr: Self::Repr) -> CtOption<Self> {
363 F::from_repr(repr.into()).map(Self)
364 }
365
366 fn to_repr(&self) -> Self::Repr {
367 self.0.to_repr().into()
368 }
369
370 fn is_odd(&self) -> subtle::Choice {
371 self.0.is_odd()
372 }
373}
374
375impl<F: Default + Copy> zeroize::DefaultIsZeroes for W<F> {}
376
377impl<F: PrimeField, C: elliptic_curve::Curve> From<ScalarPrimitive<C>> for W<F> {
378 fn from(s: ScalarPrimitive<C>) -> Self {
379 let bytes_be = s.as_uint().to_be_bytes();
380 Self::from_be_bytes_mod_order(bytes_be.as_ref())
381 }
382}
383
384impl<F> From<W<F>> for GenericArray<u8, typenum::U32>
385where
386 W<F>: PrimeField<Repr = GenericArray<u8, typenum::U32>>,
387{
388 fn from(s: W<F>) -> Self {
389 s.to_repr()
390 }
391}
392
393impl<F> IsHigh for W<F>
394where
395 F: PrimeField,
396 W<F>: Sub<Output = W<F>>,
397 U256: From<W<F>>,
398{
399 fn is_high(&self) -> subtle::Choice {
400 let n = Self::ZERO - Self::ONE;
401 let n_2 = U256::from(n) >> 1;
402
403 let s = U256::from(*self);
404
405 s.ct_gt(&n_2)
406 }
407}