Skip to main content

binius_field/arch/portable/
scaled_arithmetic.rs

1// Copyright 2025-2026 The Binius Developers
2
3use std::array;
4
5use bytemuck::{Pod, TransparentWrapper};
6
7use super::packed::PackedPrimitiveType;
8use crate::{
9	BinaryField,
10	arch::ScaledStrategy,
11	arithmetic_traits::{InvertOrZero, Square, TaggedInvertOrZero, TaggedMul, TaggedSquare},
12	underlier::{ScaledUnderlier, UnderlierType},
13};
14
15impl<U: UnderlierType + Pod, Scalar: BinaryField, const N: usize> TaggedMul<ScaledStrategy>
16	for PackedPrimitiveType<ScaledUnderlier<U, N>, Scalar>
17where
18	PackedPrimitiveType<U, Scalar>: std::ops::Mul<Output = PackedPrimitiveType<U, Scalar>>,
19{
20	fn mul(self, rhs: Self) -> Self {
21		Self::wrap(ScaledUnderlier(array::from_fn(|i| {
22			let lhs_i = self.0.0[i];
23			let rhs_i = rhs.0.0[i];
24			PackedPrimitiveType::peel(
25				PackedPrimitiveType::wrap(lhs_i) * PackedPrimitiveType::wrap(rhs_i),
26			)
27		})))
28	}
29}
30
31impl<U: UnderlierType + Pod, Scalar: BinaryField, const N: usize> TaggedSquare<ScaledStrategy>
32	for PackedPrimitiveType<ScaledUnderlier<U, N>, Scalar>
33where
34	PackedPrimitiveType<U, Scalar>: Square,
35{
36	fn square(self) -> Self {
37		Self::wrap(ScaledUnderlier(self.0.0.map(|sub_underlier| {
38			PackedPrimitiveType::peel(PackedPrimitiveType::wrap(sub_underlier).square())
39		})))
40	}
41}
42
43impl<U: UnderlierType + Pod, Scalar: BinaryField, const N: usize> TaggedInvertOrZero<ScaledStrategy>
44	for PackedPrimitiveType<ScaledUnderlier<U, N>, Scalar>
45where
46	PackedPrimitiveType<U, Scalar>: InvertOrZero,
47{
48	fn invert_or_zero(self) -> Self {
49		Self::wrap(ScaledUnderlier(self.0.0.map(|sub_underlier| {
50			PackedPrimitiveType::peel(PackedPrimitiveType::wrap(sub_underlier).invert_or_zero())
51		})))
52	}
53}