binius_field/
extension.rs1use std::{
4 iter,
5 ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign},
6};
7
8use super::{Field, error::Error};
9
10pub trait ExtensionField<F: Field>:
11 Field
12 + From<F>
13 + TryInto<F>
14 + Add<F, Output = Self>
15 + Sub<F, Output = Self>
16 + Mul<F, Output = Self>
17 + AddAssign<F>
18 + SubAssign<F>
19 + MulAssign<F>
20{
21 const LOG_DEGREE: usize;
23
24 const DEGREE: usize = 1 << Self::LOG_DEGREE;
28
29 #[inline]
35 fn basis(i: usize) -> Self {
36 Self::basis_checked(i).expect("pre-condition: 0 <= i < DEGREE")
37 }
38
39 fn basis_checked(i: usize) -> Result<Self, Error>;
48
49 #[inline]
53 fn from_bases(base_elems: impl IntoIterator<Item = F>) -> Result<Self, Error> {
54 Self::from_bases_sparse(base_elems, 0)
55 }
56
57 fn from_bases_sparse(
64 base_elems: impl IntoIterator<Item = F>,
65 log_stride: usize,
66 ) -> Result<Self, Error>;
67
68 fn iter_bases(&self) -> impl Iterator<Item = F>;
70
71 fn into_iter_bases(self) -> impl Iterator<Item = F>;
73
74 #[inline]
76 fn get_base(&self, i: usize) -> F {
77 assert!(i < Self::DEGREE, "index out of bounds");
78 unsafe { self.get_base_unchecked(i) }
79 }
80
81 unsafe fn get_base_unchecked(&self, i: usize) -> F;
86
87 fn square_transpose(values: &mut [Self]) -> Result<(), Error>;
89}
90
91impl<F: Field> ExtensionField<F> for F {
92 const LOG_DEGREE: usize = 0;
93
94 #[inline(always)]
95 fn basis_checked(i: usize) -> Result<Self, Error> {
96 if i != 0 {
97 return Err(Error::ExtensionDegreeMismatch);
98 }
99 Ok(Self::ONE)
100 }
101
102 #[inline(always)]
103 fn from_bases_sparse(
104 base_elems: impl IntoIterator<Item = F>,
105 log_stride: usize,
106 ) -> Result<Self, Error> {
107 let mut base_elems = base_elems.into_iter();
108 if log_stride != 0 {
109 return Err(Error::ExtensionDegreeMismatch);
110 }
111
112 match base_elems.next() {
113 Some(elem) => Ok(elem),
114 None => Ok(Self::ZERO),
115 }
116 }
117
118 #[inline(always)]
119 fn iter_bases(&self) -> impl Iterator<Item = F> {
120 iter::once(*self)
121 }
122
123 #[inline(always)]
124 fn into_iter_bases(self) -> impl Iterator<Item = F> {
125 iter::once(self)
126 }
127
128 #[inline(always)]
129 unsafe fn get_base_unchecked(&self, i: usize) -> F {
130 debug_assert_eq!(i, 0);
131 *self
132 }
133
134 #[inline]
135 fn square_transpose(values: &mut [Self]) -> Result<(), Error> {
136 if values.len() != 1 {
137 return Err(Error::MismatchedLengths);
138 }
139
140 Ok(())
141 }
142}