use core::ops::{Index, Mul, Range};
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use hybrid_array::{Array, ArraySize, typenum::U8};
use crate::{
fields::BigGaloisField,
utils::{array_ref, get_bit},
};
#[derive(Debug, Clone)]
pub(crate) struct VoleCommits<'a, F: BigGaloisField, L: ArraySize> {
pub(crate) scalars: Box<Array<F, L>>,
pub(crate) delta: &'a F,
}
impl<'a, F, L> VoleCommits<'a, F, L>
where
F: BigGaloisField,
L: ArraySize,
{
pub(crate) fn from_constant<L2>(input: &Array<u8, L>, delta: &'a F) -> VoleCommits<'a, F, L2>
where
L: ArraySize + Mul<U8, Output = L2>,
L2: ArraySize,
{
let scalars = Box::new(<Array<F, L2>>::from_iter(
(0..L2::USIZE).map(|i| *delta * get_bit(input, i)),
));
VoleCommits { scalars, delta }
}
pub(crate) fn to_ref(&self) -> VoleCommitsRef<'_, F, L> {
VoleCommitsRef {
scalars: &self.scalars,
delta: self.delta,
}
}
pub(crate) fn get_commits_ref<L2>(&self, start_idx: usize) -> VoleCommitsRef<'_, F, L2>
where
L2: ArraySize,
{
VoleCommitsRef {
scalars: array_ref(&self.scalars[start_idx..start_idx + L2::USIZE]),
delta: self.delta,
}
}
pub(crate) fn get_field_commit(&self, idx: usize) -> F {
debug_assert!(idx * 8 + 8 <= L::USIZE);
F::byte_combine_slice(&self.scalars[8 * idx..8 * idx + 8])
}
pub(crate) fn get_field_commit_sq(&self, idx: usize) -> F {
debug_assert!(idx * 8 + 8 <= L::USIZE);
F::byte_combine_sq_slice(&self.scalars[8 * idx..8 * idx + 8])
}
}
#[derive(Debug, Copy, Clone)]
pub(crate) struct VoleCommitsRef<'a, F: BigGaloisField, L: ArraySize> {
pub(crate) scalars: &'a Array<F, L>,
pub(crate) delta: &'a F,
}
impl<'a, F, L> VoleCommitsRef<'a, F, L>
where
F: BigGaloisField,
L: ArraySize,
{
pub(crate) fn get_commits_ref<L2>(&self, start_idx: usize) -> VoleCommitsRef<'a, F, L2>
where
L2: ArraySize,
{
VoleCommitsRef {
scalars: array_ref(&self.scalars[start_idx..start_idx + L2::USIZE]),
delta: self.delta,
}
}
}
impl<F, L> Index<usize> for VoleCommits<'_, F, L>
where
F: BigGaloisField,
L: ArraySize,
{
type Output = F;
fn index(&self, index: usize) -> &Self::Output {
&self.scalars[index]
}
}
impl<F, L> Index<Range<usize>> for VoleCommits<'_, F, L>
where
F: BigGaloisField,
L: ArraySize,
{
type Output = [F];
fn index(&self, index: Range<usize>) -> &Self::Output {
&self.scalars[index]
}
}
impl<F, L> Index<usize> for VoleCommitsRef<'_, F, L>
where
F: BigGaloisField,
L: ArraySize,
{
type Output = F;
fn index(&self, index: usize) -> &Self::Output {
&self.scalars[index]
}
}
impl<F, L> Index<Range<usize>> for VoleCommitsRef<'_, F, L>
where
F: BigGaloisField,
L: ArraySize,
{
type Output = [F];
fn index(&self, index: Range<usize>) -> &Self::Output {
&self.scalars[index]
}
}
impl<F, L> AsRef<Array<F, L>> for VoleCommits<'_, F, L>
where
F: BigGaloisField,
L: ArraySize,
{
fn as_ref(&self) -> &Array<F, L> {
&self.scalars
}
}