binius_field/
as_packed_field.rs

1// Copyright 2024-2025 Irreducible Inc.
2
3use crate::{
4	BinaryField128bGhash, ExtensionField, Field, PackedBinaryGhash1x128b, PackedField,
5	aes_field::*,
6	arch::{packed_1::*, packed_aes_8::*},
7	binary_field::*,
8	underlier::{UnderlierType, WithUnderlier},
9};
10
11/// Trait that establishes correspondence between the scalar field and a packed field of the same
12/// bit size with a single element.
13///
14/// E.g. `BinaryField64b` -> `PackedBinaryField1x64b`.
15/// Note that the underlier of the packed field may be different.
16/// E.g. `BinaryField128b` has u128 as underlier, while for x64 `PackedBinaryField1x128b`'s
17/// underlier may be `M128`.
18pub trait AsSinglePacked: Field {
19	type Packed: PackedField<Scalar = Self>
20		+ WithUnderlier<Underlier: From<Self::Underlier> + Into<Self::Underlier>>;
21
22	fn to_single_packed(self) -> Self::Packed {
23		assert_eq!(Self::Packed::WIDTH, 1);
24
25		Self::Packed::set_single(self)
26	}
27
28	fn from_single_packed(value: Self::Packed) -> Self {
29		assert_eq!(Self::Packed::WIDTH, 1);
30
31		value.get(0)
32	}
33}
34
35macro_rules! impl_as_single_packed_field {
36	($field:ty, $packed_field:ty) => {
37		impl AsSinglePacked for $field {
38			type Packed = $packed_field;
39		}
40	};
41}
42
43impl_as_single_packed_field!(BinaryField1b, PackedBinaryField1x1b);
44impl_as_single_packed_field!(AESTowerField8b, PackedAESBinaryField1x8b);
45impl_as_single_packed_field!(BinaryField128bGhash, PackedBinaryGhash1x128b);
46
47/// This trait represents correspondence (UnderlierType, Field) -> PackedField.
48/// For example (u64, BinaryField16b) -> PackedBinaryField4x16b.
49pub trait PackScalar<F: Field>: UnderlierType {
50	type Packed: PackedField<Scalar = F> + WithUnderlier<Underlier = Self>;
51}
52
53/// Returns the packed field type for the scalar field `F` and underlier `U`.
54pub type PackedType<U, F> = <U as PackScalar<F>>::Packed;
55
56/// A trait to convert field to a same bit size packed field with some smaller scalar.
57pub(crate) trait AsPackedField<Scalar: Field>: Field
58where
59	Self: ExtensionField<Scalar>,
60{
61	type Packed: PackedField<Scalar = Scalar>
62		+ WithUnderlier<Underlier: From<Self::Underlier> + Into<Self::Underlier>>;
63}
64
65impl<Scalar, F> AsPackedField<Scalar> for F
66where
67	F: Field
68		+ WithUnderlier<Underlier: PackScalar<Scalar>>
69		+ AsSinglePacked
70		+ ExtensionField<Scalar>,
71	Scalar: Field,
72{
73	type Packed = <Self::Underlier as PackScalar<Scalar>>::Packed;
74}