Skip to main content

binius_transcript/fiat_shamir/
buffer.rs

1// Copyright 2024-2025 Irreducible Inc.
2
3use std::slice;
4
5use bytes::{Buf, BufMut, buf::UninitSlice};
6
7use super::Challenger;
8
9#[derive(Debug, Default, Clone)]
10pub struct FiatShamirBuf<Inner, Challenger> {
11	pub buffer: Inner,
12	pub challenger: Challenger,
13}
14
15impl<Inner: Buf, Challenger_: Challenger> Buf for FiatShamirBuf<Inner, Challenger_> {
16	fn remaining(&self) -> usize {
17		self.buffer.remaining()
18	}
19
20	fn chunk(&self) -> &[u8] {
21		self.buffer.chunk()
22	}
23
24	fn advance(&mut self, cnt: usize) {
25		assert!(cnt <= self.buffer.remaining());
26		// Get the slice that was written to the inner buf, observe that and advance
27		let readable = self.buffer.chunk();
28		// Because our internal buffer is created from vec, this should never happen.
29		assert!(cnt <= readable.len());
30		self.challenger.observer().put_slice(&readable[..cnt]);
31		self.buffer.advance(cnt);
32	}
33}
34
35unsafe impl<Inner: BufMut, Challenger_: Challenger> BufMut for FiatShamirBuf<Inner, Challenger_> {
36	fn remaining_mut(&self) -> usize {
37		self.buffer.remaining_mut()
38	}
39
40	unsafe fn advance_mut(&mut self, cnt: usize) {
41		assert!(cnt <= self.buffer.remaining_mut());
42		let written = self.buffer.chunk_mut();
43		// Because out internal buffer is BytesMut cnt <= written.len(), but adding as per
44		// implementation notes
45		assert!(cnt <= written.len());
46
47		// NOTE: This is the unsafe part, you are reading the next cnt bytes on the assumption that
48		// caller has ensured us the next cnt bytes are initialized.
49		let written: &[u8] = unsafe { slice::from_raw_parts(written.as_mut_ptr(), cnt) };
50
51		self.challenger.observer().put_slice(written);
52		unsafe {
53			self.buffer.advance_mut(cnt);
54		}
55	}
56
57	fn chunk_mut(&mut self) -> &mut UninitSlice {
58		self.buffer.chunk_mut()
59	}
60}