pub struct Shift {
pub variant: ShiftVariant,
pub amount: u8,
}Expand description
One shift: an operation paired with the distance it moves by.
The amount is always below the variant’s max_amount, so a Shift
that exists denotes the same operation wherever it is read.
Every variant is the identity at amount 0, so the amount alone does not fix how the identity is
spelled. Shift::IDENTITY is the canonical spelling, and Self::is_canonical is what says
which spelling a constraint system may carry.
The amount is stored as a byte to keep the struct small: constraint systems hold millions of these.
use binius_core::{constraint_system::Shift, word::Word};
let word = Word::from_u64(0xf0);
assert_eq!(Shift::srl(4).apply(word), Word::from_u64(0x0f));
assert_eq!(Shift::IDENTITY.apply(word), word);
// Every variant is the identity at amount 0, but only one spelling is canonical.
assert!(Shift::rotr(0).is_identity());
assert!(!Shift::rotr(0).is_canonical());Fields§
§variant: ShiftVariantThe operation this shift performs.
amount: u8The number of bits to shift by, below the variant’s upper bound.
Implementations§
Source§impl Shift
impl Shift
Sourcepub const fn new(variant: ShiftVariant, amount: usize) -> Self
pub const fn new(variant: ShiftVariant, amount: usize) -> Self
A shift of amount bits by variant.
§Panics
Panics if the amount is not below the variant’s max_amount:
32 for the half-word (*32) variants, 64 for the rest.
Sourcepub const fn sar(amount: usize) -> Self
pub const fn sar(amount: usize) -> Self
Shift Right Arithmetic.
This is similar to the Shift Right Logical but instead of shifting in 0 bits it will replicate the sign bit.
§Panics
Panics if the shift amount is greater than or equal to 64.
Sourcepub const fn rotr(amount: usize) -> Self
pub const fn rotr(amount: usize) -> Self
Rotate Right.
Rotates bits to the right, with bits shifted off the right end wrapping around to the left.
§Panics
Panics if the shift amount is greater than or equal to 64.
Sourcepub const fn sll32(amount: usize) -> Self
pub const fn sll32(amount: usize) -> Self
Shift Left Logical on 32-bit halves.
Performs independent logical left shifts on the upper and lower 32-bit halves.
§Panics
Panics if the shift amount is greater than or equal to 32.
Sourcepub const fn srl32(amount: usize) -> Self
pub const fn srl32(amount: usize) -> Self
Shift Right Logical on 32-bit halves.
Performs independent logical right shifts on the upper and lower 32-bit halves.
§Panics
Panics if the shift amount is greater than or equal to 32.
Sourcepub const fn sra32(amount: usize) -> Self
pub const fn sra32(amount: usize) -> Self
Shift Right Arithmetic on 32-bit halves.
Performs independent arithmetic right shifts on the upper and lower 32-bit halves, sign extending each half independently.
§Panics
Panics if the shift amount is greater than or equal to 32.
Sourcepub const fn rotr32(amount: usize) -> Self
pub const fn rotr32(amount: usize) -> Self
Rotate Right on 32-bit halves.
Performs independent rotate right operations on the upper and lower 32-bit halves.
§Panics
Panics if the shift amount is greater than or equal to 32.
Sourcepub const fn is_identity(self) -> bool
pub const fn is_identity(self) -> bool
Whether this shift leaves every word untouched.
Every variant is the identity at amount 0, so this holds for more shifts than
Shift::IDENTITY alone.
Sourcepub const fn is_canonical(self) -> bool
pub const fn is_canonical(self) -> bool
Whether this is the canonical spelling of the operation it denotes.
Only the identity has more than one spelling, and Shift::IDENTITY is the one to use.
Constraint systems carry canonical shifts only, so that two terms denoting the same shifted
word compare equal.
Sourcepub const fn index(self) -> usize
pub const fn index(self) -> usize
Where this shift sits in the enumeration of every (variant, amount) spelling.
The variant indexes runs of Word::BITS, and the amount indexes within a run:
[ Sll 0 .. Sll 63 | Slr 0 .. Slr 63 | ... | Rotr32 0 .. Rotr32 63 ]
0 63 64 127 448 511A reduction keying one table entry per spelling addresses it by this index. So does the prover’s multilinear over the same axis pair, which is what lets the two agree.
§Panics
Panics if the amount is not below Word::BITS.
Above it a shift would index into the next variant’s run, sharing an entry with another
shift.
Sourcepub fn apply(self, word: Word) -> Word
pub fn apply(self, word: Word) -> Word
Applies this shift to a word and returns the result.
§Performance
Which operation to run is decided on every call. To shift many words by one fixed shift,
resolve the variant once instead — see ShiftVariant::write_shifted and
ShiftVariant::xor_shifted.
Sourcepub fn compose(inner: Shift, outer: Shift) -> Composition
pub fn compose(inner: Shift, outer: Shift) -> Composition
Classifies the composition of two shifts, outer applied to the result of inner.
This is the merge rule for a shift sequence: it says whether the two collapse to one shift, clear the word, or genuinely need both slots.
Collapsing is not just a matter of adding amounts. Two shifts collapse when the second
continues the first — which happens for more pairs than sharing a variant, since a shift
that has already cleared the sign bit or carried every bit past the halfway point leaves
the next shift nothing to distinguish. chained enumerates those, and degenerate the
cases where one shift has flattened the word past the other’s notice.
Reporting Composition::Pair where a collapse exists would cost a shift slot but never a
wrong answer; the tests check against an independent bit-level model so that does not
happen silently.
§Arguments
inner: the shift applied first.outer: the shift applied to its result.
Trait Implementations§
Source§impl DeserializeBytes for Shift
impl DeserializeBytes for Shift
fn deserialize(read_buf: impl Buf) -> Result<Self, SerializationError>where
Self: Sized,
Source§impl Ord for Shift
impl Ord for Shift
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialOrd for Shift
impl PartialOrd for Shift
Source§impl SerializeBytes for Shift
impl SerializeBytes for Shift
impl Copy for Shift
impl Eq for Shift
impl StructuralPartialEq for Shift
Auto Trait Implementations§
impl Freeze for Shift
impl RefUnwindSafe for Shift
impl Send for Shift
impl Sync for Shift
impl Unpin for Shift
impl UnsafeUnpin for Shift
impl UnwindSafe for Shift
Blanket Implementations§
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,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§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