binius_field/arch/portable/byte_sliced/
underlier.rs

1// Copyright 2025 Irreducible Inc.
2
3use binius_utils::checked_arithmetics::checked_log_2;
4use bytemuck::{Pod, Zeroable};
5use rand::RngCore;
6use subtle::{Choice, ConstantTimeEq};
7
8use crate::underlier::{Random, ScaledUnderlier, UnderlierType};
9
10/// Unerlier for byte-sliced fields. Even though it may seem to be equivalent to
11/// `ScaledUnderlier<U, N>`, it is not. The difference is in order of bytes,
12/// that's why this is a separate type.
13#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
14#[repr(transparent)]
15pub struct ByteSlicedUnderlier<U, const N: usize>(ScaledUnderlier<U, N>);
16
17impl<U: Random, const N: usize> Random for ByteSlicedUnderlier<U, N> {
18	fn random(mut rng: impl RngCore) -> Self {
19		Self(Random::random(&mut rng))
20	}
21}
22
23impl<U: ConstantTimeEq, const N: usize> ConstantTimeEq for ByteSlicedUnderlier<U, N> {
24	fn ct_eq(&self, other: &Self) -> Choice {
25		self.0.ct_eq(&other.0)
26	}
27}
28
29unsafe impl<U: Zeroable, const N: usize> Zeroable for ByteSlicedUnderlier<U, N> {}
30
31unsafe impl<U: Pod, const N: usize> Pod for ByteSlicedUnderlier<U, N> {}
32
33impl<U: UnderlierType + Pod, const N: usize> UnderlierType for ByteSlicedUnderlier<U, N> {
34	const LOG_BITS: usize = U::LOG_BITS + checked_log_2(N);
35}