1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
use crate::traits::Borsh; use crate::Uint; use crate::{BitIterBE, BitIteratorBE}; pub trait PrimeFieldParams { type Inner: Uint; const MODULUS: Self::Inner; const MODULUS_BITS: u32; const REPR_SHAVE_BITS: u32; const R: Self::Inner; const R2: Self::Inner; const INV: u64; const GENERATOR: Self::Inner; const S: u32; const ROOT_OF_UNITY: Self::Inner; } #[derive(Debug, PartialEq)] pub enum LegendreSymbol { Zero = 0, QuadraticResidue = 1, QuadraticNonResidue = -1, } pub trait Field: Sized + Clone + Copy + Default + core::cmp::PartialEq + core::cmp::Eq + core::fmt::Debug + core::fmt::Display { const ZERO: Self; const ONE: Self; #[cfg(feature = "rand_support")] fn random<R: rand::Rng + ?Sized>(rng: &mut R) -> Self; fn is_zero(&self) -> bool; fn wrapping_add(self, other: Self) -> Self; fn wrapping_sub(self, other: Self) -> Self; fn wrapping_mul(self, other: Self) -> Self; fn wrapping_div(self, other: Self) -> Self { self.wrapping_mul(other.checked_inv().expect("Division by zero")) } fn wrapping_neg(self) -> Self; fn square(self) -> Self; fn double(self) -> Self; fn checked_inv(self) -> Option<Self>; fn frobenius_map(self, power: usize) -> Self; fn pow<S: BitIterBE>(self, exp: S) -> Self { let mut res = Self::ONE; let mut found_one = false; for i in exp.bit_iter_be() { if found_one { res = res.square(); } else { found_one = i; } if i { res = res.wrapping_mul(self); } } res } } pub trait SqrtField: Field { fn legendre(&self) -> LegendreSymbol; fn sqrt(&self) -> Option<Self>; } pub trait PrimeField: PrimeFieldParams + SqrtField + core::str::FromStr + From<&'static str> + Borsh { fn from_uint(v: Self::Inner) -> Option<Self>; fn from_mont_uint(v: Self::Inner) -> Option<Self>; fn from_uint_unchecked(v: Self::Inner) -> Self; fn from_mont_uint_unchecked(v: Self::Inner) -> Self; fn to_uint(&self) -> Self::Inner; fn to_mont_uint(&self) -> Self::Inner; fn as_mont_uint(&self) -> &Self::Inner; fn as_mont_uint_mut(&mut self) -> &mut Self::Inner; fn to_other<Fq: PrimeField>(&self) -> Option<Fq> { let u = self.to_uint().to_other()?; if u >= Fq::MODULUS { None } else { Some(Fq::from_uint_unchecked(u)) } } fn to_other_reduced<Fq: PrimeField>(&self) -> Fq { match self.to_uint().to_other::<Fq::Inner>() { Some(u) => Fq::from_uint_unchecked(u.wrapping_rem(Fq::MODULUS)), None => { let u = self .to_uint() .wrapping_rem(<Fq as PrimeFieldParams>::MODULUS.to_other().unwrap()); Fq::from_uint_unchecked(u.to_other().unwrap()) } } } }