use alloc::vec::Vec;
use zeroize::Zeroizing;
fn encode_le_u64(len: usize) -> [u8; 8] {
(len as u64).to_le_bytes()
}
fn append_lv(buf: &mut Vec<u8>, data: &[u8]) {
buf.extend_from_slice(&encode_le_u64(data.len()));
buf.extend_from_slice(data);
}
#[allow(clippy::too_many_arguments)]
pub fn build_transcript(
context: &[u8],
id_prover: &[u8],
id_verifier: &[u8],
m: &[u8],
n: &[u8],
share_p: &[u8],
share_v: &[u8],
z: &[u8],
v: &[u8],
w0: &[u8],
) -> Zeroizing<Vec<u8>> {
let mut tt = Vec::new();
append_lv(&mut tt, context);
append_lv(&mut tt, id_prover);
append_lv(&mut tt, id_verifier);
append_lv(&mut tt, m);
append_lv(&mut tt, n);
append_lv(&mut tt, share_p);
append_lv(&mut tt, share_v);
append_lv(&mut tt, z);
append_lv(&mut tt, v);
append_lv(&mut tt, w0);
Zeroizing::new(tt)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_encode_le_u64() {
assert_eq!(encode_le_u64(0), [0, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(encode_le_u64(1), [1, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(encode_le_u64(256), [0, 1, 0, 0, 0, 0, 0, 0]);
}
#[test]
fn test_append_lv() {
let mut buf = Vec::new();
append_lv(&mut buf, b"test");
assert_eq!(buf.len(), 8 + 4);
assert_eq!(&buf[..8], &[4, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(&buf[8..], b"test");
}
#[test]
fn test_build_transcript_10_fields() {
let tt = build_transcript(
b"ctx", b"P", b"V", b"MM", b"NN", b"sP", b"sV", b"ZZ", b"VV", b"w",
);
assert_eq!(tt.len(), 80 + 18);
}
#[test]
fn test_build_transcript_empty_fields() {
let tt = build_transcript(b"", b"", b"", b"M", b"N", b"", b"", b"", b"", b"");
assert_eq!(tt.len(), 82);
}
#[test]
fn test_transcript_field_order() {
let tt = build_transcript(b"C", b"P", b"V", b"M", b"N", b"sP", b"sV", b"Z", b"V", b"w");
assert_eq!(&tt[0..8], &[1, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(tt[8], b'C');
assert_eq!(&tt[9..17], &[1, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(tt[17], b'P');
}
}