elliptic_curve/
macros.rs
1#[macro_export]
48macro_rules! impl_field_element {
49 (
50 $fe:tt,
51 $bytes:ty,
52 $uint:ty,
53 $modulus:expr,
54 $arr:ty,
55 $from_mont:ident,
56 $to_mont:ident,
57 $add:ident,
58 $sub:ident,
59 $mul:ident,
60 $neg:ident,
61 $square:ident
62 ) => {
63 impl $fe {
64 pub const ZERO: Self = Self(<$uint>::ZERO);
66
67 pub const ONE: Self = Self::from_uint_unchecked(<$uint>::ONE);
69
70 #[doc = stringify!($fe)]
72 pub fn from_be_bytes(repr: $bytes) -> $crate::subtle::CtOption<Self> {
74 use $crate::bigint::ArrayEncoding as _;
75 Self::from_uint(<$uint>::from_be_byte_array(repr))
76 }
77
78 #[doc = stringify!($fe)]
80 pub fn from_be_slice(slice: &[u8]) -> $crate::Result<Self> {
82 <$uint as $crate::bigint::Encoding>::Repr::try_from(slice)
83 .ok()
84 .and_then(|array| Self::from_be_bytes(array.into()).into())
85 .ok_or($crate::Error)
86 }
87
88 #[doc = stringify!($fe)]
90 pub fn from_le_bytes(repr: $bytes) -> $crate::subtle::CtOption<Self> {
92 use $crate::bigint::ArrayEncoding as _;
93 Self::from_uint(<$uint>::from_le_byte_array(repr))
94 }
95
96 #[doc = stringify!($fe)]
98 pub fn from_le_slice(slice: &[u8]) -> $crate::Result<Self> {
100 <$uint as $crate::bigint::Encoding>::Repr::try_from(slice)
101 .ok()
102 .and_then(|array| Self::from_le_bytes(array.into()).into())
103 .ok_or($crate::Error)
104 }
105
106 #[doc = stringify!($fe)]
108 #[doc = stringify!($uint)]
111 pub fn from_uint(uint: $uint) -> $crate::subtle::CtOption<Self> {
117 use $crate::subtle::ConstantTimeLess as _;
118 let is_some = uint.ct_lt(&$modulus);
119 $crate::subtle::CtOption::new(Self::from_uint_unchecked(uint), is_some)
120 }
121
122 #[doc = stringify!($fe)]
124 #[allow(dead_code)]
130 pub(crate) const fn from_be_hex(hex: &str) -> Self {
131 Self::from_uint_unchecked(<$uint>::from_be_hex(hex))
132 }
133
134 #[doc = stringify!($fe)]
136 #[allow(dead_code)]
142 pub(crate) const fn from_le_hex(hex: &str) -> Self {
143 Self::from_uint_unchecked(<$uint>::from_le_hex(hex))
144 }
145
146 #[doc = stringify!($fe)]
148 #[doc = stringify!($uint)]
150 pub(crate) const fn from_uint_unchecked(w: $uint) -> Self {
156 Self(<$uint>::from_words($to_mont(w.as_words())))
157 }
158
159 #[doc = stringify!($fe)]
161 pub fn to_be_bytes(self) -> $bytes {
163 use $crate::bigint::ArrayEncoding as _;
164 self.to_canonical().to_be_byte_array()
165 }
166
167 #[doc = stringify!($fe)]
169 pub fn to_le_bytes(self) -> $bytes {
171 use $crate::bigint::ArrayEncoding as _;
172 self.to_canonical().to_le_byte_array()
173 }
174
175 #[doc = stringify!($fe)]
177 #[doc = stringify!($uint)]
179 #[inline]
181 pub const fn to_canonical(self) -> $uint {
182 <$uint>::from_words($from_mont(self.0.as_words()))
183 }
184
185 #[doc = stringify!($fe)]
187 pub fn is_odd(&self) -> Choice {
193 use $crate::bigint::Integer;
194 self.to_canonical().is_odd()
195 }
196
197 #[doc = stringify!($fe)]
199 pub fn is_even(&self) -> Choice {
205 !self.is_odd()
206 }
207
208 #[doc = stringify!($fe)]
210 pub fn is_zero(&self) -> Choice {
216 self.ct_eq(&Self::ZERO)
217 }
218
219 pub const fn add(&self, rhs: &Self) -> Self {
221 Self(<$uint>::from_words($add(
222 self.0.as_words(),
223 rhs.0.as_words(),
224 )))
225 }
226
227 #[must_use]
229 pub const fn double(&self) -> Self {
230 self.add(self)
231 }
232
233 pub const fn sub(&self, rhs: &Self) -> Self {
235 Self(<$uint>::from_words($sub(
236 self.0.as_words(),
237 rhs.0.as_words(),
238 )))
239 }
240
241 pub const fn mul(&self, rhs: &Self) -> Self {
243 Self(<$uint>::from_words($mul(
244 self.0.as_words(),
245 rhs.0.as_words(),
246 )))
247 }
248
249 pub const fn neg(&self) -> Self {
251 Self(<$uint>::from_words($neg(self.0.as_words())))
252 }
253
254 #[must_use]
256 pub const fn square(&self) -> Self {
257 Self(<$uint>::from_words($square(self.0.as_words())))
258 }
259 }
260
261 impl AsRef<$arr> for $fe {
262 fn as_ref(&self) -> &$arr {
263 self.0.as_ref()
264 }
265 }
266
267 impl Default for $fe {
268 fn default() -> Self {
269 Self::ZERO
270 }
271 }
272
273 impl Eq for $fe {}
274
275 impl PartialEq for $fe {
276 fn eq(&self, rhs: &Self) -> bool {
277 self.0.ct_eq(&(rhs.0)).into()
278 }
279 }
280
281 impl $crate::subtle::ConditionallySelectable for $fe {
282 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
283 Self(<$uint>::conditional_select(&a.0, &b.0, choice))
284 }
285 }
286
287 impl $crate::subtle::ConstantTimeEq for $fe {
288 fn ct_eq(&self, other: &Self) -> $crate::subtle::Choice {
289 self.0.ct_eq(&other.0)
290 }
291 }
292
293 impl $crate::subtle::ConstantTimeGreater for $fe {
294 fn ct_gt(&self, other: &Self) -> $crate::subtle::Choice {
295 self.0.ct_gt(&other.0)
296 }
297 }
298
299 impl $crate::subtle::ConstantTimeLess for $fe {
300 fn ct_lt(&self, other: &Self) -> $crate::subtle::Choice {
301 self.0.ct_lt(&other.0)
302 }
303 }
304
305 impl $crate::zeroize::DefaultIsZeroes for $fe {}
306
307 impl $crate::ff::Field for $fe {
308 fn random(mut rng: impl $crate::rand_core::RngCore) -> Self {
309 let mut bytes = <$bytes>::default();
311
312 loop {
313 rng.fill_bytes(&mut bytes);
314 if let Some(fe) = Self::from_be_bytes(bytes).into() {
315 return fe;
316 }
317 }
318 }
319
320 fn zero() -> Self {
321 Self::ZERO
322 }
323
324 fn one() -> Self {
325 Self::ONE
326 }
327
328 fn is_zero(&self) -> Choice {
329 Self::ZERO.ct_eq(self)
330 }
331
332 #[must_use]
333 fn square(&self) -> Self {
334 self.square()
335 }
336
337 #[must_use]
338 fn double(&self) -> Self {
339 self.double()
340 }
341
342 fn invert(&self) -> CtOption<Self> {
343 self.invert()
344 }
345
346 fn sqrt(&self) -> CtOption<Self> {
347 self.sqrt()
348 }
349 }
350
351 $crate::impl_field_op!($fe, $uint, Add, add, $add);
352 $crate::impl_field_op!($fe, $uint, Sub, sub, $sub);
353 $crate::impl_field_op!($fe, $uint, Mul, mul, $mul);
354
355 impl AddAssign<$fe> for $fe {
356 #[inline]
357 fn add_assign(&mut self, other: $fe) {
358 *self = *self + other;
359 }
360 }
361
362 impl AddAssign<&$fe> for $fe {
363 #[inline]
364 fn add_assign(&mut self, other: &$fe) {
365 *self = *self + other;
366 }
367 }
368
369 impl SubAssign<$fe> for $fe {
370 #[inline]
371 fn sub_assign(&mut self, other: $fe) {
372 *self = *self - other;
373 }
374 }
375
376 impl SubAssign<&$fe> for $fe {
377 #[inline]
378 fn sub_assign(&mut self, other: &$fe) {
379 *self = *self - other;
380 }
381 }
382
383 impl MulAssign<&$fe> for $fe {
384 #[inline]
385 fn mul_assign(&mut self, other: &$fe) {
386 *self = *self * other;
387 }
388 }
389
390 impl MulAssign for $fe {
391 #[inline]
392 fn mul_assign(&mut self, other: $fe) {
393 *self = *self * other;
394 }
395 }
396
397 impl Neg for $fe {
398 type Output = $fe;
399
400 #[inline]
401 fn neg(self) -> $fe {
402 Self($neg(self.as_ref()).into())
403 }
404 }
405 };
406}
407
408#[macro_export]
411macro_rules! impl_field_op {
412 ($fe:tt, $uint:ty, $op:tt, $op_fn:ident, $func:ident) => {
413 impl ::core::ops::$op for $fe {
414 type Output = $fe;
415
416 #[inline]
417 fn $op_fn(self, rhs: $fe) -> $fe {
418 $fe($func(self.as_ref(), rhs.as_ref()).into())
419 }
420 }
421
422 impl ::core::ops::$op<&$fe> for $fe {
423 type Output = $fe;
424
425 #[inline]
426 fn $op_fn(self, rhs: &$fe) -> $fe {
427 $fe($func(self.as_ref(), rhs.as_ref()).into())
428 }
429 }
430
431 impl ::core::ops::$op<&$fe> for &$fe {
432 type Output = $fe;
433
434 #[inline]
435 fn $op_fn(self, rhs: &$fe) -> $fe {
436 $fe($func(self.as_ref(), rhs.as_ref()).into())
437 }
438 }
439 };
440}