binius_core/constraint_system/
values_data.rs1use std::borrow::Cow;
3
4use binius_utils::serialization::{DeserializeBytes, SerializationError, SerializeBytes};
5use bytes::{Buf, BufMut};
6
7use crate::word::Word;
8
9#[derive(Clone, Debug, PartialEq, Eq)]
15pub struct ValuesData<'a> {
16 data: Cow<'a, [Word]>,
17}
18
19impl<'a> ValuesData<'a> {
20 pub const SERIALIZATION_VERSION: u32 = 1;
22
23 pub const fn borrowed(data: &'a [Word]) -> Self {
25 Self {
26 data: Cow::Borrowed(data),
27 }
28 }
29
30 pub const fn owned(data: Vec<Word>) -> Self {
32 Self {
33 data: Cow::Owned(data),
34 }
35 }
36
37 pub fn as_slice(&self) -> &[Word] {
39 &self.data
40 }
41
42 pub fn len(&self) -> usize {
44 self.data.len()
45 }
46
47 pub fn is_empty(&self) -> bool {
49 self.data.is_empty()
50 }
51
52 pub fn into_owned(self) -> Vec<Word> {
54 self.data.into_owned()
55 }
56
57 pub fn to_owned(&self) -> ValuesData<'static> {
59 ValuesData {
60 data: Cow::Owned(self.data.to_vec()),
61 }
62 }
63}
64
65impl<'a> SerializeBytes for ValuesData<'a> {
66 fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
67 Self::SERIALIZATION_VERSION.serialize(&mut write_buf)?;
68
69 self.data.as_ref().serialize(write_buf)
70 }
71}
72
73impl DeserializeBytes for ValuesData<'static> {
74 fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
75 where
76 Self: Sized,
77 {
78 let version = u32::deserialize(&mut read_buf)?;
79 if version != Self::SERIALIZATION_VERSION {
80 return Err(SerializationError::InvalidConstruction {
81 name: "Witness::version",
82 });
83 }
84
85 let data = Vec::<Word>::deserialize(read_buf)?;
86
87 Ok(ValuesData::owned(data))
88 }
89}
90
91impl<'a> From<&'a [Word]> for ValuesData<'a> {
92 fn from(data: &'a [Word]) -> Self {
93 ValuesData::borrowed(data)
94 }
95}
96
97impl From<Vec<Word>> for ValuesData<'static> {
98 fn from(data: Vec<Word>) -> Self {
99 ValuesData::owned(data)
100 }
101}
102
103impl<'a> AsRef<[Word]> for ValuesData<'a> {
104 fn as_ref(&self) -> &[Word] {
105 self.as_slice()
106 }
107}
108
109impl<'a> std::ops::Deref for ValuesData<'a> {
110 type Target = [Word];
111
112 fn deref(&self) -> &Self::Target {
113 self.as_slice()
114 }
115}
116
117impl<'a> From<ValuesData<'a>> for Vec<Word> {
118 fn from(value: ValuesData<'a>) -> Self {
119 value.into_owned()
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn test_witness_serialization_round_trip_owned() {
129 let data = vec![
130 Word::from_u64(1),
131 Word::from_u64(42),
132 Word::from_u64(0xDEADBEEF),
133 Word::from_u64(0x1234567890ABCDEF),
134 ];
135 let witness = ValuesData::owned(data.clone());
136
137 let mut buf = Vec::new();
138 witness.serialize(&mut buf).unwrap();
139
140 let deserialized = ValuesData::deserialize(&mut buf.as_slice()).unwrap();
141 assert_eq!(witness, deserialized);
142 assert_eq!(deserialized.as_slice(), data.as_slice());
143 }
144
145 #[test]
146 fn test_witness_serialization_round_trip_borrowed() {
147 let data = vec![Word::from_u64(123), Word::from_u64(456)];
148 let witness = ValuesData::borrowed(&data);
149
150 let mut buf = Vec::new();
151 witness.serialize(&mut buf).unwrap();
152
153 let deserialized = ValuesData::deserialize(&mut buf.as_slice()).unwrap();
154 assert_eq!(witness, deserialized);
155 assert_eq!(deserialized.as_slice(), data.as_slice());
156 }
157
158 #[test]
159 fn test_witness_version_mismatch() {
160 let mut buf = Vec::new();
161 999u32.serialize(&mut buf).unwrap(); vec![Word::from_u64(1)].serialize(&mut buf).unwrap(); let result = ValuesData::deserialize(&mut buf.as_slice());
165 assert!(result.is_err());
166 match result.unwrap_err() {
167 SerializationError::InvalidConstruction { name } => {
168 assert_eq!(name, "Witness::version");
169 }
170 _ => panic!("Expected version mismatch error"),
171 }
172 }
173
174 #[test]
177 #[ignore] fn create_witness_reference_binary_file() {
179 let data = vec![
180 Word::from_u64(1),
181 Word::from_u64(42),
182 Word::from_u64(0xDEADBEEF),
183 Word::from_u64(0x1234567890ABCDEF),
184 ];
185 let witness = ValuesData::owned(data);
186
187 let mut buf = Vec::new();
188 witness.serialize(&mut buf).unwrap();
189
190 let test_data_path = std::path::Path::new("verifier/core/test_data/witness_v1.bin");
191
192 if let Some(parent) = test_data_path.parent() {
193 std::fs::create_dir_all(parent).unwrap();
194 }
195
196 std::fs::write(test_data_path, &buf).unwrap();
197
198 println!("Created Witness reference binary file at: {:?}", test_data_path);
199 println!("Binary data length: {} bytes", buf.len());
200 }
201
202 #[test]
206 fn test_witness_deserialize_from_reference_binary_file() {
207 let binary_data = include_bytes!("../../test_data/witness_v1.bin");
208
209 let deserialized = ValuesData::deserialize(&mut binary_data.as_slice()).unwrap();
210
211 assert_eq!(deserialized.len(), 4);
212 assert_eq!(deserialized.as_slice()[0].as_u64(), 1);
213 assert_eq!(deserialized.as_slice()[1].as_u64(), 42);
214 assert_eq!(deserialized.as_slice()[2].as_u64(), 0xDEADBEEF);
215 assert_eq!(deserialized.as_slice()[3].as_u64(), 0x1234567890ABCDEF);
216
217 let version_bytes = &binary_data[0..4]; let expected_version_bytes = 1u32.to_le_bytes(); assert_eq!(
223 version_bytes, expected_version_bytes,
224 "WitnessData binary file version mismatch. If you made breaking changes, increment WitnessData::SERIALIZATION_VERSION"
225 );
226 }
227}