use super::code::{LinearCode, ReedSolomon};
use super::linear_form::LinearFormHandle;
use crate::field::Goldilocks4;
pub(crate) trait TransposeCode: LinearCode {
fn apply_transpose(&self, input: &[Self::Alphabet]) -> Vec<Self::Alphabet>;
}
impl TransposeCode for ReedSolomon<Goldilocks4> {
fn apply_transpose(&self, input: &[Goldilocks4]) -> Vec<Goldilocks4> {
assert_eq!(input.len(), self.codeword_len);
let ntt_out = Goldilocks4::ntt(input.to_vec());
ntt_out.into_iter().take(self.msg_len).collect()
}
}
pub(crate) trait CodeswitchHandle: LinearCode {
type TransposeHandle: LinearFormHandle<Alphabet = Self::Alphabet>;
fn apply_transpose_handle(&self, index: usize) -> Self::TransposeHandle;
}
pub(crate) struct ReedSolomonTransposeHandle {
coefficients: Vec<Goldilocks4>,
}
impl LinearFormHandle for ReedSolomonTransposeHandle {
type Alphabet = Goldilocks4;
fn form_size(&self) -> usize {
self.coefficients.len()
}
fn folded_form(&self, rand: &[Goldilocks4]) -> Vec<Goldilocks4> {
assert!(
self.coefficients.len().is_power_of_two(),
"ReedSolomonTransposeHandle: coefficient length must be a power of two"
);
assert!(
rand.len() <= self.coefficients.len().ilog2() as usize,
"ReedSolomonTransposeHandle: too many fold challenges"
);
let mut values = self.coefficients.clone();
for &w in rand {
let half = values.len() / 2;
values = (0..half)
.map(|k| values[k] + (values[k + half] - values[k]) * w)
.collect();
}
values
}
}
impl CodeswitchHandle for ReedSolomon<Goldilocks4> {
type TransposeHandle = ReedSolomonTransposeHandle;
fn apply_transpose_handle(&self, index: usize) -> Self::TransposeHandle {
assert!(
index < self.codeword_len,
"ReedSolomon::apply_transpose_handle: index {index} >= codeword_len {}",
self.codeword_len
);
let log_n = self.codeword_len.trailing_zeros() as usize;
let omega = Goldilocks4::two_adic_generator(log_n);
let point = omega.pow(index as u64);
let mut coefficients = Vec::with_capacity(self.msg_len);
let mut p = Goldilocks4::ONE;
for _ in 0..self.msg_len {
coefficients.push(p);
p *= point;
}
ReedSolomonTransposeHandle { coefficients }
}
}