hacspec_lib/
math_integers.rs

1//! # Math Integers
2//!
3//! This module implements a number of different math integers.
4//!
5//! ## Integers
6//!
7//! * Unsigned Integers: `unsigned_integer`, `unsigned_public_integer`
8//! * Signed Integers: `signed_integer`, `signed_public_integer`
9//! * Natural Numbers modulo an integer: `nat_mod`, `public_nat_mod`
10//!
11//! ```
12//! use hacspec_lib::*;
13//! unsigned_integer!(LargeSecretInteger, 233);
14//! let a = LargeSecretInteger::from_literal(1);
15//! let b = LargeSecretInteger::from_literal(2);
16//! let c = a + b;
17//! let result = std::panic::catch_unwind(|| {
18//!     // This panics because comparing secret math integers is currently not support.
19//!     assert!(c.equal(LargeSecretInteger::from_literal(3)));
20//! });
21//! assert!(result.is_err());
22//! let _max = LargeSecretInteger::from_hex("1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
23//! ```
24
25// TODO: Implement Integer for all math integers?
26
27#[macro_export]
28macro_rules! unsigned_public_integer {
29    ($name:ident,$n:literal) => {
30        abstract_unsigned_public_integer!($name, $n);
31
32        impl $name {
33            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
34            pub fn from_byte_seq_be<A: SeqTrait<U8>>(s: &A) -> $name {
35                $name::from_be_bytes(
36                    s.iter()
37                        .map(|x| U8::declassify(*x))
38                        .collect::<Vec<_>>()
39                        .as_slice(),
40                )
41            }
42
43            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
44            pub fn from_public_byte_seq_be<A: SeqTrait<u8>>(s: A) -> $name {
45                // XXX: unnecessarily complex
46                $name::from_be_bytes(s.iter().map(|x| *x).collect::<Vec<_>>().as_slice())
47            }
48
49            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
50            pub fn to_byte_seq_be(self) -> Seq<U8> {
51                Seq::from_vec(
52                    self.to_be_bytes()
53                        .iter()
54                        .map(|x| U8::classify(*x))
55                        .collect::<Vec<U8>>(),
56                )
57            }
58        }
59
60        impl NumericCopy for $name {}
61        impl UnsignedInteger for $name {}
62        impl UnsignedIntegerCopy for $name {}
63        impl Integer for $name {
64            const NUM_BITS: usize = $n;
65
66            #[inline]
67            #[cfg_attr(feature = "use_attributes", in_hacspec)]
68            fn ZERO() -> Self {
69                Self::from_literal(0)
70            }
71            #[inline]
72            #[cfg_attr(feature = "use_attributes", in_hacspec)]
73            fn ONE() -> Self {
74                Self::from_literal(1)
75            }
76            #[inline]
77            #[cfg_attr(feature = "use_attributes", in_hacspec)]
78            fn TWO() -> Self {
79                Self::from_literal(2)
80            }
81
82            #[inline]
83            #[cfg_attr(feature = "use_attributes", in_hacspec)]
84            fn from_literal(val: u128) -> Self {
85                Self::from_literal(val)
86            }
87
88            #[inline]
89            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
90            fn from_hex_string(s: &String) -> Self {
91                Self::from_hex(&s.replace("0x", ""))
92            }
93
94            /// Get bit `i` of this integer.
95            #[inline]
96            #[cfg_attr(feature = "use_attributes", in_hacspec)]
97            fn get_bit(self, i: usize) -> Self {
98                (self >> i) & Self::ONE()
99            }
100
101            /// Set bit `i` of this integer to `b` and return the result.
102            /// Bit `b` has to be `0` or `1`.
103            #[inline]
104            #[cfg_attr(feature = "use_attributes", in_hacspec)]
105            fn set_bit(self, b: Self, i: usize) -> Self {
106                debug_assert!(b.clone().equal(Self::ONE()) || b.clone().equal(Self::ZERO()));
107                let tmp1 = Self::from_literal(!(1 << i));
108                let tmp2 = b << i;
109                (self & tmp1) | tmp2
110            }
111
112            /// Set bit `pos` of this integer to bit `yi` of integer `y`.
113            #[inline]
114            #[cfg_attr(feature = "use_attributes", in_hacspec)]
115            fn set(self, pos: usize, y: Self, yi: usize) -> Self {
116                let b = y.get_bit(yi);
117                self.set_bit(b, pos)
118            }
119
120            #[cfg_attr(feature = "use_attributes", in_hacspec)]
121            fn rotate_left(self, n: usize) -> Self {
122                // Taken from https://blog.regehr.org/archives/1063
123                assert!(n < Self::NUM_BITS);
124                (self.clone() << n) | (self >> ((-(n as i32) as usize) & (Self::NUM_BITS - 1)))
125            }
126
127            #[cfg_attr(feature = "use_attributes", in_hacspec)]
128            fn rotate_right(self, n: usize) -> Self {
129                // Taken from https://blog.regehr.org/archives/1063
130                assert!(n < Self::NUM_BITS);
131                (self.clone() >> n) | (self << ((-(n as i32) as usize) & (Self::NUM_BITS - 1)))
132            }
133        }
134        impl ModNumeric for $name {
135            /// (self - rhs) % n.
136            #[cfg_attr(feature = "use_attributes", in_hacspec)]
137            fn sub_mod(self, rhs: Self, n: Self) -> Self {
138                (self - rhs) % n
139            }
140            /// `(self + rhs) % n`
141            #[cfg_attr(feature = "use_attributes", in_hacspec)]
142            fn add_mod(self, rhs: Self, n: Self) -> Self {
143                (self + rhs) % n
144            }
145            /// `(self * rhs) % n`
146            #[cfg_attr(feature = "use_attributes", in_hacspec)]
147            fn mul_mod(self, rhs: Self, n: Self) -> Self {
148                (self * rhs) % n
149            }
150            /// `(self ^ exp) % n`
151            #[cfg_attr(feature = "use_attributes", in_hacspec)]
152            fn pow_mod(self, exp: Self, n: Self) -> Self {
153                self.pow_felem(exp, n)
154            }
155            /// `self % n`
156            #[cfg_attr(feature = "use_attributes", in_hacspec)]
157            fn modulo(self, n: Self) -> Self {
158                self % n
159            }
160            /// `self % n` that always returns a positive integer
161            #[cfg_attr(feature = "use_attributes", in_hacspec)]
162            fn signed_modulo(self, n: Self) -> Self {
163                self.modulo(n)
164            }
165            /// `|self|`
166            #[cfg_attr(feature = "use_attributes", in_hacspec)]
167            fn absolute(self) -> Self {
168                self
169            }
170        }
171        impl Numeric for $name {
172            /// Return largest value that can be represented.
173            #[cfg_attr(feature = "use_attributes", in_hacspec)]
174            fn max_val() -> Self {
175                $name::max_value()
176            }
177
178            #[cfg_attr(feature = "use_attributes", in_hacspec)]
179            fn wrap_add(self, rhs: Self) -> Self {
180                self + rhs
181            }
182            #[cfg_attr(feature = "use_attributes", in_hacspec)]
183            fn wrap_sub(self, rhs: Self) -> Self {
184                self - rhs
185            }
186            #[cfg_attr(feature = "use_attributes", in_hacspec)]
187            fn wrap_mul(self, rhs: Self) -> Self {
188                self * rhs
189            }
190            #[cfg_attr(feature = "use_attributes", in_hacspec)]
191            fn wrap_div(self, rhs: Self) -> Self {
192                self / rhs
193            }
194
195            /// `self ^ exp` where `exp` is a `u32`.
196            #[cfg_attr(feature = "use_attributes", in_hacspec)]
197            fn exp(self, exp: u32) -> Self {
198                self.pow(exp.into(), Self::max_val())
199            }
200            /// `self ^ exp` where `exp` is a `Self`.
201            #[cfg_attr(feature = "use_attributes", in_hacspec)]
202            fn pow_self(self, exp: Self) -> Self {
203                self.pow_felem(exp.into(), Self::max_val())
204            }
205            /// Division.
206            #[cfg_attr(feature = "use_attributes", in_hacspec)]
207            fn divide(self, rhs: Self) -> Self {
208                self / rhs
209            }
210            /// Invert self modulo n.
211            #[cfg_attr(feature = "use_attributes", in_hacspec)]
212            fn inv(self, n: Self) -> Self {
213                $name::inv(self, n)
214            }
215
216            // Comparison functions returning bool.
217            #[cfg_attr(feature = "use_attributes", in_hacspec)]
218            fn equal(self, other: Self) -> bool {
219                self == other
220            }
221            #[cfg_attr(feature = "use_attributes", in_hacspec)]
222            fn greater_than(self, other: Self) -> bool {
223                self > other
224            }
225            #[cfg_attr(feature = "use_attributes", in_hacspec)]
226            fn greater_than_or_equal(self, other: Self) -> bool {
227                self >= other
228            }
229            #[cfg_attr(feature = "use_attributes", in_hacspec)]
230            fn less_than(self, other: Self) -> bool {
231                self < other
232            }
233            #[cfg_attr(feature = "use_attributes", in_hacspec)]
234            fn less_than_or_equal(self, other: Self) -> bool {
235                self >= other
236            }
237
238            // Comparison functions returning a bit mask (0x0..0 or 0xF..F).
239            #[cfg_attr(feature = "use_attributes", in_hacspec)]
240            fn not_equal_bm(self, other: Self) -> Self {
241                if !self.equal(other) {
242                    Self::max_val()
243                } else {
244                    Self::from_literal(0)
245                }
246            }
247            #[cfg_attr(feature = "use_attributes", in_hacspec)]
248            fn equal_bm(self, other: Self) -> Self {
249                if self.equal(other) {
250                    Self::max_val()
251                } else {
252                    Self::from_literal(0)
253                }
254            }
255            #[cfg_attr(feature = "use_attributes", in_hacspec)]
256            fn greater_than_bm(self, other: Self) -> Self {
257                if self.greater_than(other) {
258                    Self::max_val()
259                } else {
260                    Self::from_literal(0)
261                }
262            }
263            #[cfg_attr(feature = "use_attributes", in_hacspec)]
264            fn greater_than_or_equal_bm(self, other: Self) -> Self {
265                if self.greater_than_or_equal(other) {
266                    Self::max_val()
267                } else {
268                    Self::from_literal(0)
269                }
270            }
271            #[cfg_attr(feature = "use_attributes", in_hacspec)]
272            fn less_than_bm(self, other: Self) -> Self {
273                if self.less_than(other) {
274                    Self::max_val()
275                } else {
276                    Self::from_literal(0)
277                }
278            }
279            #[cfg_attr(feature = "use_attributes", in_hacspec)]
280            fn less_than_or_equal_bm(self, other: Self) -> Self {
281                if self.less_than_or_equal(other) {
282                    Self::max_val()
283                } else {
284                    Self::from_literal(0)
285                }
286            }
287        }
288    };
289}
290
291#[macro_export]
292macro_rules! signed_public_integer {
293    ($name:ident,$n:literal) => {
294        abstract_signed_public_integer!($name, $n);
295
296        impl NumericCopy for $name {}
297        impl ModNumeric for $name {
298            /// (self - rhs) % n.
299            #[cfg_attr(feature = "use_attributes", in_hacspec)]
300            fn sub_mod(self, rhs: Self, n: Self) -> Self {
301                (self - rhs).signed_modulo(n)
302            }
303            /// `(self + rhs) % n`
304            #[cfg_attr(feature = "use_attributes", in_hacspec)]
305            fn add_mod(self, rhs: Self, n: Self) -> Self {
306                (self + rhs).signed_modulo(n)
307            }
308            /// `(self * rhs) % n`
309            #[cfg_attr(feature = "use_attributes", in_hacspec)]
310            fn mul_mod(self, rhs: Self, n: Self) -> Self {
311                (self * rhs).signed_modulo(n)
312            }
313            /// `(self ^ exp) % n`
314            #[cfg_attr(feature = "use_attributes", in_hacspec)]
315            fn pow_mod(self, exp: Self, n: Self) -> Self {
316                self.pow_felem(exp, n).signed_modulo(n)
317            }
318            /// `self % n`
319            #[cfg_attr(feature = "use_attributes", in_hacspec)]
320            fn modulo(self, n: Self) -> Self {
321                self % n
322            }
323            /// `self % n` that always returns a positive integer
324            #[cfg_attr(feature = "use_attributes", in_hacspec)]
325            fn signed_modulo(self, n: Self) -> Self {
326                let mut ret = self.modulo(n);
327                while ret.less_than(Self::default()) {
328                    ret = ret + n;
329                }
330                ret
331            }
332            /// `|self|`
333            /// TODO: implement in abstract-integers
334            #[cfg_attr(feature = "use_attributes", in_hacspec)]
335            fn absolute(self) -> Self {
336                unimplemented!();
337            }
338        }
339        impl Numeric for $name {
340            /// Return largest value that can be represented.
341            #[cfg_attr(feature = "use_attributes", in_hacspec)]
342            fn max_val() -> Self {
343                Self::max_value()
344            }
345
346            #[cfg_attr(feature = "use_attributes", in_hacspec)]
347            fn wrap_add(self, rhs: Self) -> Self {
348                self + rhs
349            }
350            #[cfg_attr(feature = "use_attributes", in_hacspec)]
351            fn wrap_sub(self, rhs: Self) -> Self {
352                self - rhs
353            }
354            #[cfg_attr(feature = "use_attributes", in_hacspec)]
355            fn wrap_mul(self, rhs: Self) -> Self {
356                self * rhs
357            }
358            #[cfg_attr(feature = "use_attributes", in_hacspec)]
359            fn wrap_div(self, rhs: Self) -> Self {
360                self / rhs
361            }
362
363            /// `self ^ exp` where `exp` is a `u32`.
364            #[cfg_attr(feature = "use_attributes", in_hacspec)]
365            fn exp(self, exp: u32) -> Self {
366                self.pow(exp.into(), Self::max_val())
367            }
368            /// `self ^ exp` where `exp` is a `Self`.
369            #[cfg_attr(feature = "use_attributes", in_hacspec)]
370            fn pow_self(self, exp: Self) -> Self {
371                self.pow_felem(exp, Self::max_val())
372            }
373            /// Division.
374            #[cfg_attr(feature = "use_attributes", in_hacspec)]
375            fn divide(self, rhs: Self) -> Self {
376                self / rhs
377            }
378            /// Invert self modulo n.
379            #[cfg_attr(feature = "use_attributes", in_hacspec)]
380            fn inv(self, n: Self) -> Self {
381                $name::inv(self, n)
382            }
383
384            // Comparison functions returning bool.
385            #[cfg_attr(feature = "use_attributes", in_hacspec)]
386            fn equal(self, other: Self) -> bool {
387                self == other
388            }
389            #[cfg_attr(feature = "use_attributes", in_hacspec)]
390            fn greater_than(self, other: Self) -> bool {
391                self > other
392            }
393            #[cfg_attr(feature = "use_attributes", in_hacspec)]
394            fn greater_than_or_equal(self, other: Self) -> bool {
395                self >= other
396            }
397            #[cfg_attr(feature = "use_attributes", in_hacspec)]
398            fn less_than(self, other: Self) -> bool {
399                self < other
400            }
401            #[cfg_attr(feature = "use_attributes", in_hacspec)]
402            fn less_than_or_equal(self, other: Self) -> bool {
403                self <= other
404            }
405
406            // Comparison functions returning a bit mask (0x0..0 or 0xF..F).
407            #[cfg_attr(feature = "use_attributes", in_hacspec)]
408            fn not_equal_bm(self, other: Self) -> Self {
409                if !self.equal(other) {
410                    Self::from_signed_literal(-1)
411                } else {
412                    Self::from_signed_literal(0)
413                }
414            }
415            #[cfg_attr(feature = "use_attributes", in_hacspec)]
416            fn equal_bm(self, other: Self) -> Self {
417                if self.equal(other) {
418                    Self::from_signed_literal(-1)
419                } else {
420                    Self::from_signed_literal(0)
421                }
422            }
423            #[cfg_attr(feature = "use_attributes", in_hacspec)]
424            fn greater_than_bm(self, other: Self) -> Self {
425                if self.greater_than(other) {
426                    Self::from_signed_literal(-1)
427                } else {
428                    Self::from_signed_literal(0)
429                }
430            }
431            #[cfg_attr(feature = "use_attributes", in_hacspec)]
432            fn greater_than_or_equal_bm(self, other: Self) -> Self {
433                if self.greater_than_or_equal(other) {
434                    Self::from_signed_literal(-1)
435                } else {
436                    Self::from_signed_literal(0)
437                }
438            }
439            #[cfg_attr(feature = "use_attributes", in_hacspec)]
440            fn less_than_bm(self, other: Self) -> Self {
441                if self.less_than(other) {
442                    Self::from_signed_literal(-1)
443                } else {
444                    Self::from_signed_literal(0)
445                }
446            }
447            #[cfg_attr(feature = "use_attributes", in_hacspec)]
448            fn less_than_or_equal_bm(self, other: Self) -> Self {
449                if self.less_than_or_equal(other) {
450                    Self::from_signed_literal(-1)
451                } else {
452                    Self::from_signed_literal(0)
453                }
454            }
455        }
456    };
457}
458
459#[macro_export]
460macro_rules! unsigned_integer {
461    ($name:ident,$n:literal) => {
462        abstract_unsigned_secret_integer!($name, $n);
463
464        impl NumericCopy for $name {}
465        impl ModNumeric for $name {
466            /// (self - rhs) % n.
467            #[cfg_attr(feature = "use_attributes", in_hacspec)]
468            fn sub_mod(self, rhs: Self, n: Self) -> Self {
469                unimplemented!();
470            }
471            /// `(self + rhs) % n`
472            #[cfg_attr(feature = "use_attributes", in_hacspec)]
473            fn add_mod(self, rhs: Self, n: Self) -> Self {
474                unimplemented!();
475            }
476            /// `(self * rhs) % n`
477            #[cfg_attr(feature = "use_attributes", in_hacspec)]
478            fn mul_mod(self, rhs: Self, n: Self) -> Self {
479                unimplemented!();
480            }
481            /// `(self ^ exp) % n`
482            #[cfg_attr(feature = "use_attributes", in_hacspec)]
483            fn pow_mod(self, exp: Self, n: Self) -> Self {
484                unimplemented!();
485            }
486            /// `self % n`
487            #[cfg_attr(feature = "use_attributes", in_hacspec)]
488            fn modulo(self, n: Self) -> Self {
489                unimplemented!();
490            }
491            /// `self % n` that always returns a positive integer
492            #[cfg_attr(feature = "use_attributes", in_hacspec)]
493            fn signed_modulo(self, n: Self) -> Self {
494                self.modulo(n)
495            }
496            /// `|self|`
497            #[cfg_attr(feature = "use_attributes", in_hacspec)]
498            fn absolute(self) -> Self {
499                self
500            }
501        }
502        impl Numeric for $name {
503            /// Return largest value that can be represented.
504            #[cfg_attr(feature = "use_attributes", in_hacspec)]
505            fn max_val() -> Self {
506                unimplemented!();
507            }
508
509            #[cfg_attr(feature = "use_attributes", in_hacspec)]
510            fn wrap_add(self, rhs: Self) -> Self {
511                self + rhs
512            }
513            #[cfg_attr(feature = "use_attributes", in_hacspec)]
514            fn wrap_sub(self, rhs: Self) -> Self {
515                self - rhs
516            }
517            #[cfg_attr(feature = "use_attributes", in_hacspec)]
518            fn wrap_mul(self, rhs: Self) -> Self {
519                self * rhs
520            }
521            #[cfg_attr(feature = "use_attributes", in_hacspec)]
522            fn wrap_div(self, rhs: Self) -> Self {
523                unimplemented!();
524            }
525
526            /// `self ^ exp` where `exp` is a `u32`.
527            #[cfg_attr(feature = "use_attributes", in_hacspec)]
528            fn exp(self, exp: u32) -> Self {
529                unimplemented!();
530            }
531            /// `self ^ exp` where `exp` is a `Self`.
532            #[cfg_attr(feature = "use_attributes", in_hacspec)]
533            fn pow_self(self, exp: Self) -> Self {
534                unimplemented!();
535            }
536            /// Division.
537            #[cfg_attr(feature = "use_attributes", in_hacspec)]
538            fn divide(self, rhs: Self) -> Self {
539                unimplemented!();
540            }
541            /// Invert self modulo n.
542            #[cfg_attr(feature = "use_attributes", in_hacspec)]
543            fn inv(self, n: Self) -> Self {
544                unimplemented!();
545            }
546
547            // Comparison functions returning bool.
548            #[cfg_attr(feature = "use_attributes", in_hacspec)]
549            fn equal(self, other: Self) -> bool {
550                unimplemented!();
551            }
552            #[cfg_attr(feature = "use_attributes", in_hacspec)]
553            fn greater_than(self, other: Self) -> bool {
554                unimplemented!();
555            }
556            #[cfg_attr(feature = "use_attributes", in_hacspec)]
557            fn greater_than_or_equal(self, other: Self) -> bool {
558                unimplemented!();
559            }
560            #[cfg_attr(feature = "use_attributes", in_hacspec)]
561            fn less_than(self, other: Self) -> bool {
562                unimplemented!();
563            }
564            #[cfg_attr(feature = "use_attributes", in_hacspec)]
565            fn less_than_or_equal(self, other: Self) -> bool {
566                unimplemented!();
567            }
568
569            // Comparison functions returning a bit mask (0x0..0 or 0xF..F).
570            #[cfg_attr(feature = "use_attributes", in_hacspec)]
571            fn not_equal_bm(self, other: Self) -> Self {
572                unimplemented!();
573            }
574            #[cfg_attr(feature = "use_attributes", in_hacspec)]
575            fn equal_bm(self, other: Self) -> Self {
576                unimplemented!();
577            }
578            #[cfg_attr(feature = "use_attributes", in_hacspec)]
579            fn greater_than_bm(self, other: Self) -> Self {
580                unimplemented!();
581            }
582            #[cfg_attr(feature = "use_attributes", in_hacspec)]
583            fn greater_than_or_equal_bm(self, other: Self) -> Self {
584                unimplemented!();
585            }
586            #[cfg_attr(feature = "use_attributes", in_hacspec)]
587            fn less_than_bm(self, other: Self) -> Self {
588                unimplemented!();
589            }
590            #[cfg_attr(feature = "use_attributes", in_hacspec)]
591            fn less_than_or_equal_bm(self, other: Self) -> Self {
592                unimplemented!();
593            }
594        }
595    };
596}
597
598#[macro_export]
599macro_rules! signed_integer {
600    ($name:ident,$n:literal) => {
601        abstract_signed_secret_integer!($name, $n);
602
603        impl NumericCopy for $name {}
604        impl Integer for $name {
605            const NUM_BITS: usize = $n;
606
607            #[inline]
608            #[cfg_attr(feature = "use_attributes", in_hacspec)]
609            fn ZERO() -> Self {
610                Self::from_literal(0)
611            }
612            #[inline]
613            #[cfg_attr(feature = "use_attributes", in_hacspec)]
614            fn ONE() -> Self {
615                Self::from_literal(1)
616            }
617            #[inline]
618            #[cfg_attr(feature = "use_attributes", in_hacspec)]
619            fn TWO() -> Self {
620                Self::from_literal(2)
621            }
622
623            #[inline]
624            #[cfg_attr(feature = "use_attributes", in_hacspec)]
625            fn from_literal(val: u128) -> Self {
626                Self::from_literal(val)
627            }
628
629            #[inline]
630            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
631            /// Read hex string to `Self`.
632            fn from_hex_string(s: &String) -> Self {
633                let sign_str = if s.starts_with("-") { "-" } else { "+" };
634                Self::from_hex(
635                    &sign_str,
636                    &s.replace("0x", "").replace("-", "").replace("+", ""),
637                )
638            }
639
640            /// Get bit `i` of this integer.
641            #[inline]
642            #[cfg_attr(feature = "use_attributes", in_hacspec)]
643            fn get_bit(self, i: usize) -> Self {
644                (self >> i) & Self::ONE()
645            }
646
647            /// Set bit `i` of this integer to `b` and return the result.
648            /// Bit `b` has to be `0` or `1`.
649            #[inline]
650            #[cfg_attr(feature = "use_attributes", in_hacspec)]
651            fn set_bit(self, b: Self, i: usize) -> Self {
652                debug_assert!(b.clone().equal(Self::ONE()) || b.clone().equal(Self::ZERO()));
653                let tmp1 = Self::from_literal(!(1 << i));
654                let tmp2 = b << i;
655                (self & tmp1) | tmp2
656            }
657
658            /// Set bit `pos` of this integer to bit `yi` of integer `y`.
659            #[inline]
660            #[cfg_attr(feature = "use_attributes", in_hacspec)]
661            fn set(self, pos: usize, y: Self, yi: usize) -> Self {
662                let b = y.get_bit(yi);
663                self.set_bit(b, pos)
664            }
665
666            #[cfg_attr(feature = "use_attributes", in_hacspec)]
667            fn rotate_left(self, n: usize) -> Self {
668                // Taken from https://blog.regehr.org/archives/1063
669                assert!(n < Self::NUM_BITS);
670                (self.clone() << n) | (self >> ((-(n as i32) as usize) & (Self::NUM_BITS - 1)))
671            }
672
673            #[cfg_attr(feature = "use_attributes", in_hacspec)]
674            fn rotate_right(self, n: usize) -> Self {
675                // Taken from https://blog.regehr.org/archives/1063
676                assert!(n < Self::NUM_BITS);
677                (self.clone() >> n) | (self << ((-(n as i32) as usize) & (Self::NUM_BITS - 1)))
678            }
679        }
680        impl ModNumeric for $name {
681            /// (self - rhs) % n.
682            #[cfg_attr(feature = "use_attributes", in_hacspec)]
683            fn sub_mod(self, rhs: Self, n: Self) -> Self {
684                (self - rhs).modulo(n)
685            }
686            /// `(self + rhs) % n`
687            #[cfg_attr(feature = "use_attributes", in_hacspec)]
688            fn add_mod(self, rhs: Self, n: Self) -> Self {
689                (self + rhs).modulo(n)
690            }
691            /// `(self * rhs) % n`
692            #[cfg_attr(feature = "use_attributes", in_hacspec)]
693            fn mul_mod(self, rhs: Self, n: Self) -> Self {
694                (self * rhs).modulo(n)
695            }
696            /// `(self ^ exp) % n`
697            /// TODO: implement
698            #[cfg_attr(feature = "use_attributes", in_hacspec)]
699            fn pow_mod(self, exp: Self, n: Self) -> Self {
700                unimplemented!();
701            }
702            /// `self % n`
703            #[cfg_attr(feature = "use_attributes", in_hacspec)]
704            fn modulo(self, n: Self) -> Self {
705                unimplemented!();
706            }
707            /// `self % n` that always returns a positive integer
708            /// FIXME: implement ct
709            #[cfg_attr(feature = "use_attributes", in_hacspec)]
710            fn signed_modulo(self, n: Self) -> Self {
711                let mut ret = self.modulo(n);
712                while ret.less_than(Self::default()) {
713                    ret = ret + n;
714                }
715                ret
716            }
717            /// `|self|`
718            /// TODO: implement in abstract-integers
719            #[cfg_attr(feature = "use_attributes", in_hacspec)]
720            fn absolute(self) -> Self {
721                unimplemented!();
722            }
723        }
724        impl Numeric for $name {
725            /// Return largest value that can be represented.
726            #[cfg_attr(feature = "use_attributes", in_hacspec)]
727            fn max_val() -> Self {
728                unimplemented!();
729            }
730
731            #[cfg_attr(feature = "use_attributes", in_hacspec)]
732            fn wrap_add(self, rhs: Self) -> Self {
733                self + rhs
734            }
735            #[cfg_attr(feature = "use_attributes", in_hacspec)]
736            fn wrap_sub(self, rhs: Self) -> Self {
737                self - rhs
738            }
739            #[cfg_attr(feature = "use_attributes", in_hacspec)]
740            fn wrap_mul(self, rhs: Self) -> Self {
741                self * rhs
742            }
743            #[cfg_attr(feature = "use_attributes", in_hacspec)]
744            fn wrap_div(self, rhs: Self) -> Self {
745                unimplemented!();
746            }
747
748            /// `self ^ exp` where `exp` is a `u32`.
749            #[cfg_attr(feature = "use_attributes", in_hacspec)]
750            fn exp(self, exp: u32) -> Self {
751                unimplemented!();
752            }
753            /// `self ^ exp` where `exp` is a `Self`.
754            #[cfg_attr(feature = "use_attributes", in_hacspec)]
755            fn pow_self(self, exp: Self) -> Self {
756                unimplemented!();
757            }
758            /// Division.
759            #[cfg_attr(feature = "use_attributes", in_hacspec)]
760            fn divide(self, rhs: Self) -> Self {
761                unimplemented!();
762            }
763            /// Invert self modulo n.
764            #[cfg_attr(feature = "use_attributes", in_hacspec)]
765            fn inv(self, n: Self) -> Self {
766                unimplemented!();
767            }
768
769            // Comparison functions returning bool.
770            #[cfg_attr(feature = "use_attributes", in_hacspec)]
771            fn equal(self, other: Self) -> bool {
772                unimplemented!();
773            }
774            #[cfg_attr(feature = "use_attributes", in_hacspec)]
775            fn greater_than(self, other: Self) -> bool {
776                unimplemented!();
777            }
778            #[cfg_attr(feature = "use_attributes", in_hacspec)]
779            fn greater_than_or_equal(self, other: Self) -> bool {
780                unimplemented!();
781            }
782            #[cfg_attr(feature = "use_attributes", in_hacspec)]
783            fn less_than(self, other: Self) -> bool {
784                unimplemented!();
785            }
786            #[cfg_attr(feature = "use_attributes", in_hacspec)]
787            fn less_than_or_equal(self, other: Self) -> bool {
788                unimplemented!();
789            }
790
791            // Comparison functions returning a bit mask (0x0..0 or 0xF..F).
792            #[cfg_attr(feature = "use_attributes", in_hacspec)]
793            fn not_equal_bm(self, other: Self) -> Self {
794                unimplemented!();
795            }
796            #[cfg_attr(feature = "use_attributes", in_hacspec)]
797            fn equal_bm(self, other: Self) -> Self {
798                unimplemented!();
799            }
800            #[cfg_attr(feature = "use_attributes", in_hacspec)]
801            fn greater_than_bm(self, other: Self) -> Self {
802                unimplemented!();
803            }
804            #[cfg_attr(feature = "use_attributes", in_hacspec)]
805            fn greater_than_or_equal_bm(self, other: Self) -> Self {
806                unimplemented!();
807            }
808            #[cfg_attr(feature = "use_attributes", in_hacspec)]
809            fn less_than_bm(self, other: Self) -> Self {
810                unimplemented!();
811            }
812            #[cfg_attr(feature = "use_attributes", in_hacspec)]
813            fn less_than_or_equal_bm(self, other: Self) -> Self {
814                unimplemented!();
815            }
816        }
817    };
818}
819
820#[macro_export]
821macro_rules! nat_mod {
822    (type_name: $name:ident, type_of_canvas: $base:ident, bit_size_of_field: $bits:literal, modulo_value: $n:literal) => {
823        abstract_nat_mod!($name, $base, $bits, $n);
824
825        impl $name {
826            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
827            pub fn from_byte_seq_le<A: SeqTrait<U8>>(s: A) -> $name {
828                $name::from_le_bytes(
829                    s.iter()
830                        .map(|x| U8::declassify(*x))
831                        .collect::<Vec<_>>()
832                        .as_slice(),
833                )
834            }
835
836            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
837            pub fn to_byte_seq_le(self) -> Seq<U8> {
838                Seq::from_vec(
839                    self.to_le_bytes()
840                        .iter()
841                        .map(|x| U8::classify(*x))
842                        .collect::<Vec<U8>>(),
843                )
844            }
845        }
846
847        impl NumericCopy for $name {}
848        impl Integer for $name {
849            const NUM_BITS: usize = $bits;
850
851            #[inline]
852            #[cfg_attr(feature = "use_attributes", in_hacspec)]
853            fn ZERO() -> Self {
854                Self::from_literal(0)
855            }
856            #[inline]
857            #[cfg_attr(feature = "use_attributes", in_hacspec)]
858            fn ONE() -> Self {
859                Self::from_literal(1)
860            }
861            #[inline]
862            #[cfg_attr(feature = "use_attributes", in_hacspec)]
863            fn TWO() -> Self {
864                Self::from_literal(2)
865            }
866
867            #[inline]
868            #[cfg_attr(feature = "use_attributes", in_hacspec)]
869            fn from_literal(val: u128) -> Self {
870                Self::from_literal(val)
871            }
872
873            #[inline]
874            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
875            fn from_hex_string(s: &String) -> Self {
876                Self::from_hex(&s.replace("0x", ""))
877            }
878
879            /// Get bit `i` of this integer.
880            #[inline]
881            #[cfg_attr(feature = "use_attributes", in_hacspec)]
882            fn get_bit(self, i: usize) -> Self {
883                (self >> i) & Self::ONE()
884            }
885
886            /// Set bit `i` of this integer to `b` and return the result.
887            /// Bit `b` has to be `0` or `1`.
888            #[inline]
889            #[cfg_attr(feature = "use_attributes", in_hacspec)]
890            fn set_bit(self, b: Self, i: usize) -> Self {
891                debug_assert!(b.clone().equal(Self::ONE()) || b.clone().equal(Self::ZERO()));
892                let tmp1 = Self::from_literal(!(1 << i));
893                let tmp2 = b << i;
894                (self & tmp1) | tmp2
895            }
896
897            /// Set bit `pos` of this integer to bit `yi` of integer `y`.
898            #[inline]
899            #[cfg_attr(feature = "use_attributes", in_hacspec)]
900            fn set(self, pos: usize, y: Self, yi: usize) -> Self {
901                let b = y.get_bit(yi);
902                self.set_bit(b, pos)
903            }
904
905            #[cfg_attr(feature = "use_attributes", in_hacspec)]
906            fn rotate_left(self, n: usize) -> Self {
907                // Taken from https://blog.regehr.org/archives/1063
908                assert!(n < Self::NUM_BITS);
909                (self.clone() << n) | (self >> ((-(n as i32) as usize) & (Self::NUM_BITS - 1)))
910            }
911
912            #[cfg_attr(feature = "use_attributes", in_hacspec)]
913            fn rotate_right(self, n: usize) -> Self {
914                // Taken from https://blog.regehr.org/archives/1063
915                assert!(n < Self::NUM_BITS);
916                (self.clone() >> n) | (self << ((-(n as i32) as usize) & (Self::NUM_BITS - 1)))
917            }
918        }
919        impl UnsignedInteger for $name {}
920        // XXX: Note that this is not actually doing anything. There's no public
921        //      version.
922        impl SecretInteger for $name {
923            type PublicVersion = BigInt;
924            #[cfg_attr(feature = "use_attributes", in_hacspec)]
925            fn classify(x: Self::PublicVersion) -> Self {
926                unimplemented!();
927            }
928        }
929        impl UnsignedSecretInteger for $name {
930            #[cfg_attr(feature = "use_attributes", in_hacspec)]
931            fn to_le_bytes(self) -> Seq<U8> {
932                unimplemented!();
933            }
934            #[cfg_attr(feature = "use_attributes", in_hacspec)]
935            fn to_be_bytes(self) -> Seq<U8> {
936                unimplemented!();
937            }
938            #[cfg_attr(feature = "use_attributes", in_hacspec)]
939            fn from_le_bytes(x: &Seq<U8>) -> Self {
940                unimplemented!();
941            }
942            #[cfg_attr(feature = "use_attributes", in_hacspec)]
943            fn from_be_bytes(x: &Seq<U8>) -> Self {
944                unimplemented!();
945            }
946        }
947        impl ModNumeric for $name {
948            /// (self - rhs) % n.
949            #[cfg_attr(feature = "use_attributes", in_hacspec)]
950            fn sub_mod(self, rhs: Self, n: Self) -> Self {
951                self - rhs
952            }
953            /// `(self + rhs) % n`
954            #[cfg_attr(feature = "use_attributes", in_hacspec)]
955            fn add_mod(self, rhs: Self, n: Self) -> Self {
956                self + rhs
957            }
958            /// `(self * rhs) % n`
959            #[cfg_attr(feature = "use_attributes", in_hacspec)]
960            fn mul_mod(self, rhs: Self, n: Self) -> Self {
961                self * rhs
962            }
963            /// `(self ^ exp) % n`
964            #[cfg_attr(feature = "use_attributes", in_hacspec)]
965            fn pow_mod(self, exp: Self, n: Self) -> Self {
966                unimplemented!();
967            }
968            /// `self % n`
969            #[cfg_attr(feature = "use_attributes", in_hacspec)]
970            fn modulo(self, n: Self) -> Self {
971                self.modulo(n)
972            }
973            /// `self % n` that always returns a positive integer
974            #[cfg_attr(feature = "use_attributes", in_hacspec)]
975            fn signed_modulo(self, n: Self) -> Self {
976                self.modulo(n)
977            }
978            /// `|self|`
979            #[cfg_attr(feature = "use_attributes", in_hacspec)]
980            fn absolute(self) -> Self {
981                self
982            }
983        }
984        impl Numeric for $name {
985            /// Return largest value that can be represented.
986            #[cfg_attr(feature = "use_attributes", in_hacspec)]
987            fn max_val() -> Self {
988                unimplemented!();
989            }
990
991            #[cfg_attr(feature = "use_attributes", in_hacspec)]
992            fn wrap_add(self, rhs: Self) -> Self {
993                self + rhs
994            }
995            #[cfg_attr(feature = "use_attributes", in_hacspec)]
996            fn wrap_sub(self, rhs: Self) -> Self {
997                self - rhs
998            }
999            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1000            fn wrap_mul(self, rhs: Self) -> Self {
1001                self * rhs
1002            }
1003            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1004            fn wrap_div(self, rhs: Self) -> Self {
1005                unimplemented!();
1006            }
1007
1008            /// `self ^ exp` where `exp` is a `u32`.
1009            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1010            fn exp(self, exp: u32) -> Self {
1011                unimplemented!();
1012            }
1013            /// `self ^ exp` where `exp` is a `Self`.
1014            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1015            fn pow_self(self, exp: Self) -> Self {
1016                unimplemented!();
1017            }
1018            /// Division.
1019            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1020            fn divide(self, rhs: Self) -> Self {
1021                unimplemented!();
1022            }
1023            /// Invert self modulo n.
1024            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1025            fn inv(self, n: Self) -> Self {
1026                unimplemented!();
1027            }
1028
1029            // Comparison functions returning bool.
1030            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1031            fn equal(self, other: Self) -> bool {
1032                let bm = self.equal_bm(other);
1033                let bm: BigInt = bm.declassify();
1034                bm != BigInt::zero()
1035            }
1036            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1037            fn greater_than(self, other: Self) -> bool {
1038                let bm = self.greater_than_bm(other);
1039                let bm: BigInt = bm.declassify();
1040                bm != BigInt::zero()
1041            }
1042            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1043            fn greater_than_or_equal(self, other: Self) -> bool {
1044                let bm = self.greater_than_or_equal_bm(other);
1045                let bm: BigInt = bm.declassify();
1046                bm != BigInt::zero()
1047            }
1048            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1049            fn less_than(self, other: Self) -> bool {
1050                let bm = self.less_than_bm(other);
1051                let bm: BigInt = bm.declassify();
1052                bm != BigInt::zero()
1053            }
1054            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1055            fn less_than_or_equal(self, other: Self) -> bool {
1056                let bm = self.less_than_or_equal_bm(other);
1057                let bm: BigInt = bm.declassify();
1058                bm != BigInt::zero()
1059            }
1060
1061            // Comparison functions returning a bit mask (0x0..0 or 0xF..F).
1062            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1063            fn not_equal_bm(self, other: Self) -> Self {
1064                self.comp_ne(other)
1065            }
1066            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1067            fn equal_bm(self, other: Self) -> Self {
1068                self.comp_eq(other)
1069            }
1070            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1071            fn greater_than_bm(self, other: Self) -> Self {
1072                self.comp_gt(other)
1073            }
1074            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1075            fn greater_than_or_equal_bm(self, other: Self) -> Self {
1076                self.comp_gte(other)
1077            }
1078            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1079            fn less_than_bm(self, other: Self) -> Self {
1080                self.comp_lt(other)
1081            }
1082            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1083            fn less_than_or_equal_bm(self, other: Self) -> Self {
1084                self.comp_lte(other)
1085            }
1086        }
1087    };
1088}
1089
1090#[macro_export]
1091macro_rules! public_nat_mod {
1092    (type_name: $name:ident, type_of_canvas: $base:ident,  bit_size_of_field: $bits:literal, modulo_value: $n:literal) => {
1093        unsigned_public_integer!($base, $bits);
1094        abstract_public_modular_integer!($name, $base, $base::from_hex($n));
1095
1096        impl $name {
1097            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
1098            pub fn from_byte_seq_be<A: SeqTrait<U8>>(s: &A) -> $name {
1099                $base::from_be_bytes(
1100                    s.iter()
1101                        .map(|x| U8::declassify(*x))
1102                        .collect::<Vec<_>>()
1103                        .as_slice(),
1104                )
1105                .into()
1106            }
1107
1108            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
1109            pub fn from_public_byte_seq_be<A: SeqTrait<u8>>(s: A) -> $name {
1110                $base::from_be_bytes(s.iter().map(|x| *x).collect::<Vec<_>>().as_slice()).into()
1111            }
1112
1113            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
1114            pub fn to_byte_seq_be(self) -> Seq<U8> {
1115                Seq::from_vec(
1116                    self.to_be_bytes()
1117                        .iter()
1118                        .map(|x| U8::classify(*x))
1119                        .collect::<Vec<U8>>(),
1120                )
1121            }
1122
1123            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
1124            pub fn to_public_byte_seq_be(self) -> Seq<u8> {
1125                Seq::from_vec(self.to_be_bytes())
1126            }
1127
1128            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
1129            pub fn from_byte_seq_le<A: SeqTrait<U8>>(s: A) -> $name {
1130                $base::from_le_bytes(
1131                    s.iter()
1132                        .map(|x| U8::declassify(*x))
1133                        .collect::<Vec<_>>()
1134                        .as_slice(),
1135                )
1136                .into()
1137            }
1138
1139            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
1140            pub fn from_public_byte_seq_le<A: SeqTrait<u8>>(s: A) -> $name {
1141                $base::from_le_bytes(s.iter().map(|x| *x).collect::<Vec<_>>().as_slice()).into()
1142            }
1143
1144            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
1145            pub fn to_byte_seq_le(self) -> Seq<U8> {
1146                Seq::from_vec(
1147                    self.to_le_bytes()
1148                        .iter()
1149                        .map(|x| U8::classify(*x))
1150                        .collect::<Vec<U8>>(),
1151                )
1152            }
1153
1154            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
1155            pub fn to_public_byte_seq_le(self) -> Seq<u8> {
1156                Seq::from_vec(self.to_le_bytes())
1157            }
1158
1159            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
1160            pub fn from_secret_literal(x: U128) -> $name {
1161                $base::from_literal(U128::declassify(x)).into()
1162            }
1163        }
1164
1165        impl NumericCopy for $name {}
1166        impl UnsignedInteger for $name {}
1167        impl UnsignedIntegerCopy for $name {}
1168        impl Integer for $name {
1169            const NUM_BITS: usize = $bits;
1170
1171            #[inline]
1172            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1173            fn ZERO() -> Self {
1174                Self::from_literal(0)
1175            }
1176            #[inline]
1177            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1178            fn ONE() -> Self {
1179                Self::from_literal(1)
1180            }
1181            #[inline]
1182            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1183            fn TWO() -> Self {
1184                Self::from_literal(2)
1185            }
1186
1187            #[inline]
1188            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1189            fn from_literal(val: u128) -> Self {
1190                Self::from_literal(val)
1191            }
1192
1193            #[inline]
1194            #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
1195            fn from_hex_string(s: &String) -> Self {
1196                Self::from_hex(&s.replace("0x", ""))
1197            }
1198
1199            /// Get bit `i` of this integer.
1200            #[inline]
1201            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1202            fn get_bit(self, i: usize) -> Self {
1203                (self >> i) & Self::ONE()
1204            }
1205
1206            /// Set bit `i` of this integer to `b` and return the result.
1207            /// Bit `b` has to be `0` or `1`.
1208            #[inline]
1209            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1210            fn set_bit(self, b: Self, i: usize) -> Self {
1211                debug_assert!(b.clone().equal(Self::ONE()) || b.clone().equal(Self::ZERO()));
1212                let tmp1 = Self::from_literal(!(1 << i));
1213                let tmp2 = b << i;
1214                (self & tmp1) | tmp2
1215            }
1216
1217            /// Set bit `pos` of this integer to bit `yi` of integer `y`.
1218            #[inline]
1219            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1220            fn set(self, pos: usize, y: Self, yi: usize) -> Self {
1221                let b = y.get_bit(yi);
1222                self.set_bit(b, pos)
1223            }
1224
1225            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1226            fn rotate_left(self, n: usize) -> Self {
1227                // Taken from https://blog.regehr.org/archives/1063
1228                assert!(n < Self::NUM_BITS);
1229                (self.clone() << n) | (self >> ((-(n as i32) as usize) & (Self::NUM_BITS - 1)))
1230            }
1231
1232            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1233            fn rotate_right(self, n: usize) -> Self {
1234                // Taken from https://blog.regehr.org/archives/1063
1235                assert!(n < Self::NUM_BITS);
1236                (self.clone() >> n) | (self << ((-(n as i32) as usize) & (Self::NUM_BITS - 1)))
1237            }
1238        }
1239        impl ModNumeric for $name {
1240            /// (self - rhs) % n.
1241            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1242            fn sub_mod(self, rhs: Self, n: Self) -> Self {
1243                self - rhs
1244            }
1245            /// `(self + rhs) % n`
1246            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1247            fn add_mod(self, rhs: Self, n: Self) -> Self {
1248                self + rhs
1249            }
1250            /// `(self * rhs) % n`
1251            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1252            fn mul_mod(self, rhs: Self, n: Self) -> Self {
1253                self * rhs
1254            }
1255            /// `(self ^ exp) % n`
1256            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1257            fn pow_mod(self, exp: Self, n: Self) -> Self {
1258                self.pow_felem(exp)
1259            }
1260            /// `self % n`
1261            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1262            fn modulo(self, n: Self) -> Self {
1263                self % n
1264            }
1265            /// `self % n` that always returns a positive integer
1266            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1267            fn signed_modulo(self, n: Self) -> Self {
1268                self.modulo(n)
1269            }
1270            /// `|self|`
1271            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1272            fn absolute(self) -> Self {
1273                self
1274            }
1275        }
1276        impl Numeric for $name {
1277            /// Return largest value that can be represented.
1278            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1279            fn max_val() -> Self {
1280                (Self::max() - $base::from_literal(1)).into()
1281            }
1282
1283            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1284            fn wrap_add(self, rhs: Self) -> Self {
1285                self + rhs
1286            }
1287            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1288            fn wrap_sub(self, rhs: Self) -> Self {
1289                self - rhs
1290            }
1291            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1292            fn wrap_mul(self, rhs: Self) -> Self {
1293                self * rhs
1294            }
1295            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1296            fn wrap_div(self, rhs: Self) -> Self {
1297                self / rhs
1298            }
1299
1300            /// `self ^ exp` where `exp` is a `u32`.
1301            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1302            fn exp(self, exp: u32) -> Self {
1303                self.pow(exp.into())
1304            }
1305            /// `self ^ exp` where `exp` is a `Self`.
1306            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1307            fn pow_self(self, exp: Self) -> Self {
1308                self.pow_felem(exp)
1309            }
1310            /// Division.
1311            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1312            fn divide(self, rhs: Self) -> Self {
1313                self / rhs
1314            }
1315            /// Invert self modulo n.
1316            /// **NOTE:** `n` is ignored and inversion is done with respect to
1317            ///            the modulus.
1318            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1319            fn inv(self, n: Self) -> Self {
1320                self.inv()
1321            }
1322
1323            // Comparison functions returning bool.
1324            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1325            fn equal(self, other: Self) -> bool {
1326                self == other
1327            }
1328            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1329            fn greater_than(self, other: Self) -> bool {
1330                self > other
1331            }
1332            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1333            fn greater_than_or_equal(self, other: Self) -> bool {
1334                self >= other
1335            }
1336            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1337            fn less_than(self, other: Self) -> bool {
1338                self < other
1339            }
1340            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1341            fn less_than_or_equal(self, other: Self) -> bool {
1342                self <= other
1343            }
1344
1345            // Comparison functions returning a bit mask (0x0..0 or 0xF..F).
1346            // Return $bits-1 1s as we can't represent 0xF..F.
1347            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1348            fn not_equal_bm(self, other: Self) -> Self {
1349                if self != other {
1350                    (Self::ONE() << ($bits - 1)) - Self::ONE()
1351                } else {
1352                    Self::ZERO()
1353                }
1354            }
1355            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1356            fn equal_bm(self, other: Self) -> Self {
1357                if self == other {
1358                    (Self::ONE() << ($bits - 1)) - Self::ONE()
1359                } else {
1360                    Self::ZERO()
1361                }
1362            }
1363            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1364            fn greater_than_bm(self, other: Self) -> Self {
1365                if self > other {
1366                    (Self::ONE() << ($bits - 1)) - Self::ONE()
1367                } else {
1368                    Self::ZERO()
1369                }
1370            }
1371            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1372            fn greater_than_or_equal_bm(self, other: Self) -> Self {
1373                if self >= other {
1374                    (Self::ONE() << ($bits - 1)) - Self::ONE()
1375                } else {
1376                    Self::ZERO()
1377                }
1378            }
1379            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1380            fn less_than_bm(self, other: Self) -> Self {
1381                if self < other {
1382                    (Self::ONE() << ($bits - 1)) - Self::ONE()
1383                } else {
1384                    Self::ZERO()
1385                }
1386            }
1387            #[cfg_attr(feature = "use_attributes", in_hacspec)]
1388            fn less_than_or_equal_bm(self, other: Self) -> Self {
1389                if self <= other {
1390                    (Self::ONE() << ($bits - 1)) - Self::ONE()
1391                } else {
1392                    Self::ZERO()
1393                }
1394            }
1395        }
1396    };
1397}