1use std::fmt::Debug;
2use std::ops::{Div, Neg, Sub};
3
4use num_traits::{One, Zero};
5
6pub trait Field:
9 Clone
10 + PartialEq
11 + Debug
12 + Zero
13 + One
14 + Neg<Output = Self>
15 + Sub<Output = Self>
16 + Div<Output = Self>
17{
18 fn inverse(&self) -> Option<Self> {
20 (!self.is_zero()).then(|| Self::one() / self.clone())
21 }
22}
23
24impl<F> Field for F where
25 F: Clone + PartialEq + Debug + Zero + One + Neg<Output = F> + Sub<Output = F> + Div<Output = F>
26{
27}
28
29pub fn pow<F: Field>(x: &F, mut e: u64) -> F {
31 let (mut base, mut acc) = (x.clone(), F::one());
32 while e > 0 {
33 if e & 1 == 1 {
34 acc = acc * base.clone();
35 }
36 e >>= 1;
37 if e > 0 {
38 base = base.clone() * base;
39 }
40 }
41 acc
42}
43
44pub fn nat<F: Field>(n: u64) -> F {
46 let two = F::one() + F::one();
47 (0..u64::BITS - n.leading_zeros())
48 .rev()
49 .fold(F::zero(), |acc, i| {
50 let acc = acc * two.clone();
51 if n >> i & 1 == 1 { acc + F::one() } else { acc }
52 })
53}