use crate::errors;
use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::vec::Vec;
use hekate_crypto::Hasher;
use hekate_crypto::transcript::Transcript;
use hekate_math::TowerField;
pub fn absorb_chiplet_header<H: Hasher>(
transcript: &mut Transcript<H>,
name: &str,
num_rows: usize,
num_cols: usize,
root: &[u8; 32],
) {
transcript.append_message(b"chiplet_name", name.as_bytes());
transcript.append_u64(b"chiplet_num_rows", num_rows as u64);
transcript.append_u64(b"chiplet_num_cols", num_cols as u64);
transcript.append_message(b"chiplet_root", root);
}
pub fn absorb_logup_claimed_sums<F, H>(transcript: &mut Transcript<H>, claimed_sums: &[(String, F)])
where
F: TowerField,
H: Hasher,
{
transcript.append_u64(b"logup_claim_count", claimed_sums.len() as u64);
for (bus_id, claim) in claimed_sums {
transcript.append_message(b"logup_claim_bus_id", bus_id.as_bytes());
transcript.append_field(b"logup_claim_sum", *claim);
}
}
pub fn absorb_logup_h_evals<F, H>(transcript: &mut Transcript<H>, h_evals: &[(String, F)])
where
F: TowerField,
H: Hasher,
{
transcript.append_u64(b"logup_h_count", h_evals.len() as u64);
for (bus_id, h_eval) in h_evals {
transcript.append_message(b"logup_h_bus_id", bus_id.as_bytes());
transcript.append_field(b"logup_h_eval", *h_eval);
}
}
pub fn absorb_lookup_bus_heights<H: Hasher>(
transcript: &mut Transcript<H>,
entries: &[(String, u64)],
) {
transcript.append_u64(b"lookup_bus_count", entries.len() as u64);
for (bus_id, n_max) in entries {
transcript.append_message(b"lookup_bus_id", bus_id.as_bytes());
transcript.append_u64(b"lookup_bus_n_max", *n_max);
}
}
pub fn challenge_r_bus<F, H>(
transcript: &mut Transcript<H>,
bus_id: &str,
num_vars: usize,
) -> errors::Result<Vec<F>>
where
F: TowerField,
H: Hasher,
{
transcript.append_message(b"lookup_bus_id", bus_id.as_bytes());
let mut coords = Vec::with_capacity(num_vars);
for _ in 0..num_vars {
coords.push(transcript.challenge_field::<F>(b"r_bus")?);
}
Ok(coords)
}
pub fn draw_lookup_bus_points<F, H>(
transcript: &mut Transcript<H>,
entries: &[(String, u64)],
) -> errors::Result<BTreeMap<String, Vec<F>>>
where
F: TowerField,
H: Hasher,
{
for (_, n_max) in entries {
if *n_max == 0 || !n_max.is_power_of_two() {
return Err(errors::Error::Protocol {
protocol: "transcript",
message: "lookup bus N_max must be a non-zero power of two",
});
}
}
absorb_lookup_bus_heights(transcript, entries);
let mut points = BTreeMap::new();
for (bus_id, n_max) in entries {
let num_vars = n_max.trailing_zeros() as usize;
points.insert(
bus_id.clone(),
challenge_r_bus::<F, H>(transcript, bus_id, num_vars)?,
);
}
Ok(points)
}