pub struct PackedGf2<U: Underlier>(/* private fields */);Expand description
Several independent elements of GF(2), one per bit of a block of storage.
Lane i is bit i mod B of word i / B, counting from the least significant bit.
Read as bytes, that puts lane i at bit i mod 8 of byte i / 8.
This is the order a bit witness already has on the wire, so packing one moves no bits.
The arithmetic is what the field does to one bit, applied to the whole block at once:
a + b -> a XOR b
a * b -> a AND b
a^2 -> aImplementations§
Source§impl<U: Underlier> PackedGf2<U>
impl<U: Underlier> PackedGf2<U>
Sourcepub fn words_mut(&mut self) -> &mut [U::Word]
pub fn words_mut(&mut self) -> &mut [U::Word]
The backing words, lowest lanes first.
Every bit pattern is a valid packing, so writing here cannot break an invariant.
Sourcepub fn count_ones(&self) -> u32
pub fn count_ones(&self) -> u32
How many lanes hold one.
Sourcepub const fn invert_or_zero(self) -> Self
pub const fn invert_or_zero(self) -> Self
The lane-wise inverse, with zero sent to zero.
One is the only invertible element of GF(2) and it is its own inverse.
Extending the map by 0^-1 = 0 therefore makes it the identity on every lane.
Sourcepub fn narrow<V: Underlier>(&self) -> &[PackedGf2<V>]where
U: Divisible<V>,
pub fn narrow<V: Underlier>(&self) -> &[PackedGf2<V>]where
U: Divisible<V>,
This value read as a run of narrower packings, lowest lanes first.
A wide block is narrow ones side by side: lane i is lane i mod w of part i / w.
Sourcepub fn narrow_mut<V: Underlier>(&mut self) -> &mut [PackedGf2<V>]where
U: Divisible<V>,
pub fn narrow_mut<V: Underlier>(&mut self) -> &mut [PackedGf2<V>]where
U: Divisible<V>,
This value read as a run of narrower packings, lowest lanes first.
Sourcepub fn narrow_slice<V: Underlier>(slice: &[Self]) -> &[PackedGf2<V>]where
U: Divisible<V>,
pub fn narrow_slice<V: Underlier>(slice: &[Self]) -> &[PackedGf2<V>]where
U: Divisible<V>,
A run of these packings read as a run of narrower ones, lowest lanes first.
The same bytes carry the same lanes in order, so a narrower read copies nothing.
Sourcepub fn narrow_slice_mut<V: Underlier>(slice: &mut [Self]) -> &mut [PackedGf2<V>]where
U: Divisible<V>,
pub fn narrow_slice_mut<V: Underlier>(slice: &mut [Self]) -> &mut [PackedGf2<V>]where
U: Divisible<V>,
A run of these packings read as a run of narrower ones, lowest lanes first.
Sourcepub const fn as_bytes(slice: &[Self]) -> &[u8] ⓘ
pub const fn as_bytes(slice: &[Self]) -> &[u8] ⓘ
A run of these packings read as bytes, lowest lanes first.
Byte k holds lanes 8k .. 8k + 8, lowest lane at the lowest bit.
Sourcepub fn interleave(&self, other: Self, block_len: usize) -> (Self, Self)
pub fn interleave(&self, other: Self, block_len: usize) -> (Self, Self)
Cut both operands into chunks of block_len lanes and interleave the chunks.
Cut the stack of the two into two-by-two matrices of chunks, and transpose each:
A = [x0, y0, x1, y1]
B = [x2, y2, x3, y3]
block_len = 1 -> ([x0, x2, x1, x3], [y0, y2, y1, y3])A chunk as wide as the value leaves both operands untouched.
This is the convention the packed-field trait fixes. So a caller can swap a bit-sliced packing for any other and see one permutation.
§Panics
Panics unless the chunk length is a power of two no larger than the width.
Trait Implementations§
Source§impl<U: Underlier, T: Into<Self>> AddAssign<T> for PackedGf2<U>
impl<U: Underlier, T: Into<Self>> AddAssign<T> for PackedGf2<U>
Source§fn add_assign(&mut self, rhs: T)
fn add_assign(&mut self, rhs: T)
+= operation. Read moreSource§impl<U: Underlier> Algebra<Gf2> for PackedGf2<U>
impl<U: Underlier> Algebra<Gf2> for PackedGf2<U>
Source§fn quadratic_extension_square(a: &[Self; 2], w: F) -> [Self; 2]
fn quadratic_extension_square(a: &[Self; 2], w: F) -> [Self; 2]
Source§fn mixed_dot_product<const N: usize>(a: &[Self; N], f: &[F; N]) -> Selfwhere
F: Dup,
fn mixed_dot_product<const N: usize>(a: &[Self; N], f: &[F; N]) -> Selfwhere
F: Dup,
Source§const BATCHED_LC_CHUNK: usize = 8
const BATCHED_LC_CHUNK: usize = 8
batched_linear_combination. Read moreimpl<U: Copy + Underlier> Copy for PackedGf2<U>
Source§impl<U: Underlier> Distribution<PackedGf2<U>> for StandardUniform
impl<U: Underlier> Distribution<PackedGf2<U>> for StandardUniform
Source§impl<U: Underlier> DivAssign<Gf2> for PackedGf2<U>
impl<U: Underlier> DivAssign<Gf2> for PackedGf2<U>
Source§fn div_assign(&mut self, rhs: Gf2)
fn div_assign(&mut self, rhs: Gf2)
/= operation. Read moreimpl<U: Eq + Underlier> Eq for PackedGf2<U>
Source§impl<U: Underlier, T: Into<Self>> MulAssign<T> for PackedGf2<U>
impl<U: Underlier, T: Into<Self>> MulAssign<T> for PackedGf2<U>
Source§fn mul_assign(&mut self, rhs: T)
fn mul_assign(&mut self, rhs: T)
*= operation. Read moreSource§impl<U: Underlier> PrimeCharacteristicRing for PackedGf2<U>
impl<U: Underlier> PrimeCharacteristicRing for PackedGf2<U>
Source§fn div_2exp_u64(&self, _exp: u64) -> Self
fn div_2exp_u64(&self, _exp: u64) -> Self
§Panics
Always panics: 2 is not invertible in characteristic 2.
Source§type PrimeSubfield = Gf2
type PrimeSubfield = Gf2
ℤ/p where the characteristic of this ring is p.Source§fn from_prime_subfield(f: Self::PrimeSubfield) -> Self
fn from_prime_subfield(f: Self::PrimeSubfield) -> Self
Source§fn xor(&self, y: &Self) -> Self
fn xor(&self, y: &Self) -> Self
xor. Read moreSource§fn mul_2exp_u64(&self, exp: u64) -> Self
fn mul_2exp_u64(&self, exp: u64) -> Self
mul_2exp_u64(a, exp) = a * 2^{exp}. Read moreSource§fn bool_check(&self) -> Self
fn bool_check(&self) -> Self
x * (x - 1). Read moreSource§fn from_usize(int: usize) -> Self
fn from_usize(int: usize) -> Self
Source§fn from_isize(int: isize) -> Self
fn from_isize(int: isize) -> Self
Source§fn xor3(&self, y: &Self, z: &Self) -> Self
fn xor3(&self, y: &Self, z: &Self) -> Self
xor. Read moreSource§fn exp_const_u64<const POWER: u64>(&self) -> Self
fn exp_const_u64<const POWER: u64>(&self) -> Self
Source§fn exp_power_of_2(&self, power_log: usize) -> Self
fn exp_power_of_2(&self, power_log: usize) -> Self
exp_power_of_2(a, power_log) = a^{2^power_log}. Read moreSource§fn powers(&self) -> Powers<Self> ⓘ
fn powers(&self) -> Powers<Self> ⓘ
self: self^0, self^1, self^2, ....Source§fn shifted_powers(&self, start: Self) -> Powers<Self> ⓘ
fn shifted_powers(&self, start: Self) -> Powers<Self> ⓘ
self shifted by start: start, start*self^1, start*self^2, ....Source§fn 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
Source§fn sum_array<const N: usize>(input: &[Self]) -> Self
fn sum_array<const N: usize>(input: &[Self]) -> Self
Source§fn zero_vec(len: usize) -> Vec<Self>
fn zero_vec(len: usize) -> Vec<Self>
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. Read moreimpl<U: PartialEq + Underlier> StructuralPartialEq for PackedGf2<U>
Auto Trait Implementations§
impl<U> Freeze for PackedGf2<U>where
U: Freeze,
impl<U> RefUnwindSafe for PackedGf2<U>where
U: RefUnwindSafe,
impl<U> Send for PackedGf2<U>
impl<U> Sync for PackedGf2<U>
impl<U> Unpin for PackedGf2<U>where
U: Unpin,
impl<U> UnsafeUnpin for PackedGf2<U>where
U: UnsafeUnpin,
impl<U> UnwindSafe for PackedGf2<U>where
U: UnwindSafe,
Blanket Implementations§
Source§impl<R> Algebra<R> for Rwhere
R: PrimeCharacteristicRing,
impl<R> Algebra<R> for Rwhere
R: PrimeCharacteristicRing,
Source§fn mixed_dot_product<const N: usize>(a: &[R; N], f: &[R; N]) -> R
fn mixed_dot_product<const N: usize>(a: &[R; N], f: &[R; N]) -> R
Source§fn quadratic_extension_square(a: &[Self; 2], w: F) -> [Self; 2]
fn quadratic_extension_square(a: &[Self; 2], w: F) -> [Self; 2]
Source§const BATCHED_LC_CHUNK: usize = 8
const BATCHED_LC_CHUNK: usize = 8
batched_linear_combination. Read moreSource§impl<F> AlgebraIdentity<F> for Fwhere
F: PrimeCharacteristicRing,
impl<F> AlgebraIdentity<F> for Fwhere
F: PrimeCharacteristicRing,
Source§impl<F> BasedVectorSpace<F> for Fwhere
F: PrimeCharacteristicRing,
impl<F> BasedVectorSpace<F> for Fwhere
F: PrimeCharacteristicRing,
Source§const DIMENSION: usize = 1
const DIMENSION: usize = 1
Source§fn as_basis_coefficients_slice(&self) -> &[F]
fn as_basis_coefficients_slice(&self) -> &[F]
A and uses this to
map an element of A to a slice of DIMENSION F elements. Read moreSource§fn from_basis_coefficients_fn<Fn>(f: Fn) -> F
fn from_basis_coefficients_fn<Fn>(f: Fn) -> F
A and uses this to
map DIMENSION F elements to an element of A. Similar
to core:array::from_fn, the DIMENSION F elements are
given by Fn(0), ..., Fn(DIMENSION - 1) called in that order. Read moreSource§fn from_basis_coefficients_iter<I>(iter: I) -> Option<F>where
I: ExactSizeIterator<Item = F>,
fn from_basis_coefficients_iter<I>(iter: I) -> Option<F>where
I: ExactSizeIterator<Item = F>,
A and uses this to
map DIMENSION F elements to an element of A. Read moreSource§fn flatten_to_base(vec: Vec<F>) -> Vec<F>
fn flatten_to_base(vec: Vec<F>) -> Vec<F>
Source§fn reconstitute_from_base(vec: Vec<F>) -> Vec<F>
fn reconstitute_from_base(vec: Vec<F>) -> Vec<F>
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more