pub trait FieldAlgebra:
Sized
+ Default
+ Clone
+ Add<Output = Self>
+ AddAssign
+ Sub<Output = Self>
+ SubAssign
+ Neg<Output = Self>
+ Mul<Output = Self>
+ MulAssign
+ Sum
+ Product
+ Debug {
type F: Field;
const ZERO: Self;
const ONE: Self;
const TWO: Self;
const NEG_ONE: Self;
Show 22 methods
// Required methods
fn from_f(f: Self::F) -> Self;
fn from_bool(b: bool) -> Self;
fn from_canonical_u8(n: u8) -> Self;
fn from_canonical_u16(n: u16) -> Self;
fn from_canonical_u32(n: u32) -> Self;
fn from_canonical_u64(n: u64) -> Self;
fn from_canonical_usize(n: usize) -> Self;
fn from_wrapped_u32(n: u32) -> Self;
fn from_wrapped_u64(n: u64) -> Self;
// Provided methods
fn double(&self) -> Self { ... }
fn square(&self) -> Self { ... }
fn cube(&self) -> Self { ... }
fn exp_u64(&self, power: u64) -> Self { ... }
fn exp_const_u64<const POWER: u64>(&self) -> Self { ... }
fn exp_power_of_2(&self, power_log: usize) -> Self { ... }
fn mul_2exp_u64(&self, exp: u64) -> Self { ... }
fn powers(&self) -> Powers<Self> ⓘ { ... }
fn shifted_powers(&self, start: Self) -> Powers<Self> ⓘ { ... }
fn powers_packed<P: PackedField<Scalar = Self>>(&self) -> Powers<P> ⓘ { ... }
fn shifted_powers_packed<P: PackedField<Scalar = Self>>(
&self,
start: Self,
) -> Powers<P> ⓘ { ... }
fn dot_product<const N: usize>(u: &[Self; N], v: &[Self; N]) -> Self { ... }
fn zero_vec(len: usize) -> Vec<Self> { ... }
}
Expand description
A commutative algebra over a finite field.
This permits elements like:
- an actual field element
- a symbolic expression which would evaluate to a field element
- an array of field elements
Mathematically speaking, this is an algebraic structure with addition,
multiplication and scalar multiplication. The addition and multiplication
maps must be both commutative and associative, and there must
exist identity elements for both (named ZERO
and ONE
respectively). Furthermore, multiplication must distribute over
addition. Finally, the scalar multiplication must be realized by
a ring homomorphism from the field to the algebra.
Required Associated Constants§
Sourceconst ZERO: Self
const ZERO: Self
The additive identity of the algebra.
For every element a
in the algebra we require the following properties:
a + ZERO = ZERO + a = a,
a + (-a) = (-a) + a = ZERO.
Sourceconst ONE: Self
const ONE: Self
The multiplicative identity of the Algebra
For every element a
in the algebra we require the following property:
a*ONE = ONE*a = a.
Sourceconst TWO: Self
const TWO: Self
The element in the algebra given by ONE + ONE
.
This is provided as a convenience as TWO
occurs regularly in
the proving system. This also is slightly faster than computing
it via addition. Note that multiplication by TWO
is discouraged.
Instead of a * TWO
use a.double()
which will be faster.
If the field has characteristic 2 this is equal to ZERO.
Sourceconst NEG_ONE: Self
const NEG_ONE: Self
The element in the algebra given by -ONE
.
This is provided as a convenience as NEG_ONE
occurs regularly in
the proving system. This also is slightly faster than computing
it via negation. Note that where possible NEG_ONE
should be absorbed
into mathematical operations. For example a - b
will be faster
than a + NEG_ONE * b
and similarly (-b)
is faster than NEG_ONE * b
.
If the field has characteristic 2 this is equal to ONE.
Required Associated Types§
Required Methods§
Sourcefn from_f(f: Self::F) -> Self
fn from_f(f: Self::F) -> Self
Interpret a field element as a commutative algebra element.
Mathematically speaking, this map is a ring homomorphism from the base field to the commutative algebra. The existence of this map makes this structure an algebra and not simply a commutative ring.
Sourcefn from_canonical_u8(n: u8) -> Self
fn from_canonical_u8(n: u8) -> Self
Convert from a canonical u8
.
If the input is not canonical, i.e. if it exceeds the field’s characteristic, then the behavior is undefined.
Sourcefn from_canonical_u16(n: u16) -> Self
fn from_canonical_u16(n: u16) -> Self
Convert from a canonical u16
.
If the input is not canonical, i.e. if it exceeds the field’s characteristic, then the behavior is undefined.
Sourcefn from_canonical_u32(n: u32) -> Self
fn from_canonical_u32(n: u32) -> Self
Convert from a canonical u32
.
If the input is not canonical, i.e. if it exceeds the field’s characteristic, then the behavior is undefined.
Sourcefn from_canonical_u64(n: u64) -> Self
fn from_canonical_u64(n: u64) -> Self
Convert from a canonical u64
.
If the input is not canonical, i.e. if it exceeds the field’s characteristic, then the behavior is undefined.
Sourcefn from_canonical_usize(n: usize) -> Self
fn from_canonical_usize(n: usize) -> Self
Convert from a canonical usize
.
If the input is not canonical, i.e. if it exceeds the field’s characteristic, then the behavior is undefined.
fn from_wrapped_u32(n: u32) -> Self
fn from_wrapped_u64(n: u64) -> Self
Provided Methods§
Sourcefn double(&self) -> Self
fn double(&self) -> Self
The elementary function double(a) = 2*a
.
This function should be preferred over calling a + a
or TWO * a
as a faster implementation may be available for some algebras.
If the field has characteristic 2 then this returns 0.
Sourcefn square(&self) -> Self
fn square(&self) -> Self
The elementary function square(a) = a^2
.
This function should be preferred over calling a * a
, as a faster implementation may be available for some algebras.
Sourcefn cube(&self) -> Self
fn cube(&self) -> Self
The elementary function cube(a) = a^3
.
This function should be preferred over calling a * a * a
, as a faster implementation may be available for some algebras.
Sourcefn exp_u64(&self, power: u64) -> Self
fn exp_u64(&self, power: u64) -> Self
Exponentiation by a u64
power.
The default implementation calls exp_u64_generic
, which by default performs exponentiation
by squaring. Rather than override this method, it is generally recommended to have the
concrete field type override exp_u64_generic
, so that any optimizations will apply to all
abstract fields.
Sourcefn exp_const_u64<const POWER: u64>(&self) -> Self
fn exp_const_u64<const POWER: u64>(&self) -> Self
Exponentiation by a constant power.
For a collection of small values we implement custom multiplication chain circuits which can be faster than the simpler square and multiply approach.
Sourcefn exp_power_of_2(&self, power_log: usize) -> Self
fn exp_power_of_2(&self, power_log: usize) -> Self
Compute self^{2^power_log} by repeated squaring.
Sourcefn mul_2exp_u64(&self, exp: u64) -> Self
fn mul_2exp_u64(&self, exp: u64) -> Self
self * 2^exp
Sourcefn powers(&self) -> Powers<Self> ⓘ
fn powers(&self) -> Powers<Self> ⓘ
Construct an iterator which returns powers of self: self^0, self^1, self^2, ...
.
Sourcefn shifted_powers(&self, start: Self) -> Powers<Self> ⓘ
fn shifted_powers(&self, start: Self) -> Powers<Self> ⓘ
Construct an iterator which returns powers of self
shifted by start: start, start*self^1, start*self^2, ...
.
Sourcefn powers_packed<P: PackedField<Scalar = Self>>(&self) -> Powers<P> ⓘ
fn powers_packed<P: PackedField<Scalar = Self>>(&self) -> Powers<P> ⓘ
Construct an iterator which returns powers of self
packed into PackedField
elements.
E.g. if PACKING::WIDTH = 4
this returns the elements:
[self^0, self^1, self^2, self^3], [self^4, self^5, self^6, self^7], ...
.
Sourcefn shifted_powers_packed<P: PackedField<Scalar = Self>>(
&self,
start: Self,
) -> Powers<P> ⓘ
fn shifted_powers_packed<P: PackedField<Scalar = Self>>( &self, start: Self, ) -> Powers<P> ⓘ
Construct an iterator which returns powers of self
shifted by start
and packed into PackedField
elements.
E.g. if PACKING::WIDTH = 4
this returns the elements:
[start, start*self, start*self^2, start*self^3], [start*self^4, start*self^5, start*self^6, start*self^7], ...
.
Sourcefn dot_product<const N: usize>(u: &[Self; N], v: &[Self; N]) -> Self
fn dot_product<const N: usize>(u: &[Self; N], v: &[Self; N]) -> Self
Compute the dot product of two vectors.
Sourcefn zero_vec(len: usize) -> Vec<Self>
fn zero_vec(len: usize) -> Vec<Self>
Allocates a vector of zero elements of length len
. Many operating systems zero pages
before assigning them to a userspace process. In that case, our process should not need to
write zeros, which would be redundant. However, the compiler may not always recognize this.
In particular, vec![Self::ZERO; len]
appears to result in redundant userspace zeroing.
This is the default implementation, but implementors may wish to provide their own
implementation which transmutes something like vec![0u32; len]
.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.