#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(rustdoc::broken_intra_doc_links)]
#![forbid(unsafe_code)]
#[cfg(feature = "alloc")]
extern crate alloc;
mod batch;
pub use batch::*;
#[cfg(feature = "derive")]
#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
pub use ff_derive::PrimeField;
#[cfg(feature = "bits")]
#[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
pub use bitvec::view::BitViewSized;
#[cfg(feature = "bits")]
use bitvec::{array::BitArray, order::Lsb0};
use core::fmt;
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use rand_core::RngCore;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
#[cfg(feature = "bits")]
#[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
pub type FieldBits<V> = BitArray<V, Lsb0>;
pub trait Field:
Sized
+ Eq
+ Copy
+ Clone
+ Default
+ Send
+ Sync
+ fmt::Debug
+ 'static
+ ConditionallySelectable
+ ConstantTimeEq
+ Add<Output = Self>
+ Sub<Output = Self>
+ Mul<Output = Self>
+ Neg<Output = Self>
+ for<'a> Add<&'a Self, Output = Self>
+ for<'a> Mul<&'a Self, Output = Self>
+ for<'a> Sub<&'a Self, Output = Self>
+ MulAssign
+ AddAssign
+ SubAssign
+ for<'a> MulAssign<&'a Self>
+ for<'a> AddAssign<&'a Self>
+ for<'a> SubAssign<&'a Self>
{
fn random(rng: impl RngCore) -> Self;
fn zero() -> Self;
fn one() -> Self;
fn is_zero(&self) -> Choice {
self.ct_eq(&Self::zero())
}
fn is_zero_vartime(&self) -> bool {
self.is_zero().into()
}
#[must_use]
fn square(&self) -> Self;
#[must_use]
fn cube(&self) -> Self {
self.square() * self
}
#[must_use]
fn double(&self) -> Self;
fn invert(&self) -> CtOption<Self>;
fn sqrt(&self) -> CtOption<Self>;
fn pow_vartime<S: AsRef<[u64]>>(&self, exp: S) -> Self {
let mut res = Self::one();
for e in exp.as_ref().iter().rev() {
for i in (0..64).rev() {
res = res.square();
if ((*e >> i) & 1) == 1 {
res.mul_assign(self);
}
}
}
res
}
}
pub trait PrimeField: Field + From<u64> {
type Repr: Copy + Default + Send + Sync + 'static + AsRef<[u8]> + AsMut<[u8]>;
fn from_str_vartime(s: &str) -> Option<Self> {
if s.is_empty() {
return None;
}
if s == "0" {
return Some(Self::zero());
}
let mut res = Self::zero();
let ten = Self::from(10);
let mut first_digit = true;
for c in s.chars() {
match c.to_digit(10) {
Some(c) => {
if first_digit {
if c == 0 {
return None;
}
first_digit = false;
}
res.mul_assign(&ten);
res.add_assign(&Self::from(u64::from(c)));
}
None => {
return None;
}
}
}
Some(res)
}
fn from_repr(repr: Self::Repr) -> CtOption<Self>;
fn from_repr_vartime(repr: Self::Repr) -> Option<Self> {
Self::from_repr(repr).into()
}
fn to_repr(&self) -> Self::Repr;
fn is_odd(&self) -> Choice;
#[inline(always)]
fn is_even(&self) -> Choice {
!self.is_odd()
}
const NUM_BITS: u32;
const CAPACITY: u32;
fn multiplicative_generator() -> Self;
const S: u32;
fn root_of_unity() -> Self;
}
#[cfg(feature = "bits")]
#[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
pub trait PrimeFieldBits: PrimeField {
type ReprBits: BitViewSized + Send + Sync;
fn to_le_bits(&self) -> FieldBits<Self::ReprBits>;
fn char_le_bits() -> FieldBits<Self::ReprBits>;
}
#[cfg(feature = "derive")]
#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
pub mod derive {
pub use crate::arith_impl::*;
pub use {byteorder, rand_core, subtle};
#[cfg(feature = "bits")]
pub use bitvec;
}
#[cfg(feature = "derive")]
mod arith_impl {
#[inline(always)]
pub const fn sbb(a: u64, b: u64, borrow: u64) -> (u64, u64) {
let ret = (a as u128).wrapping_sub((b as u128) + ((borrow >> 63) as u128));
(ret as u64, (ret >> 64) as u64)
}
#[inline(always)]
pub const fn adc(a: u64, b: u64, carry: u64) -> (u64, u64) {
let ret = (a as u128) + (b as u128) + (carry as u128);
(ret as u64, (ret >> 64) as u64)
}
#[inline(always)]
pub const fn mac(a: u64, b: u64, c: u64, carry: u64) -> (u64, u64) {
let ret = (a as u128) + ((b as u128) * (c as u128)) + (carry as u128);
(ret as u64, (ret >> 64) as u64)
}
}