use core::{
fmt::Debug,
ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
};
use subtle::{ConditionallySelectable, ConstantTimeEq};
use crate::{Error, Result};
pub trait FieldImplementation
where
Self: Copy,
Self: Debug,
Self: ConditionallySelectable,
for<'b> Self: ConstantTimeEq,
Self: PartialEq,
for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
for<'b> Self: AddAssign<&'b Self>,
for<'a> &'a Self: Neg<Output = Self>,
for<'a, 'b> &'a Self: Sub<&'b Self, Output = Self>,
for<'b> Self: SubAssign<&'b Self>,
for<'a, 'b> &'a Self: Mul<&'b Self, Output = Self>,
for<'b> Self: MulAssign<&'b Self>,
{
type Limbs;
const ZERO: Self;
const ONE: Self;
const D: Self;
const D2: Self;
const APLUS2_OVER_FOUR: Self;
const EDWARDS_BASEPOINT_X: Self;
const EDWARDS_BASEPOINT_Y: Self;
const I: Self;
const MONTGOMERY_BASEPOINT_U: Self;
fn to_bytes(&self) -> [u8; 32];
fn from_unreduced_bytes(bytes: &[u8; 32]) -> Self {
let unreduced = Self::from_bytes_unchecked(bytes);
Self::from_bytes_unchecked(&unreduced.to_bytes())
}
fn from_bytes_unchecked(bytes: &[u8; 32]) -> Self;
fn from_bytes(bytes: &[u8; 32]) -> Result<Self> {
let unchecked = Self::from_bytes_unchecked(bytes);
let canonical_representation = unchecked.to_bytes();
if bool::from(bytes.ct_eq(&canonical_representation)) {
Ok(unchecked)
} else {
Err(Error::NonCanonicalFieldElement)
}
}
fn parity(&self) -> u8 {
let d = self.to_bytes();
d[0] & 1
}
fn squared(&self) -> Self {
self * self
}
fn inverse(&self) -> Self;
fn pow2523(&self) -> Self;
}
#[cfg(tweetnacl)]
pub mod tweetnacl;
#[cfg(tweetnacl)]
pub use tweetnacl::{FieldElement, Limbs};
#[cfg(haase)]
pub mod haase;
#[cfg(haase)]
pub use haase::{FieldElement, Limbs};