1use core::fmt::Error;
7
8use super::Hashable;
9use alloc::{vec, vec::Vec};
10use ark_ff::{BigInteger, PrimeField};
11use bitvec::{prelude::*, view::AsBits};
12use mina_curves::pasta::{Fp, Fq};
13use o1_utils::FieldHelpers;
14
15const SER_HEADER_SIZE: usize = 8; const SINGLE_HEADER_SIZE: usize = 4; #[derive(Default, Debug, Clone, PartialEq, Eq)]
62pub struct ROInput {
63 fields: Vec<Fp>,
64 bits: BitVec<u8>,
65}
66
67impl ROInput {
68 pub fn new() -> Self {
70 ROInput {
71 fields: vec![],
72 bits: BitVec::new(),
73 }
74 }
75
76 pub fn append_hashable(self, input: &impl Hashable) -> Self {
78 self.append_roinput(input.to_roinput())
79 }
80
81 pub fn append_roinput(mut self, mut roi: ROInput) -> Self {
83 self.fields.append(&mut roi.fields);
84 self.bits.extend(roi.bits);
85 self
86 }
87
88 pub fn append_field(mut self, f: Fp) -> Self {
90 self.fields.push(f);
91 self
92 }
93
94 pub fn append_scalar(mut self, s: Fq) -> Self {
96 let bytes = s.to_bytes();
98 let bits = &bytes.as_bits::<Lsb0>()[..Fq::MODULUS_BIT_SIZE as usize];
99 self.bits.extend(bits);
100 self
101 }
102
103 pub fn append_bool(mut self, b: bool) -> Self {
105 self.bits.push(b);
106 self
107 }
108
109 pub fn append_bytes(mut self, bytes: &[u8]) -> Self {
111 self.bits.extend_from_bitslice(bytes.as_bits::<Lsb0>());
112 self
113 }
114
115 pub fn append_u32(self, x: u32) -> Self {
117 self.append_bytes(&x.to_le_bytes())
118 }
119
120 pub fn append_u64(self, x: u64) -> Self {
122 self.append_bytes(&x.to_le_bytes())
123 }
124
125 pub fn to_bytes(&self) -> Vec<u8> {
127 let mut bits: BitVec<u8> = self.fields.iter().fold(BitVec::new(), |mut acc, fe| {
128 acc.extend_from_bitslice(
129 &fe.to_bytes().as_bits::<Lsb0>()[..Fp::MODULUS_BIT_SIZE as usize],
130 );
131
132 acc
133 });
134
135 bits.extend(&self.bits);
136
137 bits.into()
138 }
139
140 pub fn to_fields(&self) -> Vec<Fp> {
142 let mut fields: Vec<Fp> = self.fields.clone();
143
144 let bits_as_fields =
145 self.bits
146 .chunks(Fp::MODULUS_BIT_SIZE as usize - 1)
147 .fold(vec![], |mut acc, chunk| {
148 let mut bv = BitVec::<u8>::new();
162 bv.resize(chunk.len(), false);
163 bv.clone_from_bitslice(chunk);
164
165 bv.resize(Fp::MODULUS_BIT_SIZE as usize, false);
167
168 acc.push(
169 Fp::from_bytes(&bv.into_vec())
170 .expect("failed to create base field element"),
171 );
172
173 acc
174 });
175
176 fields.extend(bits_as_fields);
177
178 fields
179 }
180
181 pub fn serialize(&self) -> Vec<u8> {
183 let fields_len = self.fields.len() as u32;
185 let bits_len = self.bits.len() as u32;
186
187 let mut bytes = Vec::with_capacity(SER_HEADER_SIZE + self.to_bytes().len());
188 bytes.extend_from_slice(&fields_len.to_le_bytes());
189 bytes.extend_from_slice(&bits_len.to_le_bytes());
190 bytes.extend_from_slice(&self.to_bytes());
191 bytes
192 }
193
194 pub fn deserialize(input: &[u8]) -> Result<Self, Error> {
196 if input.len() < SER_HEADER_SIZE {
197 return Err(Error);
198 }
199
200 let fields_len =
202 u32::from_le_bytes(input[0..SINGLE_HEADER_SIZE].try_into().unwrap()) as usize;
203 let bits_len = u32::from_le_bytes(
204 input[SINGLE_HEADER_SIZE..SER_HEADER_SIZE]
205 .try_into()
206 .unwrap(),
207 ) as usize;
208
209 let bits = input[SER_HEADER_SIZE..].view_bits::<Lsb0>();
211
212 let expected_len_bits = fields_len * Fp::MODULUS_BIT_SIZE as usize + bits_len;
214 let expected_len = (expected_len_bits + 7) / 8 + SER_HEADER_SIZE;
216 if input.len() != expected_len {
217 return Err(Error);
218 }
219
220 let mut fields = Vec::with_capacity(fields_len);
222
223 for chunk in bits.chunks(Fp::MODULUS_BIT_SIZE as usize).take(fields_len) {
224 let bools: Vec<bool> = chunk.iter().by_vals().collect();
225 let repr = <Fp as PrimeField>::BigInt::from_bits_le(&bools);
227 let elt = Fp::from_bigint(repr).ok_or(Error)?;
229 fields.push(elt);
230 }
231
232 let remainder = &bits[fields_len * Fp::MODULUS_BIT_SIZE as usize..];
233 let bits = remainder.iter().take(bits_len).collect::<BitVec<u8>>();
235
236 let roi = ROInput { fields, bits };
237
238 Ok(roi)
239 }
240}
241
242#[cfg(test)]
243mod tests {
244 use super::*;
245 use crate::{
246 alloc::string::{String, ToString},
247 Hashable,
248 };
249
250 #[test]
251 fn append_bool() {
252 let roi = ROInput::new().append_bool(true);
253 assert!(roi.bits.len() == 1);
254 assert!(roi.bits.as_raw_slice() == [0x01]);
255 }
256
257 #[test]
258 fn append_two_bits() {
259 let roi = ROInput::new().append_bool(false).append_bool(true);
260 assert!(roi.bits.len() == 2);
261 assert!(roi.bits.as_raw_slice() == [0x02]);
262 }
263
264 #[test]
265 fn append_five_bits() {
266 let roi = ROInput::new()
267 .append_bool(false)
268 .append_bool(true)
269 .append_bool(false)
270 .append_bool(false)
271 .append_bool(true);
272 assert!(roi.bits.len() == 5);
273 assert!(roi.bits.as_raw_slice() == [0x12]);
274 }
275
276 #[test]
277 fn append_byte() {
278 let roi = ROInput::new().append_bytes(&[0x01]);
279 assert!(roi.bits.len() == 8);
280 assert!(roi.bits.as_raw_slice() == [0x01]);
281 }
282
283 #[test]
284 fn append_two_bytes() {
285 let roi = ROInput::new().append_bytes(&[0x10, 0xac]);
286 assert!(roi.bits.len() == 16);
287 assert!(roi.bits.as_raw_slice() == [0x10, 0xac]);
288 }
289
290 #[test]
291 fn append_five_bytes() {
292 let roi = ROInput::new().append_bytes(&[0x10, 0xac, 0x01, 0xeb, 0xca]);
293 assert!(roi.bits.len() == 40);
294 assert!(roi.bits.as_raw_slice() == [0x10, 0xac, 0x01, 0xeb, 0xca]);
295 }
296
297 #[test]
298 fn append_scalar() {
299 let scalar =
300 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
301 .expect("failed to create scalar");
302 let roi = ROInput::new().append_scalar(scalar);
303 assert_eq!(roi.bits.len(), 255);
304 assert_eq!(
305 roi.bits.as_raw_slice(),
306 [
307 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa, 0x28,
308 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5, 0xdd, 0x6f,
309 0x17, 0x44, 0x42, 0x16
310 ]
311 );
312 assert_eq!(
313 roi.to_bytes(),
314 [
315 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa, 0x28,
316 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5, 0xdd, 0x6f,
317 0x17, 0x44, 0x42, 0x16
318 ]
319 );
320 }
321
322 #[test]
323 fn append_scalar_and_byte() {
324 let scalar =
325 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
326 .expect("failed to create scalar");
327 let roi = ROInput::new().append_scalar(scalar).append_bytes(&[0x01]);
328 assert!(roi.bits.len() == 263);
329 assert!(
330 roi.bits.as_raw_slice()
331 == [
332 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa,
333 0x28, 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5,
334 0xdd, 0x6f, 0x17, 0x44, 0x42, 0x96, 0x00
335 ]
336 );
337 }
338
339 #[test]
340 fn append_two_scalars() {
341 let scalar1 =
342 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
343 .expect("failed to create scalar");
344 let scalar2 =
345 Fq::from_hex("a1b1e948835be341277548134e0effabdbcb95b742e8c5e967e9bf13eb4ae805")
346 .expect("failed to create scalar");
347 let roi = ROInput::new().append_scalar(scalar1).append_scalar(scalar2);
348 assert!(roi.bits.len() == 510);
349 assert!(
350 roi.bits.as_raw_slice()
351 == [
352 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa,
353 0x28, 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5,
354 0xdd, 0x6f, 0x17, 0x44, 0x42, 0x96, 0xd0, 0xd8, 0x74, 0xa4, 0xc1, 0xad, 0xf1,
355 0xa0, 0x93, 0x3a, 0xa4, 0x09, 0x27, 0x87, 0xff, 0xd5, 0xed, 0xe5, 0xca, 0x5b,
356 0x21, 0xf4, 0xe2, 0xf4, 0xb3, 0xf4, 0xdf, 0x89, 0x75, 0x25, 0xf4, 0x02
357 ]
358 );
359 }
360
361 #[test]
362 fn append_two_scalars_and_byte() {
363 let scalar1 =
364 Fq::from_hex("60db6f4f5b8ce1c7cb747fba9e324cc3268c7a6e3f43cd82d451ae99a7b2bd1f")
365 .expect("failed to create scalar");
366 let scalar2 =
367 Fq::from_hex("fe7775b106bceb58f3e23e5a4eb99f404b8ed8cf2afeef9c9d1800f12138cd07")
368 .expect("failed to create scalar");
369 let roi = ROInput::new()
370 .append_scalar(scalar1)
371 .append_bytes(&[0x2a])
372 .append_scalar(scalar2);
373 assert!(roi.bits.len() == 518);
374 assert!(
375 roi.bits.as_raw_slice()
376 == [
377 0x60, 0xdb, 0x6f, 0x4f, 0x5b, 0x8c, 0xe1, 0xc7, 0xcb, 0x74, 0x7f, 0xba, 0x9e,
378 0x32, 0x4c, 0xc3, 0x26, 0x8c, 0x7a, 0x6e, 0x3f, 0x43, 0xcd, 0x82, 0xd4, 0x51,
379 0xae, 0x99, 0xa7, 0xb2, 0xbd, 0x1f, 0x15, 0xff, 0xbb, 0xba, 0x58, 0x03, 0xde,
380 0x75, 0xac, 0x79, 0x71, 0x1f, 0x2d, 0xa7, 0xdc, 0x4f, 0xa0, 0x25, 0x47, 0xec,
381 0x67, 0x15, 0xff, 0x77, 0xce, 0x4e, 0x0c, 0x80, 0xf8, 0x10, 0x9c, 0xe6, 0x03
382 ]
383 );
384 }
385
386 #[test]
387 fn append_u32() {
388 let roi = ROInput::new().append_u32(1984u32);
389 assert!(roi.bits.len() == 32);
390 assert!(roi.bits.as_raw_slice() == [0xc0, 0x07, 0x00, 0x00]);
391 }
392
393 #[test]
394 fn append_two_u32_and_bit() {
395 let roi = ROInput::new()
396 .append_u32(1729u32)
397 .append_bool(false)
398 .append_u32(u32::MAX);
399 assert!(roi.bits.len() == 65);
400 assert!(roi.bits.as_raw_slice() == [0xc1, 0x06, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01]);
401 }
402
403 #[test]
404 fn append_u64() {
405 let roi = ROInput::new().append_u64(6174u64);
406 assert!(roi.bits.len() == 64);
407 assert!(roi.bits.as_raw_slice() == [0x1e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
408 }
409
410 #[test]
411 fn append_two_u64_and_bits() {
412 let roi = ROInput::new()
413 .append_bool(true)
414 .append_u64(u64::MAX / 6174u64)
415 .append_bool(false)
416 .append_u64(u64::MAX / 1111u64);
417 assert!(roi.bits.len() == 130);
418 assert!(
419 roi.bits.as_raw_slice()
420 == [
421 0xe1, 0x29, 0x89, 0xd6, 0xcb, 0x3a, 0x15, 0x00, 0x08, 0x17, 0xc4, 0x9b, 0x04,
422 0xf4, 0xeb, 0x00, 0x00
423 ]
424 );
425 }
426
427 #[test]
428 fn all_1() {
429 let roi = ROInput::new()
430 .append_bool(true)
431 .append_scalar(
432 Fq::from_hex("01d1755db21c8cd2a9cf5a3436178da3d70f484cd4b4c8834b799921e7d7a102")
433 .expect("failed to create scalar"),
434 )
435 .append_u64(18446744073709551557)
436 .append_bytes(&[0xba, 0xdc, 0x0f, 0xfe])
437 .append_scalar(
438 Fq::from_hex("e70187e9b125524489d0433da76fd8287fa652eaebde147b45fa0cd86f171810")
439 .expect("failed to create scalar"),
440 )
441 .append_bool(false)
442 .append_u32(2147483647)
443 .append_bool(true);
444
445 assert!(roi.bits.len() == 641);
446 assert!(
447 roi.bits.as_raw_slice()
448 == [
449 0x03, 0xa2, 0xeb, 0xba, 0x64, 0x39, 0x18, 0xa5, 0x53, 0x9f, 0xb5, 0x68, 0x6c,
450 0x2e, 0x1a, 0x47, 0xaf, 0x1f, 0x90, 0x98, 0xa8, 0x69, 0x91, 0x07, 0x97, 0xf2,
451 0x32, 0x43, 0xce, 0xaf, 0x43, 0x05, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
452 0xff, 0xba, 0xdc, 0x0f, 0xfe, 0xe7, 0x01, 0x87, 0xe9, 0xb1, 0x25, 0x52, 0x44,
453 0x89, 0xd0, 0x43, 0x3d, 0xa7, 0x6f, 0xd8, 0x28, 0x7f, 0xa6, 0x52, 0xea, 0xeb,
454 0xde, 0x14, 0x7b, 0x45, 0xfa, 0x0c, 0xd8, 0x6f, 0x17, 0x18, 0x10, 0xff, 0xff,
455 0xff, 0x7f, 0x01
456 ]
457 );
458 }
459
460 #[test]
461 fn transaction_bits() {
462 let roi = ROInput::new()
463 .append_u64(1000000) .append_u64(1) .append_bool(true) .append_u32(0) .append_u32(u32::MAX) .append_bytes(&[0; 34]) .append_bool(false) .append_bool(false) .append_bool(false) .append_bool(true) .append_bool(false) .append_u64(1) .append_u64(10000000000) .append_bool(false) .append_scalar(
478 Fq::from_hex("de217a3017ca0b7a278e75f63c09890e3894be532d8dbadd30a7d450055f6d2d")
479 .expect("failed to create scalar"),
480 )
481 .append_bytes(&[0x01]);
482 assert_eq!(roi.bits.len(), 862);
483 assert_eq!(
484 roi.bits.as_raw_slice(),
485 [
486 0x40, 0x42, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
487 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x02,
491 0x95, 0x00, 0x00, 0x00, 0x00, 0xef, 0x10, 0x3d, 0x98, 0x0b, 0xe5, 0x05, 0xbd, 0x13,
492 0xc7, 0x3a, 0x7b, 0x9e, 0x84, 0x44, 0x07, 0x1c, 0x4a, 0xdf, 0xa9, 0x96, 0x46, 0xdd,
493 0x6e, 0x98, 0x53, 0x6a, 0xa8, 0x82, 0xaf, 0xb6, 0x56, 0x00
494 ]
495 )
496 }
497
498 #[test]
499 fn append_field() {
500 let roi = ROInput::new().append_field(
501 Fp::from_hex("2eaedae42a7461d5952d27b97ecad068b698ebb94e8a0e4c45388bb613de7e08")
502 .expect("failed to create field"),
503 );
504
505 assert_eq!(
506 roi.to_bytes(),
507 [
508 0x2e, 0xae, 0xda, 0xe4, 0x2a, 0x74, 0x61, 0xd5, 0x95, 0x2d, 0x27, 0xb9, 0x7e, 0xca,
509 0xd0, 0x68, 0xb6, 0x98, 0xeb, 0xb9, 0x4e, 0x8a, 0x0e, 0x4c, 0x45, 0x38, 0x8b, 0xb6,
510 0x13, 0xde, 0x7e, 0x08
511 ]
512 );
513 }
514
515 #[test]
516 fn append_two_fields() {
517 let roi = ROInput::new()
518 .append_field(
519 Fp::from_hex("0cdaf334e9632268a5aa959c2781fb32bf45565fe244ae42c849d3fdc7c6441d")
520 .expect("failed to create field"),
521 )
522 .append_field(
523 Fp::from_hex("2eaedae42a7461d5952d27b97ecad068b698ebb94e8a0e4c45388bb613de7e08")
524 .expect("failed to create field"),
525 );
526
527 assert_eq!(
528 roi.to_bytes(),
529 [
530 0x0c, 0xda, 0xf3, 0x34, 0xe9, 0x63, 0x22, 0x68, 0xa5, 0xaa, 0x95, 0x9c, 0x27, 0x81,
531 0xfb, 0x32, 0xbf, 0x45, 0x56, 0x5f, 0xe2, 0x44, 0xae, 0x42, 0xc8, 0x49, 0xd3, 0xfd,
532 0xc7, 0xc6, 0x44, 0x1d, 0x17, 0x57, 0x6d, 0x72, 0x15, 0xba, 0xb0, 0xea, 0xca, 0x96,
533 0x93, 0x5c, 0x3f, 0x65, 0x68, 0x34, 0x5b, 0xcc, 0xf5, 0x5c, 0x27, 0x45, 0x07, 0xa6,
534 0x22, 0x9c, 0x45, 0xdb, 0x09, 0x6f, 0x3f, 0x04
535 ]
536 );
537 }
538
539 #[test]
540 fn append_three_fields() {
541 let roi = ROInput::new()
542 .append_field(
543 Fp::from_hex("1f3f142986041b54427aa2032632e34df2fa9bde9bce70c04c5034266619e529")
544 .expect("failed to create field"),
545 )
546 .append_field(
547 Fp::from_hex("37f4433b85e753a91a1d79751645f1448954c433f9492e36a933ca7f3df61a04")
548 .expect("failed to create field"),
549 )
550 .append_field(
551 Fp::from_hex("6cf4772d3e1aab98a2b514b73a4f6e0df1fb4f703ecfa762196b22c26da4341c")
552 .expect("failed to create field"),
553 );
554
555 assert_eq!(
556 roi.to_bytes(),
557 [
558 0x1f, 0x3f, 0x14, 0x29, 0x86, 0x04, 0x1b, 0x54, 0x42, 0x7a, 0xa2, 0x03, 0x26, 0x32,
559 0xe3, 0x4d, 0xf2, 0xfa, 0x9b, 0xde, 0x9b, 0xce, 0x70, 0xc0, 0x4c, 0x50, 0x34, 0x26,
560 0x66, 0x19, 0xe5, 0xa9, 0x1b, 0xfa, 0xa1, 0x9d, 0xc2, 0xf3, 0xa9, 0x54, 0x8d, 0x8e,
561 0xbc, 0x3a, 0x8b, 0xa2, 0x78, 0xa2, 0x44, 0x2a, 0xe2, 0x99, 0xfc, 0x24, 0x17, 0x9b,
562 0xd4, 0x19, 0xe5, 0xbf, 0x1e, 0x7b, 0x0d, 0x02, 0x1b, 0xfd, 0x5d, 0x8b, 0x8f, 0xc6,
563 0x2a, 0xa6, 0x68, 0x2d, 0xc5, 0xad, 0xce, 0x93, 0x5b, 0x43, 0xfc, 0xfe, 0x13, 0x9c,
564 0xcf, 0xf3, 0xa9, 0x58, 0xc6, 0x9a, 0x88, 0x70, 0x1b, 0x29, 0x0d, 0x07
565 ]
566 );
567 }
568
569 #[test]
570 fn append_field_and_scalar() {
571 let roi = ROInput::new()
572 .append_field(
573 Fp::from_hex("64cde530327a36fcb88b6d769adca9b7c5d266e7d0042482203f3fd3a0d71721")
574 .expect("failed to create field"),
575 )
576 .append_scalar(
577 Fq::from_hex("604355d0daa455db783fd7ee11c5bd9b04d67ba64c27c95bef95e379f98c6432")
578 .expect("failed to create scalar"),
579 );
580
581 assert_eq!(
582 roi.to_bytes(),
583 [
584 0x64, 0xcd, 0xe5, 0x30, 0x32, 0x7a, 0x36, 0xfc, 0xb8, 0x8b, 0x6d, 0x76, 0x9a, 0xdc,
585 0xa9, 0xb7, 0xc5, 0xd2, 0x66, 0xe7, 0xd0, 0x04, 0x24, 0x82, 0x20, 0x3f, 0x3f, 0xd3,
586 0xa0, 0xd7, 0x17, 0x21, 0xb0, 0xa1, 0x2a, 0x68, 0x6d, 0xd2, 0xaa, 0x6d, 0xbc, 0x9f,
587 0x6b, 0xf7, 0x88, 0xe2, 0xde, 0x4d, 0x02, 0xeb, 0x3d, 0x53, 0xa6, 0x93, 0xe4, 0xad,
588 0xf7, 0xca, 0xf1, 0xbc, 0x7c, 0x46, 0x32, 0x19
589 ]
590 );
591 }
592
593 #[test]
594 fn append_field_bit_and_scalar() {
595 let roi = ROInput::new()
596 .append_field(
597 Fp::from_hex("d897c7a8b811d8acd3eeaa4adf42292802eed80031c2ad7c8989aea1fe94322c")
598 .expect("failed to create field"),
599 )
600 .append_bool(false)
601 .append_scalar(
602 Fq::from_hex("79586cc6b8b53c8991b2abe0ca76508f056ca50f06836ce4d818c2ff73d42b28")
603 .expect("failed to create scalar"),
604 );
605
606 assert_eq!(
607 roi.to_bytes(),
608 [
609 0xd8, 0x97, 0xc7, 0xa8, 0xb8, 0x11, 0xd8, 0xac, 0xd3, 0xee, 0xaa, 0x4a, 0xdf, 0x42,
610 0x29, 0x28, 0x02, 0xee, 0xd8, 0x00, 0x31, 0xc2, 0xad, 0x7c, 0x89, 0x89, 0xae, 0xa1,
611 0xfe, 0x94, 0x32, 0x2c, 0x79, 0x58, 0x6c, 0xc6, 0xb8, 0xb5, 0x3c, 0x89, 0x91, 0xb2,
612 0xab, 0xe0, 0xca, 0x76, 0x50, 0x8f, 0x05, 0x6c, 0xa5, 0x0f, 0x06, 0x83, 0x6c, 0xe4,
613 0xd8, 0x18, 0xc2, 0xff, 0x73, 0xd4, 0x2b, 0x28
614 ]
615 );
616 }
617
618 #[test]
619 fn to_bytes() {
620 let roi = ROInput::new()
621 .append_field(
622 Fp::from_hex("a5984f2bd00906f9a86e75bfb4b2c3625f1a0d1cfacc1501e8e82ae7041efc14")
623 .expect("failed to create field"),
624 )
625 .append_field(
626 Fp::from_hex("8af0bc770d49a5b9fcabfcdd033bab470b2a211ef80b710efe71315cfa818c0a")
627 .expect("failed to create field"),
628 )
629 .append_bool(false)
630 .append_u32(314u32)
631 .append_scalar(
632 Fq::from_hex("c23c43a23ddc1516578b0f0d81b93cdbbc97744acc697cfc8c5dfd01cc448323")
633 .expect("failed to create scalar"),
634 );
635
636 assert_eq!(
637 roi.to_bytes(),
638 [
639 0xa5, 0x98, 0x4f, 0x2b, 0xd0, 0x09, 0x06, 0xf9, 0xa8, 0x6e, 0x75, 0xbf, 0xb4, 0xb2,
640 0xc3, 0x62, 0x5f, 0x1a, 0x0d, 0x1c, 0xfa, 0xcc, 0x15, 0x01, 0xe8, 0xe8, 0x2a, 0xe7,
641 0x04, 0x1e, 0xfc, 0x14, 0x45, 0x78, 0xde, 0xbb, 0x86, 0xa4, 0xd2, 0x5c, 0xfe, 0x55,
642 0xfe, 0xee, 0x81, 0x9d, 0xd5, 0xa3, 0x05, 0x95, 0x10, 0x0f, 0xfc, 0x85, 0x38, 0x07,
643 0xff, 0xb8, 0x18, 0x2e, 0xfd, 0x40, 0x46, 0x05, 0x9d, 0x00, 0x00, 0x00, 0x61, 0x9e,
644 0x21, 0xd1, 0x1e, 0xee, 0x0a, 0x8b, 0xab, 0xc5, 0x87, 0x86, 0xc0, 0x5c, 0x9e, 0x6d,
645 0xde, 0x4b, 0x3a, 0x25, 0xe6, 0x34, 0x3e, 0x7e, 0xc6, 0xae, 0xfe, 0x00, 0x66, 0xa2,
646 0xc1, 0x11
647 ]
648 );
649 }
650
651 #[test]
652 fn to_fields_1_scalar() {
653 let roi = ROInput::new().append_scalar(
654 Fq::from_hex("5d496dd8ff63f640c006887098092b16bc8c78504f84fa1ee3a0b54f85f0a625")
655 .expect("failed to create scalar"),
656 );
657
658 assert_eq!(
659 roi.to_bytes(),
660 [
661 0x5d, 0x49, 0x6d, 0xd8, 0xff, 0x63, 0xf6, 0x40, 0xc0, 0x06, 0x88, 0x70, 0x98, 0x09,
662 0x2b, 0x16, 0xbc, 0x8c, 0x78, 0x50, 0x4f, 0x84, 0xfa, 0x1e, 0xe3, 0xa0, 0xb5, 0x4f,
663 0x85, 0xf0, 0xa6, 0x25
664 ]
665 );
666
667 assert_eq!(
668 roi.to_fields(),
669 [
670 Fp::from_hex("5d496dd8ff63f640c006887098092b16bc8c78504f84fa1ee3a0b54f85f0a625")
671 .expect("failed to create field"),
672 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
673 .expect("failed to create field"),
674 ]
675 );
676 }
677
678 #[test]
679 fn to_fields_1_scalar_2_bits() {
680 let roi = ROInput::new()
681 .append_scalar(
682 Fq::from_hex("e8a9961c8c417b0d0e3d7366f6b0e6ef90a6dad123070f715e8a9eaa02e47330")
683 .expect("failed to create scalar"),
684 )
685 .append_bool(false)
686 .append_bool(true);
687
688 assert_eq!(
689 roi.to_bytes(),
690 [
691 0xe8, 0xa9, 0x96, 0x1c, 0x8c, 0x41, 0x7b, 0x0d, 0x0e, 0x3d, 0x73, 0x66, 0xf6, 0xb0,
692 0xe6, 0xef, 0x90, 0xa6, 0xda, 0xd1, 0x23, 0x07, 0x0f, 0x71, 0x5e, 0x8a, 0x9e, 0xaa,
693 0x02, 0xe4, 0x73, 0x30, 0x01
694 ]
695 );
696
697 assert_eq!(
698 roi.to_fields(),
699 [
700 Fp::from_hex("e8a9961c8c417b0d0e3d7366f6b0e6ef90a6dad123070f715e8a9eaa02e47330")
701 .expect("failed to create field"),
702 Fp::from_hex("0400000000000000000000000000000000000000000000000000000000000000")
703 .expect("failed to create field"),
704 ]
705 );
706 }
707
708 #[test]
709 fn to_fields_2_scalars() {
710 let roi = ROInput::new()
711 .append_scalar(
712 Fq::from_hex("e05c25d2c17ec20d6bc8fd21204af52808451076cff687407164a21d352ddd22")
713 .expect("failed to create scalar"),
714 )
715 .append_scalar(
716 Fq::from_hex("c356dbb39478508818e0320dffa6c1ef512564366ec885ee2fc4d385dd36df0f")
717 .expect("failed to create scalar"),
718 );
719
720 assert_eq!(
721 roi.to_bytes(),
722 [
723 0xe0, 0x5c, 0x25, 0xd2, 0xc1, 0x7e, 0xc2, 0x0d, 0x6b, 0xc8, 0xfd, 0x21, 0x20, 0x4a,
724 0xf5, 0x28, 0x08, 0x45, 0x10, 0x76, 0xcf, 0xf6, 0x87, 0x40, 0x71, 0x64, 0xa2, 0x1d,
725 0x35, 0x2d, 0xdd, 0xa2, 0x61, 0xab, 0xed, 0x59, 0x4a, 0x3c, 0x28, 0x44, 0x0c, 0x70,
726 0x99, 0x86, 0x7f, 0xd3, 0xe0, 0xf7, 0xa8, 0x12, 0x32, 0x1b, 0x37, 0xe4, 0x42, 0xf7,
727 0x17, 0xe2, 0xe9, 0xc2, 0x6e, 0x9b, 0xef, 0x07
728 ]
729 );
730
731 assert_eq!(
732 roi.to_fields(),
733 [
734 Fp::from_hex("e05c25d2c17ec20d6bc8fd21204af52808451076cff687407164a21d352ddd22")
735 .expect("failed to create field"),
736 Fp::from_hex("86adb66729f1a01031c0651afe4d83dfa34ac86cdc900bdd5f88a70bbb6dbe1f")
737 .expect("failed to create field"),
738 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
739 .expect("failed to create field"),
740 ]
741 );
742 }
743
744 #[test]
745 fn to_fields_2_bits_scalar_u32() {
746 let roi = ROInput::new()
747 .append_bool(true)
748 .append_bool(false)
749 .append_scalar(
750 Fq::from_hex("689634de233b06251a80ac7df64483922727757eea1adc6f0c8f184441cfe10d")
751 .expect("failed to create scalar"),
752 )
753 .append_u32(834803);
754
755 assert_eq!(
756 roi.to_bytes(),
757 [
758 0xa1, 0x59, 0xd2, 0x78, 0x8f, 0xec, 0x18, 0x94, 0x68, 0x00, 0xb2, 0xf6, 0xd9, 0x13,
759 0x0d, 0x4a, 0x9e, 0x9c, 0xd4, 0xf9, 0xa9, 0x6b, 0x70, 0xbf, 0x31, 0x3c, 0x62, 0x10,
760 0x05, 0x3d, 0x87, 0x37, 0xe6, 0x79, 0x19, 0x00, 0x00
761 ]
762 );
763
764 assert_eq!(
765 roi.to_fields(),
766 [
767 Fp::from_hex("a159d2788fec18946800b2f6d9130d4a9e9cd4f9a96b70bf313c6210053d8737")
768 .expect("failed to create field"),
769 Fp::from_hex("98e7650000000000000000000000000000000000000000000000000000000000")
770 .expect("failed to create field"),
771 ]
772 );
773 }
774
775 #[test]
776 fn to_fields_2_bits_field_scalar() {
777 let roi = ROInput::new()
778 .append_bool(false)
779 .append_bool(true)
780 .append_field(
781 Fp::from_hex("90926b620ad09ed616d5df158504faed42928719c58ae619d9eccc062f920411")
782 .expect("failed to create field"),
783 )
784 .append_scalar(
785 Fq::from_hex("689634de233b06251a80ac7df64483922727757eea1adc6f0c8f184441cfe10d")
786 .expect("failed to create scalar"),
787 );
788
789 assert_eq!(
790 roi.to_bytes(),
791 [
792 0x90, 0x92, 0x6b, 0x62, 0x0a, 0xd0, 0x9e, 0xd6, 0x16, 0xd5, 0xdf, 0x15, 0x85, 0x04,
793 0xfa, 0xed, 0x42, 0x92, 0x87, 0x19, 0xc5, 0x8a, 0xe6, 0x19, 0xd9, 0xec, 0xcc, 0x06,
794 0x2f, 0x92, 0x04, 0x11, 0xd1, 0x2c, 0x69, 0xbc, 0x47, 0x76, 0x0c, 0x4a, 0x34, 0x00,
795 0x59, 0xfb, 0xec, 0x89, 0x06, 0x25, 0x4f, 0x4e, 0xea, 0xfc, 0xd4, 0x35, 0xb8, 0xdf,
796 0x18, 0x1e, 0x31, 0x88, 0x82, 0x9e, 0xc3, 0x1b
797 ]
798 );
799
800 assert_eq!(
801 roi.to_fields(),
802 [
803 Fp::from_hex("90926b620ad09ed616d5df158504faed42928719c58ae619d9eccc062f920411")
804 .expect("failed to create field"),
805 Fp::from_hex("a259d2788fec18946800b2f6d9130d4a9e9cd4f9a96b70bf313c6210053d8737")
806 .expect("failed to create field"),
807 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
808 .expect("failed to create field"),
809 ]
810 );
811 }
812
813 #[test]
814 fn transaction_test_1() {
815 let roi = ROInput::new()
816 .append_field(
817 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
818 .expect("failed to create field"),
819 ) .append_field(
821 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
822 .expect("failed to create field"),
823 ) .append_field(
825 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
826 .expect("failed to create field"),
827 ) .append_u64(1000000) .append_u64(1) .append_bool(true) .append_u32(0) .append_u32(u32::MAX) .append_bytes(&[0; 34]) .append_bool(false) .append_bool(false) .append_bool(false) .append_bool(true) .append_bool(false) .append_u64(1) .append_u64(10000000000) .append_bool(false); assert_eq!(roi.bits.len() + roi.fields.len() * 255, 1364);
843 assert_eq!(
844 roi.to_bytes(),
845 [
846 0x41, 0x20, 0x3c, 0x6b, 0xba, 0xc1, 0x4b, 0x35, 0x73, 0x01, 0xe1, 0xf3, 0x86, 0xd8,
847 0x0f, 0x52, 0x12, 0x3f, 0xd0, 0x0f, 0x02, 0x19, 0x74, 0x91, 0xb6, 0x90, 0xbd, 0xdf,
848 0xa7, 0x42, 0xca, 0xa2, 0x4c, 0x16, 0x6d, 0xf9, 0x4f, 0xff, 0x0a, 0x59, 0x5e, 0xf5,
849 0x2e, 0x00, 0x72, 0xcc, 0xf6, 0xa7, 0xff, 0xe8, 0x8b, 0xe0, 0x4b, 0xf8, 0xfc, 0x42,
850 0x43, 0xf2, 0x82, 0x7b, 0x17, 0x7c, 0x47, 0xc0, 0x8f, 0xee, 0xd3, 0xe9, 0x86, 0x73,
851 0x43, 0xff, 0x7d, 0x02, 0xf6, 0x89, 0x11, 0x8c, 0x8d, 0x75, 0x0a, 0x05, 0xd6, 0xf7,
852 0xfb, 0xdd, 0x8b, 0xbd, 0xd7, 0x61, 0x6f, 0xdb, 0x86, 0x87, 0x81, 0x0a, 0x48, 0xe8,
853 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
854 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
855 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
856 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
857 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x5f, 0xa0, 0x12, 0x00,
858 0x00, 0x00, 0x00
859 ]
860 );
861
862 assert_eq!(
863 roi.to_fields(),
864 [
865 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
866 .expect("failed to create field"),
867 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
868 .expect("failed to create field"),
869 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
870 .expect("failed to create field"),
871 Fp::from_hex("40420f0000000000010000000000000001000000feffffff0100000000000000")
872 .expect("failed to create field"),
873 Fp::from_hex("0000000000000000000000000000000000000000000000000000400100000000")
874 .expect("failed to create field"),
875 Fp::from_hex("00000000902f5009000000000000000000000000000000000000000000000000")
876 .expect("failed to create field"),
877 ]
878 );
879 }
880
881 #[test]
882 fn nested_roinput_test() {
883 #[derive(Clone, Debug)]
884 struct A {
885 x: u32,
886 y: bool,
887 z: u32,
888 }
889
890 impl Hashable for A {
891 type D = ();
892
893 fn to_roinput(&self) -> ROInput {
894 ROInput::new()
895 .append_u32(self.x)
896 .append_bool(self.y)
897 .append_u32(self.z)
898 }
899
900 fn domain_string(_: Self::D) -> Option<String> {
901 "A".to_string().into()
902 }
903 }
904
905 #[derive(Clone, Debug)]
906 struct B1 {
907 a: A,
908 b: u64,
909 c: bool,
910 }
911
912 impl Hashable for B1 {
913 type D = ();
914
915 fn to_roinput(&self) -> ROInput {
916 self.a.to_roinput().append_u64(self.b).append_bool(self.c)
917 }
918
919 fn domain_string(_: Self::D) -> Option<String> {
920 "B".to_string().into()
921 }
922 }
923
924 #[derive(Clone, Debug)]
925 struct B2 {
926 a: A,
927 b: u64,
928 c: bool,
929 }
930
931 impl Hashable for B2 {
932 type D = ();
933
934 fn to_roinput(&self) -> ROInput {
935 self.a
936 .to_roinput()
937 .append_roinput(ROInput::new().append_u64(self.b).append_bool(self.c))
938 }
939
940 fn domain_string(_: Self::D) -> Option<String> {
941 "B".to_string().into()
942 }
943 }
944
945 let a = A {
946 x: 16830533,
947 y: false,
948 z: 39827791,
949 };
950 let b1 = B1 {
951 a,
952 b: 124819,
953 c: true,
954 };
955 let b2 = B2 {
956 a: b1.a.clone(),
957 b: b1.b,
958 c: b1.c,
959 };
960
961 assert_eq!(b1.to_roinput(), b2.to_roinput());
962
963 let b2 = B2 {
964 a: b1.a.clone(),
965 b: b1.b,
966 c: false,
967 };
968 assert_ne!(b1.to_roinput(), b2.to_roinput());
969
970 let b2 = B2 {
971 a: b1.a.clone(),
972 b: b1.b + 1,
973 c: b1.c,
974 };
975 assert_ne!(b1.to_roinput(), b2.to_roinput());
976 }
977
978 #[test]
979 fn serialize_empty() {
980 let roi = ROInput::new();
981
982 let serialized = roi.serialize();
983
984 assert_eq!(
985 serialized,
986 vec![0; SER_HEADER_SIZE],
987 "Serialized empty ROInput should be zero bytes"
988 );
989
990 let deserialized_roi =
991 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput");
992 assert_eq!(
993 roi, deserialized_roi,
994 "Serialized and deserialized ROInput do not match"
995 );
996 }
997
998 #[test]
999 fn serialize_single_field() {
1000 let roi = ROInput::new().append_field(
1001 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
1002 .expect("failed to create field"),
1003 );
1004
1005 let serialized = roi.serialize();
1006 let expected_length = SER_HEADER_SIZE + 32; assert_eq!(
1008 serialized.len(),
1009 expected_length,
1010 "Serialized ROInput length mismatch"
1011 );
1012 assert_eq!(
1013 serialized,
1014 [
1015 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x3c, 0x6b, 0xba, 0xc1, 0x4b, 0x35, 0x73, 0x01, 0xe1, 0xf3, 0x86, 0xd8,
1018 0x0f, 0x52, 0x12, 0x3f, 0xd0, 0x0f, 0x02, 0x19, 0x74, 0x91, 0xb6, 0x90, 0xbd, 0xdf,
1019 0xa7, 0x42, 0xca, 0x22
1020 ]
1021 .to_vec(),
1022 "Serialized ROInput does not match expected output"
1023 );
1024
1025 assert_eq!(
1026 roi,
1027 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput"),
1028 "Serialized and deserialized ROInput do not match"
1029 )
1030 }
1031
1032 #[test]
1033 fn serialize_single_bool() {
1034 let roi = ROInput::new().append_bool(true);
1035
1036 let serialized = roi.serialize();
1037 let expected_length = SER_HEADER_SIZE + 1; assert_eq!(
1039 serialized.len(),
1040 expected_length,
1041 "Serialized ROInput length mismatch"
1042 );
1043 assert_eq!(
1044 serialized,
1045 [
1046 0x00, 0x00, 0x00, 0x00,
1047 0x01, 0x00, 0x00, 0x00,
1048 0x01 ]
1050 .to_vec(),
1051 "Serialized ROInput does not match expected output"
1052 );
1053
1054 assert_eq!(
1055 roi,
1056 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput"),
1057 "Serialized and deserialized ROInput do not match"
1058 );
1059 }
1060
1061 #[test]
1062 fn serialize_multiple_bools_length() {
1063 for i in 0..1024 {
1064 let roi = ROInput::new().append_bool(i % 2 == 0);
1065 let serialized = roi.serialize();
1066
1067 let deserialized_roi =
1069 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput");
1070 assert_eq!(
1071 roi, deserialized_roi,
1072 "Serialized and deserialized ROInput do not match for i={}",
1073 i
1074 );
1075 }
1076 }
1077
1078 #[test]
1079 fn deserialize_invalid() {
1080 let invalid_data = vec![0x01, 0x00, 0x00, 0x00]; let result = ROInput::deserialize(&invalid_data);
1083 assert!(
1084 result.is_err(),
1085 "Deserialization should fail for invalid data"
1086 );
1087 }
1088
1089 #[test]
1090 fn deserialize_invalid_inconsistent_bitlen() {
1091 let invalid_data = vec![
1092 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, ];
1097
1098 let result = ROInput::deserialize(&invalid_data);
1099 assert!(
1100 result.is_err(),
1101 "Deserialization should fail for inconsistent bit length"
1102 );
1103 }
1104
1105 #[test]
1106 fn deserialize_invalid_message() {
1107 let msg = b"Test message for Mina compatibility".to_vec();
1108 let result = ROInput::deserialize(&msg);
1109 assert!(
1110 result.is_err(),
1111 "Deserialization should fail for invalid message format"
1112 );
1113 }
1114
1115 #[test]
1116 fn deserialize_invalid_fieldheader() {
1117 let invalid_data = vec![
1118 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x01, ];
1123
1124 let result = ROInput::deserialize(&invalid_data);
1125 assert!(
1126 result.is_err(),
1127 "Deserialization should fail for overflow in field header"
1128 );
1129 }
1130
1131 #[test]
1132 fn serialize_tx() {
1133 let tx_roi = ROInput::new()
1134 .append_field(
1135 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
1136 .expect("failed to create field"),
1137 )
1138 .append_field(
1139 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
1140 .expect("failed to create field"),
1141 ) .append_field(
1143 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
1144 .expect("failed to create field"),
1145 ) .append_u64(1000000) .append_u64(1) .append_bool(true) .append_u32(0) .append_u32(u32::MAX) .append_bytes(&[0; 34]) .append_bool(false) .append_bool(false) .append_bool(false) .append_bool(true) .append_bool(false) .append_u64(1) .append_u64(10000000000) .append_bool(false); let tx_bytes = tx_roi.serialize();
1162
1163 let deserialized_roi =
1164 ROInput::deserialize(&tx_bytes).expect("Failed to deserialize ROInput");
1165
1166 assert_eq!(
1167 tx_roi, deserialized_roi,
1168 "Serialized and deserialized ROInput do not match"
1169 );
1170 }
1171}