1use alloc::{vec, vec::Vec};
7use core::fmt::Error;
8
9use super::Hashable;
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;
17const SINGLE_HEADER_SIZE: usize = 4;
19
20#[derive(Default, Debug, Clone, PartialEq, Eq)]
69pub struct ROInput {
70 fields: Vec<Fp>,
71 bits: BitVec<u8>,
72}
73
74impl ROInput {
75 #[must_use]
77 pub fn new() -> Self {
78 Self {
79 fields: vec![],
80 bits: BitVec::new(),
81 }
82 }
83
84 #[must_use]
86 pub fn append_hashable(self, input: &impl Hashable) -> Self {
87 self.append_roinput(input.to_roinput())
88 }
89
90 #[must_use]
92 pub fn append_roinput(mut self, mut roi: Self) -> Self {
93 self.fields.append(&mut roi.fields);
94 self.bits.extend(roi.bits);
95 self
96 }
97
98 #[must_use]
100 pub fn append_field(mut self, f: Fp) -> Self {
101 self.fields.push(f);
102 self
103 }
104
105 #[must_use]
146 pub fn append_scalar(mut self, s: Fq) -> Self {
147 let bytes = s.to_bytes();
149 let bits = &bytes.as_bits::<Lsb0>()[..Fq::MODULUS_BIT_SIZE as usize];
150 self.bits.extend(bits);
151 self
152 }
153
154 #[must_use]
156 pub fn append_bool(mut self, b: bool) -> Self {
157 self.bits.push(b);
158 self
159 }
160
161 #[must_use]
163 pub fn append_bytes(mut self, bytes: &[u8]) -> Self {
164 self.bits.extend_from_bitslice(bytes.as_bits::<Lsb0>());
165 self
166 }
167
168 #[must_use]
170 pub fn append_u32(self, x: u32) -> Self {
171 self.append_bytes(&x.to_le_bytes())
172 }
173
174 #[must_use]
176 pub fn append_u64(self, x: u64) -> Self {
177 self.append_bytes(&x.to_le_bytes())
178 }
179
180 #[must_use]
182 pub fn to_bytes(&self) -> Vec<u8> {
183 let mut bits: BitVec<u8> = self.fields.iter().fold(BitVec::new(), |mut acc, fe| {
184 acc.extend_from_bitslice(
185 &fe.to_bytes().as_bits::<Lsb0>()[..Fp::MODULUS_BIT_SIZE as usize],
186 );
187
188 acc
189 });
190
191 bits.extend(&self.bits);
192
193 bits.into()
194 }
195
196 #[must_use]
204 pub fn to_fields(&self) -> Vec<Fp> {
205 let mut fields: Vec<Fp> = self.fields.clone();
206
207 let bits_as_fields =
208 self.bits
209 .chunks(Fp::MODULUS_BIT_SIZE as usize - 1)
210 .fold(vec![], |mut acc, chunk| {
211 let mut bv = BitVec::<u8>::new();
225 bv.resize(chunk.len(), false);
226 bv.clone_from_bitslice(chunk);
227
228 bv.resize(Fp::MODULUS_BIT_SIZE as usize, false);
230
231 acc.push(
232 Fp::from_bytes(&bv.into_vec())
233 .expect("failed to create base field element"),
234 );
235
236 acc
237 });
238
239 fields.extend(bits_as_fields);
240
241 fields
242 }
243
244 #[must_use]
246 #[allow(clippy::cast_possible_truncation)]
247 pub fn serialize(&self) -> Vec<u8> {
248 let fields_len = self.fields.len() as u32;
251 let bits_len = self.bits.len() as u32;
252
253 let mut bytes = Vec::with_capacity(SER_HEADER_SIZE + self.to_bytes().len());
254 bytes.extend_from_slice(&fields_len.to_le_bytes());
255 bytes.extend_from_slice(&bits_len.to_le_bytes());
256 bytes.extend_from_slice(&self.to_bytes());
257 bytes
258 }
259
260 pub fn deserialize(input: &[u8]) -> Result<Self, Error> {
273 if input.len() < SER_HEADER_SIZE {
274 return Err(Error);
275 }
276
277 let fields_len =
279 u32::from_le_bytes(input[0..SINGLE_HEADER_SIZE].try_into().unwrap()) as usize;
280 let bits_len = u32::from_le_bytes(
281 input[SINGLE_HEADER_SIZE..SER_HEADER_SIZE]
282 .try_into()
283 .unwrap(),
284 ) as usize;
285
286 let bits = input[SER_HEADER_SIZE..].view_bits::<Lsb0>();
288
289 let expected_len_bits = fields_len * Fp::MODULUS_BIT_SIZE as usize + bits_len;
291 let expected_len = expected_len_bits.div_ceil(8) + SER_HEADER_SIZE;
293 if input.len() != expected_len {
294 return Err(Error);
295 }
296
297 let mut fields = Vec::with_capacity(fields_len);
299
300 for chunk in bits.chunks(Fp::MODULUS_BIT_SIZE as usize).take(fields_len) {
301 let bools: Vec<bool> = chunk.iter().by_vals().collect();
302 let repr = <Fp as PrimeField>::BigInt::from_bits_le(&bools);
304 let elt = Fp::from_bigint(repr).ok_or(Error)?;
306 fields.push(elt);
307 }
308
309 let remainder = &bits[fields_len * Fp::MODULUS_BIT_SIZE as usize..];
310 let bits = remainder.iter().take(bits_len).collect::<BitVec<u8>>();
312
313 let roi = Self { fields, bits };
314
315 Ok(roi)
316 }
317}
318
319#[cfg(test)]
320mod tests {
321 use super::*;
322 use crate::{
323 alloc::string::{String, ToString},
324 Hashable,
325 };
326
327 #[test]
328 fn append_bool() {
329 let roi = ROInput::new().append_bool(true);
330 assert!(roi.bits.len() == 1);
331 assert!(roi.bits.as_raw_slice() == [0x01]);
332 }
333
334 #[test]
335 fn append_two_bits() {
336 let roi = ROInput::new().append_bool(false).append_bool(true);
337 assert!(roi.bits.len() == 2);
338 assert!(roi.bits.as_raw_slice() == [0x02]);
339 }
340
341 #[test]
342 fn append_five_bits() {
343 let roi = ROInput::new()
344 .append_bool(false)
345 .append_bool(true)
346 .append_bool(false)
347 .append_bool(false)
348 .append_bool(true);
349 assert!(roi.bits.len() == 5);
350 assert!(roi.bits.as_raw_slice() == [0x12]);
351 }
352
353 #[test]
354 fn append_byte() {
355 let roi = ROInput::new().append_bytes(&[0x01]);
356 assert!(roi.bits.len() == 8);
357 assert!(roi.bits.as_raw_slice() == [0x01]);
358 }
359
360 #[test]
361 fn append_two_bytes() {
362 let roi = ROInput::new().append_bytes(&[0x10, 0xac]);
363 assert!(roi.bits.len() == 16);
364 assert!(roi.bits.as_raw_slice() == [0x10, 0xac]);
365 }
366
367 #[test]
368 fn append_five_bytes() {
369 let roi = ROInput::new().append_bytes(&[0x10, 0xac, 0x01, 0xeb, 0xca]);
370 assert!(roi.bits.len() == 40);
371 assert!(roi.bits.as_raw_slice() == [0x10, 0xac, 0x01, 0xeb, 0xca]);
372 }
373
374 #[test]
375 fn append_scalar() {
376 let scalar =
377 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
378 .expect("failed to create scalar");
379 let roi = ROInput::new().append_scalar(scalar);
380 assert_eq!(roi.bits.len(), 255);
381 assert_eq!(
382 roi.bits.as_raw_slice(),
383 [
384 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa, 0x28,
385 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5, 0xdd, 0x6f,
386 0x17, 0x44, 0x42, 0x16
387 ]
388 );
389 assert_eq!(
390 roi.to_bytes(),
391 [
392 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa, 0x28,
393 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5, 0xdd, 0x6f,
394 0x17, 0x44, 0x42, 0x16
395 ]
396 );
397 }
398
399 #[test]
400 fn append_scalar_and_byte() {
401 let scalar =
402 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
403 .expect("failed to create scalar");
404 let roi = ROInput::new().append_scalar(scalar).append_bytes(&[0x01]);
405 assert!(roi.bits.len() == 263);
406 assert!(
407 roi.bits.as_raw_slice()
408 == [
409 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa,
410 0x28, 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5,
411 0xdd, 0x6f, 0x17, 0x44, 0x42, 0x96, 0x00
412 ]
413 );
414 }
415
416 #[test]
417 fn append_two_scalars() {
418 let scalar1 =
419 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
420 .expect("failed to create scalar");
421 let scalar2 =
422 Fq::from_hex("a1b1e948835be341277548134e0effabdbcb95b742e8c5e967e9bf13eb4ae805")
423 .expect("failed to create scalar");
424 let roi = ROInput::new().append_scalar(scalar1).append_scalar(scalar2);
425 assert!(roi.bits.len() == 510);
426 assert!(
427 roi.bits.as_raw_slice()
428 == [
429 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa,
430 0x28, 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5,
431 0xdd, 0x6f, 0x17, 0x44, 0x42, 0x96, 0xd0, 0xd8, 0x74, 0xa4, 0xc1, 0xad, 0xf1,
432 0xa0, 0x93, 0x3a, 0xa4, 0x09, 0x27, 0x87, 0xff, 0xd5, 0xed, 0xe5, 0xca, 0x5b,
433 0x21, 0xf4, 0xe2, 0xf4, 0xb3, 0xf4, 0xdf, 0x89, 0x75, 0x25, 0xf4, 0x02
434 ]
435 );
436 }
437
438 #[test]
439 fn append_two_scalars_and_byte() {
440 let scalar1 =
441 Fq::from_hex("60db6f4f5b8ce1c7cb747fba9e324cc3268c7a6e3f43cd82d451ae99a7b2bd1f")
442 .expect("failed to create scalar");
443 let scalar2 =
444 Fq::from_hex("fe7775b106bceb58f3e23e5a4eb99f404b8ed8cf2afeef9c9d1800f12138cd07")
445 .expect("failed to create scalar");
446 let roi = ROInput::new()
447 .append_scalar(scalar1)
448 .append_bytes(&[0x2a])
449 .append_scalar(scalar2);
450 assert!(roi.bits.len() == 518);
451 assert!(
452 roi.bits.as_raw_slice()
453 == [
454 0x60, 0xdb, 0x6f, 0x4f, 0x5b, 0x8c, 0xe1, 0xc7, 0xcb, 0x74, 0x7f, 0xba, 0x9e,
455 0x32, 0x4c, 0xc3, 0x26, 0x8c, 0x7a, 0x6e, 0x3f, 0x43, 0xcd, 0x82, 0xd4, 0x51,
456 0xae, 0x99, 0xa7, 0xb2, 0xbd, 0x1f, 0x15, 0xff, 0xbb, 0xba, 0x58, 0x03, 0xde,
457 0x75, 0xac, 0x79, 0x71, 0x1f, 0x2d, 0xa7, 0xdc, 0x4f, 0xa0, 0x25, 0x47, 0xec,
458 0x67, 0x15, 0xff, 0x77, 0xce, 0x4e, 0x0c, 0x80, 0xf8, 0x10, 0x9c, 0xe6, 0x03
459 ]
460 );
461 }
462
463 #[test]
464 fn test_append_scalar_max_value() {
465 let max_scalar = Fq::from(0u64) - Fq::from(1u64); let roi = ROInput::new().append_scalar(max_scalar);
468
469 assert_eq!(roi.bits.len(), 255);
471 assert_eq!(roi.fields.len(), 0);
472
473 let reconstructed_bytes = roi.bits.as_raw_slice();
475 let expected_bytes = max_scalar.to_bytes();
476
477 assert_eq!(&reconstructed_bytes[..31], &expected_bytes[..31]);
479
480 let last_byte_mask = 0x7F; assert_eq!(
483 reconstructed_bytes[31] & last_byte_mask,
484 expected_bytes[31] & last_byte_mask
485 );
486
487 let serialized_bytes = roi.to_bytes();
489 assert_eq!(serialized_bytes.len(), 32); let fields = roi.to_fields();
493 assert_eq!(fields.len(), 2); let roi_double = ROInput::new()
497 .append_scalar(max_scalar)
498 .append_scalar(max_scalar);
499 assert_eq!(roi_double.bits.len(), 510); let fields_double = roi_double.to_fields();
502 assert_eq!(fields_double.len(), 3); }
504
505 #[test]
506 fn append_u32() {
507 let roi = ROInput::new().append_u32(1984u32);
508 assert!(roi.bits.len() == 32);
509 assert!(roi.bits.as_raw_slice() == [0xc0, 0x07, 0x00, 0x00]);
510 }
511
512 #[test]
513 fn append_two_u32_and_bit() {
514 let roi = ROInput::new()
515 .append_u32(1729u32)
516 .append_bool(false)
517 .append_u32(u32::MAX);
518 assert!(roi.bits.len() == 65);
519 assert!(roi.bits.as_raw_slice() == [0xc1, 0x06, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01]);
520 }
521
522 #[test]
523 fn append_u64() {
524 let roi = ROInput::new().append_u64(6174u64);
525 assert!(roi.bits.len() == 64);
526 assert!(roi.bits.as_raw_slice() == [0x1e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
527 }
528
529 #[test]
530 fn append_two_u64_and_bits() {
531 let roi = ROInput::new()
532 .append_bool(true)
533 .append_u64(u64::MAX / 6174u64)
534 .append_bool(false)
535 .append_u64(u64::MAX / 1111u64);
536 assert!(roi.bits.len() == 130);
537 assert!(
538 roi.bits.as_raw_slice()
539 == [
540 0xe1, 0x29, 0x89, 0xd6, 0xcb, 0x3a, 0x15, 0x00, 0x08, 0x17, 0xc4, 0x9b, 0x04,
541 0xf4, 0xeb, 0x00, 0x00
542 ]
543 );
544 }
545
546 #[test]
547 fn all_1() {
548 let roi = ROInput::new()
549 .append_bool(true)
550 .append_scalar(
551 Fq::from_hex("01d1755db21c8cd2a9cf5a3436178da3d70f484cd4b4c8834b799921e7d7a102")
552 .expect("failed to create scalar"),
553 )
554 .append_u64(18_446_744_073_709_551_557)
555 .append_bytes(&[0xba, 0xdc, 0x0f, 0xfe])
556 .append_scalar(
557 Fq::from_hex("e70187e9b125524489d0433da76fd8287fa652eaebde147b45fa0cd86f171810")
558 .expect("failed to create scalar"),
559 )
560 .append_bool(false)
561 .append_u32(2_147_483_647)
562 .append_bool(true);
563
564 assert!(roi.bits.len() == 641);
565 assert!(
566 roi.bits.as_raw_slice()
567 == [
568 0x03, 0xa2, 0xeb, 0xba, 0x64, 0x39, 0x18, 0xa5, 0x53, 0x9f, 0xb5, 0x68, 0x6c,
569 0x2e, 0x1a, 0x47, 0xaf, 0x1f, 0x90, 0x98, 0xa8, 0x69, 0x91, 0x07, 0x97, 0xf2,
570 0x32, 0x43, 0xce, 0xaf, 0x43, 0x05, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
571 0xff, 0xba, 0xdc, 0x0f, 0xfe, 0xe7, 0x01, 0x87, 0xe9, 0xb1, 0x25, 0x52, 0x44,
572 0x89, 0xd0, 0x43, 0x3d, 0xa7, 0x6f, 0xd8, 0x28, 0x7f, 0xa6, 0x52, 0xea, 0xeb,
573 0xde, 0x14, 0x7b, 0x45, 0xfa, 0x0c, 0xd8, 0x6f, 0x17, 0x18, 0x10, 0xff, 0xff,
574 0xff, 0x7f, 0x01
575 ]
576 );
577 }
578
579 #[test]
580 fn transaction_bits() {
581 let roi = ROInput::new()
582 .append_u64(1_000_000) .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(10_000_000_000) .append_bool(false) .append_scalar(
597 Fq::from_hex("de217a3017ca0b7a278e75f63c09890e3894be532d8dbadd30a7d450055f6d2d")
598 .expect("failed to create scalar"),
599 )
600 .append_bytes(&[0x01]);
601 assert_eq!(roi.bits.len(), 862);
602 assert_eq!(
603 roi.bits.as_raw_slice(),
604 [
605 0x40, 0x42, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x02,
610 0x95, 0x00, 0x00, 0x00, 0x00, 0xef, 0x10, 0x3d, 0x98, 0x0b, 0xe5, 0x05, 0xbd, 0x13,
611 0xc7, 0x3a, 0x7b, 0x9e, 0x84, 0x44, 0x07, 0x1c, 0x4a, 0xdf, 0xa9, 0x96, 0x46, 0xdd,
612 0x6e, 0x98, 0x53, 0x6a, 0xa8, 0x82, 0xaf, 0xb6, 0x56, 0x00
613 ]
614 );
615 }
616
617 #[test]
618 fn append_field() {
619 let roi = ROInput::new().append_field(
620 Fp::from_hex("2eaedae42a7461d5952d27b97ecad068b698ebb94e8a0e4c45388bb613de7e08")
621 .expect("failed to create field"),
622 );
623
624 assert_eq!(
625 roi.to_bytes(),
626 [
627 0x2e, 0xae, 0xda, 0xe4, 0x2a, 0x74, 0x61, 0xd5, 0x95, 0x2d, 0x27, 0xb9, 0x7e, 0xca,
628 0xd0, 0x68, 0xb6, 0x98, 0xeb, 0xb9, 0x4e, 0x8a, 0x0e, 0x4c, 0x45, 0x38, 0x8b, 0xb6,
629 0x13, 0xde, 0x7e, 0x08
630 ]
631 );
632 }
633
634 #[test]
635 fn append_two_fields() {
636 let roi = ROInput::new()
637 .append_field(
638 Fp::from_hex("0cdaf334e9632268a5aa959c2781fb32bf45565fe244ae42c849d3fdc7c6441d")
639 .expect("failed to create field"),
640 )
641 .append_field(
642 Fp::from_hex("2eaedae42a7461d5952d27b97ecad068b698ebb94e8a0e4c45388bb613de7e08")
643 .expect("failed to create field"),
644 );
645
646 assert_eq!(
647 roi.to_bytes(),
648 [
649 0x0c, 0xda, 0xf3, 0x34, 0xe9, 0x63, 0x22, 0x68, 0xa5, 0xaa, 0x95, 0x9c, 0x27, 0x81,
650 0xfb, 0x32, 0xbf, 0x45, 0x56, 0x5f, 0xe2, 0x44, 0xae, 0x42, 0xc8, 0x49, 0xd3, 0xfd,
651 0xc7, 0xc6, 0x44, 0x1d, 0x17, 0x57, 0x6d, 0x72, 0x15, 0xba, 0xb0, 0xea, 0xca, 0x96,
652 0x93, 0x5c, 0x3f, 0x65, 0x68, 0x34, 0x5b, 0xcc, 0xf5, 0x5c, 0x27, 0x45, 0x07, 0xa6,
653 0x22, 0x9c, 0x45, 0xdb, 0x09, 0x6f, 0x3f, 0x04
654 ]
655 );
656 }
657
658 #[test]
659 fn append_three_fields() {
660 let roi = ROInput::new()
661 .append_field(
662 Fp::from_hex("1f3f142986041b54427aa2032632e34df2fa9bde9bce70c04c5034266619e529")
663 .expect("failed to create field"),
664 )
665 .append_field(
666 Fp::from_hex("37f4433b85e753a91a1d79751645f1448954c433f9492e36a933ca7f3df61a04")
667 .expect("failed to create field"),
668 )
669 .append_field(
670 Fp::from_hex("6cf4772d3e1aab98a2b514b73a4f6e0df1fb4f703ecfa762196b22c26da4341c")
671 .expect("failed to create field"),
672 );
673
674 assert_eq!(
675 roi.to_bytes(),
676 [
677 0x1f, 0x3f, 0x14, 0x29, 0x86, 0x04, 0x1b, 0x54, 0x42, 0x7a, 0xa2, 0x03, 0x26, 0x32,
678 0xe3, 0x4d, 0xf2, 0xfa, 0x9b, 0xde, 0x9b, 0xce, 0x70, 0xc0, 0x4c, 0x50, 0x34, 0x26,
679 0x66, 0x19, 0xe5, 0xa9, 0x1b, 0xfa, 0xa1, 0x9d, 0xc2, 0xf3, 0xa9, 0x54, 0x8d, 0x8e,
680 0xbc, 0x3a, 0x8b, 0xa2, 0x78, 0xa2, 0x44, 0x2a, 0xe2, 0x99, 0xfc, 0x24, 0x17, 0x9b,
681 0xd4, 0x19, 0xe5, 0xbf, 0x1e, 0x7b, 0x0d, 0x02, 0x1b, 0xfd, 0x5d, 0x8b, 0x8f, 0xc6,
682 0x2a, 0xa6, 0x68, 0x2d, 0xc5, 0xad, 0xce, 0x93, 0x5b, 0x43, 0xfc, 0xfe, 0x13, 0x9c,
683 0xcf, 0xf3, 0xa9, 0x58, 0xc6, 0x9a, 0x88, 0x70, 0x1b, 0x29, 0x0d, 0x07
684 ]
685 );
686 }
687
688 #[test]
689 fn append_field_and_scalar() {
690 let roi = ROInput::new()
691 .append_field(
692 Fp::from_hex("64cde530327a36fcb88b6d769adca9b7c5d266e7d0042482203f3fd3a0d71721")
693 .expect("failed to create field"),
694 )
695 .append_scalar(
696 Fq::from_hex("604355d0daa455db783fd7ee11c5bd9b04d67ba64c27c95bef95e379f98c6432")
697 .expect("failed to create scalar"),
698 );
699
700 assert_eq!(
701 roi.to_bytes(),
702 [
703 0x64, 0xcd, 0xe5, 0x30, 0x32, 0x7a, 0x36, 0xfc, 0xb8, 0x8b, 0x6d, 0x76, 0x9a, 0xdc,
704 0xa9, 0xb7, 0xc5, 0xd2, 0x66, 0xe7, 0xd0, 0x04, 0x24, 0x82, 0x20, 0x3f, 0x3f, 0xd3,
705 0xa0, 0xd7, 0x17, 0x21, 0xb0, 0xa1, 0x2a, 0x68, 0x6d, 0xd2, 0xaa, 0x6d, 0xbc, 0x9f,
706 0x6b, 0xf7, 0x88, 0xe2, 0xde, 0x4d, 0x02, 0xeb, 0x3d, 0x53, 0xa6, 0x93, 0xe4, 0xad,
707 0xf7, 0xca, 0xf1, 0xbc, 0x7c, 0x46, 0x32, 0x19
708 ]
709 );
710 }
711
712 #[test]
713 fn append_field_bit_and_scalar() {
714 let roi = ROInput::new()
715 .append_field(
716 Fp::from_hex("d897c7a8b811d8acd3eeaa4adf42292802eed80031c2ad7c8989aea1fe94322c")
717 .expect("failed to create field"),
718 )
719 .append_bool(false)
720 .append_scalar(
721 Fq::from_hex("79586cc6b8b53c8991b2abe0ca76508f056ca50f06836ce4d818c2ff73d42b28")
722 .expect("failed to create scalar"),
723 );
724
725 assert_eq!(
726 roi.to_bytes(),
727 [
728 0xd8, 0x97, 0xc7, 0xa8, 0xb8, 0x11, 0xd8, 0xac, 0xd3, 0xee, 0xaa, 0x4a, 0xdf, 0x42,
729 0x29, 0x28, 0x02, 0xee, 0xd8, 0x00, 0x31, 0xc2, 0xad, 0x7c, 0x89, 0x89, 0xae, 0xa1,
730 0xfe, 0x94, 0x32, 0x2c, 0x79, 0x58, 0x6c, 0xc6, 0xb8, 0xb5, 0x3c, 0x89, 0x91, 0xb2,
731 0xab, 0xe0, 0xca, 0x76, 0x50, 0x8f, 0x05, 0x6c, 0xa5, 0x0f, 0x06, 0x83, 0x6c, 0xe4,
732 0xd8, 0x18, 0xc2, 0xff, 0x73, 0xd4, 0x2b, 0x28
733 ]
734 );
735 }
736
737 #[test]
738 fn to_bytes() {
739 let roi = ROInput::new()
740 .append_field(
741 Fp::from_hex("a5984f2bd00906f9a86e75bfb4b2c3625f1a0d1cfacc1501e8e82ae7041efc14")
742 .expect("failed to create field"),
743 )
744 .append_field(
745 Fp::from_hex("8af0bc770d49a5b9fcabfcdd033bab470b2a211ef80b710efe71315cfa818c0a")
746 .expect("failed to create field"),
747 )
748 .append_bool(false)
749 .append_u32(314u32)
750 .append_scalar(
751 Fq::from_hex("c23c43a23ddc1516578b0f0d81b93cdbbc97744acc697cfc8c5dfd01cc448323")
752 .expect("failed to create scalar"),
753 );
754
755 assert_eq!(
756 roi.to_bytes(),
757 [
758 0xa5, 0x98, 0x4f, 0x2b, 0xd0, 0x09, 0x06, 0xf9, 0xa8, 0x6e, 0x75, 0xbf, 0xb4, 0xb2,
759 0xc3, 0x62, 0x5f, 0x1a, 0x0d, 0x1c, 0xfa, 0xcc, 0x15, 0x01, 0xe8, 0xe8, 0x2a, 0xe7,
760 0x04, 0x1e, 0xfc, 0x14, 0x45, 0x78, 0xde, 0xbb, 0x86, 0xa4, 0xd2, 0x5c, 0xfe, 0x55,
761 0xfe, 0xee, 0x81, 0x9d, 0xd5, 0xa3, 0x05, 0x95, 0x10, 0x0f, 0xfc, 0x85, 0x38, 0x07,
762 0xff, 0xb8, 0x18, 0x2e, 0xfd, 0x40, 0x46, 0x05, 0x9d, 0x00, 0x00, 0x00, 0x61, 0x9e,
763 0x21, 0xd1, 0x1e, 0xee, 0x0a, 0x8b, 0xab, 0xc5, 0x87, 0x86, 0xc0, 0x5c, 0x9e, 0x6d,
764 0xde, 0x4b, 0x3a, 0x25, 0xe6, 0x34, 0x3e, 0x7e, 0xc6, 0xae, 0xfe, 0x00, 0x66, 0xa2,
765 0xc1, 0x11
766 ]
767 );
768 }
769
770 #[test]
771 fn to_fields_1_scalar() {
772 let roi = ROInput::new().append_scalar(
773 Fq::from_hex("5d496dd8ff63f640c006887098092b16bc8c78504f84fa1ee3a0b54f85f0a625")
774 .expect("failed to create scalar"),
775 );
776
777 assert_eq!(
778 roi.to_bytes(),
779 [
780 0x5d, 0x49, 0x6d, 0xd8, 0xff, 0x63, 0xf6, 0x40, 0xc0, 0x06, 0x88, 0x70, 0x98, 0x09,
781 0x2b, 0x16, 0xbc, 0x8c, 0x78, 0x50, 0x4f, 0x84, 0xfa, 0x1e, 0xe3, 0xa0, 0xb5, 0x4f,
782 0x85, 0xf0, 0xa6, 0x25
783 ]
784 );
785
786 assert_eq!(
787 roi.to_fields(),
788 [
789 Fp::from_hex("5d496dd8ff63f640c006887098092b16bc8c78504f84fa1ee3a0b54f85f0a625")
790 .expect("failed to create field"),
791 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
792 .expect("failed to create field"),
793 ]
794 );
795 }
796
797 #[test]
798 fn to_fields_1_scalar_2_bits() {
799 let roi = ROInput::new()
800 .append_scalar(
801 Fq::from_hex("e8a9961c8c417b0d0e3d7366f6b0e6ef90a6dad123070f715e8a9eaa02e47330")
802 .expect("failed to create scalar"),
803 )
804 .append_bool(false)
805 .append_bool(true);
806
807 assert_eq!(
808 roi.to_bytes(),
809 [
810 0xe8, 0xa9, 0x96, 0x1c, 0x8c, 0x41, 0x7b, 0x0d, 0x0e, 0x3d, 0x73, 0x66, 0xf6, 0xb0,
811 0xe6, 0xef, 0x90, 0xa6, 0xda, 0xd1, 0x23, 0x07, 0x0f, 0x71, 0x5e, 0x8a, 0x9e, 0xaa,
812 0x02, 0xe4, 0x73, 0x30, 0x01
813 ]
814 );
815
816 assert_eq!(
817 roi.to_fields(),
818 [
819 Fp::from_hex("e8a9961c8c417b0d0e3d7366f6b0e6ef90a6dad123070f715e8a9eaa02e47330")
820 .expect("failed to create field"),
821 Fp::from_hex("0400000000000000000000000000000000000000000000000000000000000000")
822 .expect("failed to create field"),
823 ]
824 );
825 }
826
827 #[test]
828 fn to_fields_2_scalars() {
829 let roi = ROInput::new()
830 .append_scalar(
831 Fq::from_hex("e05c25d2c17ec20d6bc8fd21204af52808451076cff687407164a21d352ddd22")
832 .expect("failed to create scalar"),
833 )
834 .append_scalar(
835 Fq::from_hex("c356dbb39478508818e0320dffa6c1ef512564366ec885ee2fc4d385dd36df0f")
836 .expect("failed to create scalar"),
837 );
838
839 assert_eq!(
840 roi.to_bytes(),
841 [
842 0xe0, 0x5c, 0x25, 0xd2, 0xc1, 0x7e, 0xc2, 0x0d, 0x6b, 0xc8, 0xfd, 0x21, 0x20, 0x4a,
843 0xf5, 0x28, 0x08, 0x45, 0x10, 0x76, 0xcf, 0xf6, 0x87, 0x40, 0x71, 0x64, 0xa2, 0x1d,
844 0x35, 0x2d, 0xdd, 0xa2, 0x61, 0xab, 0xed, 0x59, 0x4a, 0x3c, 0x28, 0x44, 0x0c, 0x70,
845 0x99, 0x86, 0x7f, 0xd3, 0xe0, 0xf7, 0xa8, 0x12, 0x32, 0x1b, 0x37, 0xe4, 0x42, 0xf7,
846 0x17, 0xe2, 0xe9, 0xc2, 0x6e, 0x9b, 0xef, 0x07
847 ]
848 );
849
850 assert_eq!(
851 roi.to_fields(),
852 [
853 Fp::from_hex("e05c25d2c17ec20d6bc8fd21204af52808451076cff687407164a21d352ddd22")
854 .expect("failed to create field"),
855 Fp::from_hex("86adb66729f1a01031c0651afe4d83dfa34ac86cdc900bdd5f88a70bbb6dbe1f")
856 .expect("failed to create field"),
857 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
858 .expect("failed to create field"),
859 ]
860 );
861 }
862
863 #[test]
864 fn to_fields_2_bits_scalar_u32() {
865 let roi = ROInput::new()
866 .append_bool(true)
867 .append_bool(false)
868 .append_scalar(
869 Fq::from_hex("689634de233b06251a80ac7df64483922727757eea1adc6f0c8f184441cfe10d")
870 .expect("failed to create scalar"),
871 )
872 .append_u32(834_803);
873
874 assert_eq!(
875 roi.to_bytes(),
876 [
877 0xa1, 0x59, 0xd2, 0x78, 0x8f, 0xec, 0x18, 0x94, 0x68, 0x00, 0xb2, 0xf6, 0xd9, 0x13,
878 0x0d, 0x4a, 0x9e, 0x9c, 0xd4, 0xf9, 0xa9, 0x6b, 0x70, 0xbf, 0x31, 0x3c, 0x62, 0x10,
879 0x05, 0x3d, 0x87, 0x37, 0xe6, 0x79, 0x19, 0x00, 0x00
880 ]
881 );
882
883 assert_eq!(
884 roi.to_fields(),
885 [
886 Fp::from_hex("a159d2788fec18946800b2f6d9130d4a9e9cd4f9a96b70bf313c6210053d8737")
887 .expect("failed to create field"),
888 Fp::from_hex("98e7650000000000000000000000000000000000000000000000000000000000")
889 .expect("failed to create field"),
890 ]
891 );
892 }
893
894 #[test]
895 fn to_fields_2_bits_field_scalar() {
896 let roi = ROInput::new()
897 .append_bool(false)
898 .append_bool(true)
899 .append_field(
900 Fp::from_hex("90926b620ad09ed616d5df158504faed42928719c58ae619d9eccc062f920411")
901 .expect("failed to create field"),
902 )
903 .append_scalar(
904 Fq::from_hex("689634de233b06251a80ac7df64483922727757eea1adc6f0c8f184441cfe10d")
905 .expect("failed to create scalar"),
906 );
907
908 assert_eq!(
909 roi.to_bytes(),
910 [
911 0x90, 0x92, 0x6b, 0x62, 0x0a, 0xd0, 0x9e, 0xd6, 0x16, 0xd5, 0xdf, 0x15, 0x85, 0x04,
912 0xfa, 0xed, 0x42, 0x92, 0x87, 0x19, 0xc5, 0x8a, 0xe6, 0x19, 0xd9, 0xec, 0xcc, 0x06,
913 0x2f, 0x92, 0x04, 0x11, 0xd1, 0x2c, 0x69, 0xbc, 0x47, 0x76, 0x0c, 0x4a, 0x34, 0x00,
914 0x59, 0xfb, 0xec, 0x89, 0x06, 0x25, 0x4f, 0x4e, 0xea, 0xfc, 0xd4, 0x35, 0xb8, 0xdf,
915 0x18, 0x1e, 0x31, 0x88, 0x82, 0x9e, 0xc3, 0x1b
916 ]
917 );
918
919 assert_eq!(
920 roi.to_fields(),
921 [
922 Fp::from_hex("90926b620ad09ed616d5df158504faed42928719c58ae619d9eccc062f920411")
923 .expect("failed to create field"),
924 Fp::from_hex("a259d2788fec18946800b2f6d9130d4a9e9cd4f9a96b70bf313c6210053d8737")
925 .expect("failed to create field"),
926 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
927 .expect("failed to create field"),
928 ]
929 );
930 }
931
932 #[test]
933 fn transaction_test_1() {
934 let roi = ROInput::new()
935 .append_field(
936 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
937 .expect("failed to create field"),
938 ) .append_field(
940 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
941 .expect("failed to create field"),
942 ) .append_field(
944 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
945 .expect("failed to create field"),
946 ) .append_u64(1_000_000) .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(10_000_000_000) .append_bool(false); assert_eq!(roi.bits.len() + roi.fields.len() * 255, 1364);
962 assert_eq!(
963 roi.to_bytes(),
964 [
965 0x41, 0x20, 0x3c, 0x6b, 0xba, 0xc1, 0x4b, 0x35, 0x73, 0x01, 0xe1, 0xf3, 0x86, 0xd8,
966 0x0f, 0x52, 0x12, 0x3f, 0xd0, 0x0f, 0x02, 0x19, 0x74, 0x91, 0xb6, 0x90, 0xbd, 0xdf,
967 0xa7, 0x42, 0xca, 0xa2, 0x4c, 0x16, 0x6d, 0xf9, 0x4f, 0xff, 0x0a, 0x59, 0x5e, 0xf5,
968 0x2e, 0x00, 0x72, 0xcc, 0xf6, 0xa7, 0xff, 0xe8, 0x8b, 0xe0, 0x4b, 0xf8, 0xfc, 0x42,
969 0x43, 0xf2, 0x82, 0x7b, 0x17, 0x7c, 0x47, 0xc0, 0x8f, 0xee, 0xd3, 0xe9, 0x86, 0x73,
970 0x43, 0xff, 0x7d, 0x02, 0xf6, 0x89, 0x11, 0x8c, 0x8d, 0x75, 0x0a, 0x05, 0xd6, 0xf7,
971 0xfb, 0xdd, 0x8b, 0xbd, 0xd7, 0x61, 0x6f, 0xdb, 0x86, 0x87, 0x81, 0x0a, 0x48, 0xe8,
972 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
973 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
974 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
975 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
976 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x5f, 0xa0, 0x12, 0x00,
977 0x00, 0x00, 0x00
978 ]
979 );
980
981 assert_eq!(
982 roi.to_fields(),
983 [
984 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
985 .expect("failed to create field"),
986 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
987 .expect("failed to create field"),
988 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
989 .expect("failed to create field"),
990 Fp::from_hex("40420f0000000000010000000000000001000000feffffff0100000000000000")
991 .expect("failed to create field"),
992 Fp::from_hex("0000000000000000000000000000000000000000000000000000400100000000")
993 .expect("failed to create field"),
994 Fp::from_hex("00000000902f5009000000000000000000000000000000000000000000000000")
995 .expect("failed to create field"),
996 ]
997 );
998 }
999
1000 #[test]
1001 fn nested_roinput_test() {
1002 #[derive(Clone, Debug)]
1003 struct A {
1004 x: u32,
1005 y: bool,
1006 z: u32,
1007 }
1008
1009 impl Hashable for A {
1010 type D = ();
1011
1012 fn to_roinput(&self) -> ROInput {
1013 ROInput::new()
1014 .append_u32(self.x)
1015 .append_bool(self.y)
1016 .append_u32(self.z)
1017 }
1018
1019 fn domain_string((): Self::D) -> Option<String> {
1020 "A".to_string().into()
1021 }
1022 }
1023
1024 #[derive(Clone, Debug)]
1025 struct B1 {
1026 a: A,
1027 b: u64,
1028 c: bool,
1029 }
1030
1031 impl Hashable for B1 {
1032 type D = ();
1033
1034 fn to_roinput(&self) -> ROInput {
1035 self.a.to_roinput().append_u64(self.b).append_bool(self.c)
1036 }
1037
1038 fn domain_string((): Self::D) -> Option<String> {
1039 "B".to_string().into()
1040 }
1041 }
1042
1043 #[derive(Clone, Debug)]
1044 struct B2 {
1045 a: A,
1046 b: u64,
1047 c: bool,
1048 }
1049
1050 impl Hashable for B2 {
1051 type D = ();
1052
1053 fn to_roinput(&self) -> ROInput {
1054 self.a
1055 .to_roinput()
1056 .append_roinput(ROInput::new().append_u64(self.b).append_bool(self.c))
1057 }
1058
1059 fn domain_string((): Self::D) -> Option<String> {
1060 "B".to_string().into()
1061 }
1062 }
1063
1064 let a = A {
1065 x: 16_830_533,
1066 y: false,
1067 z: 39_827_791,
1068 };
1069 let b1 = B1 {
1070 a,
1071 b: 124_819,
1072 c: true,
1073 };
1074 let b2 = B2 {
1075 a: b1.a.clone(),
1076 b: b1.b,
1077 c: b1.c,
1078 };
1079
1080 assert_eq!(b1.to_roinput(), b2.to_roinput());
1081
1082 let b2 = B2 {
1083 a: b1.a.clone(),
1084 b: b1.b,
1085 c: false,
1086 };
1087 assert_ne!(b1.to_roinput(), b2.to_roinput());
1088
1089 let b2 = B2 {
1090 a: b1.a.clone(),
1091 b: b1.b + 1,
1092 c: b1.c,
1093 };
1094 assert_ne!(b1.to_roinput(), b2.to_roinput());
1095 }
1096
1097 #[test]
1098 fn serialize_empty() {
1099 let roi = ROInput::new();
1100
1101 let serialized = roi.serialize();
1102
1103 assert_eq!(
1104 serialized,
1105 vec![0; SER_HEADER_SIZE],
1106 "Serialized empty ROInput should be zero bytes"
1107 );
1108
1109 let deserialized_roi =
1110 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput");
1111 assert_eq!(
1112 roi, deserialized_roi,
1113 "Serialized and deserialized ROInput do not match"
1114 );
1115 }
1116
1117 #[test]
1118 fn serialize_single_field() {
1119 let roi = ROInput::new().append_field(
1120 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
1121 .expect("failed to create field"),
1122 );
1123
1124 let serialized = roi.serialize();
1125 let expected_length = SER_HEADER_SIZE + 32; assert_eq!(
1127 serialized.len(),
1128 expected_length,
1129 "Serialized ROInput length mismatch"
1130 );
1131 assert_eq!(
1132 serialized,
1133 [
1134 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x3c, 0x6b, 0xba, 0xc1, 0x4b, 0x35, 0x73, 0x01, 0xe1, 0xf3, 0x86, 0xd8,
1137 0x0f, 0x52, 0x12, 0x3f, 0xd0, 0x0f, 0x02, 0x19, 0x74, 0x91, 0xb6, 0x90, 0xbd, 0xdf,
1138 0xa7, 0x42, 0xca, 0x22
1139 ]
1140 .to_vec(),
1141 "Serialized ROInput does not match expected output"
1142 );
1143
1144 assert_eq!(
1145 roi,
1146 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput"),
1147 "Serialized and deserialized ROInput do not match"
1148 );
1149 }
1150
1151 #[test]
1152 fn serialize_single_bool() {
1153 let roi = ROInput::new().append_bool(true);
1154
1155 let serialized = roi.serialize();
1156 let expected_length = SER_HEADER_SIZE + 1; assert_eq!(
1158 serialized.len(),
1159 expected_length,
1160 "Serialized ROInput length mismatch"
1161 );
1162 assert_eq!(
1163 serialized,
1164 [
1165 0x00, 0x00, 0x00, 0x00,
1166 0x01, 0x00, 0x00, 0x00,
1167 0x01 ]
1169 .to_vec(),
1170 "Serialized ROInput does not match expected output"
1171 );
1172
1173 assert_eq!(
1174 roi,
1175 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput"),
1176 "Serialized and deserialized ROInput do not match"
1177 );
1178 }
1179
1180 #[test]
1181 fn serialize_multiple_bools_length() {
1182 for i in 0..1024 {
1183 let roi = ROInput::new().append_bool(i % 2 == 0);
1184 let serialized = roi.serialize();
1185
1186 let deserialized_roi =
1188 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput");
1189 assert_eq!(
1190 roi, deserialized_roi,
1191 "Serialized and deserialized ROInput do not match for i={i}"
1192 );
1193 }
1194 }
1195
1196 #[test]
1197 fn deserialize_invalid() {
1198 let invalid_data = vec![0x01, 0x00, 0x00, 0x00]; let result = ROInput::deserialize(&invalid_data);
1201 assert!(
1202 result.is_err(),
1203 "Deserialization should fail for invalid data"
1204 );
1205 }
1206
1207 #[test]
1208 fn deserialize_invalid_inconsistent_bitlen() {
1209 let invalid_data = vec![
1210 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, ];
1215
1216 let result = ROInput::deserialize(&invalid_data);
1217 assert!(
1218 result.is_err(),
1219 "Deserialization should fail for inconsistent bit length"
1220 );
1221 }
1222
1223 #[test]
1224 fn deserialize_invalid_message() {
1225 let msg = b"Test message for Mina compatibility".to_vec();
1226 let result = ROInput::deserialize(&msg);
1227 assert!(
1228 result.is_err(),
1229 "Deserialization should fail for invalid message format"
1230 );
1231 }
1232
1233 #[test]
1234 fn deserialize_invalid_fieldheader() {
1235 let invalid_data = vec![
1236 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x01, ];
1241
1242 let result = ROInput::deserialize(&invalid_data);
1243 assert!(
1244 result.is_err(),
1245 "Deserialization should fail for overflow in field header"
1246 );
1247 }
1248
1249 #[test]
1250 fn serialize_tx() {
1251 let tx_roi = ROInput::new()
1252 .append_field(
1253 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
1254 .expect("failed to create field"),
1255 )
1256 .append_field(
1257 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
1258 .expect("failed to create field"),
1259 ) .append_field(
1261 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
1262 .expect("failed to create field"),
1263 ) .append_u64(1_000_000) .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(10_000_000_000) .append_bool(false); let tx_bytes = tx_roi.serialize();
1280
1281 let deserialized_roi =
1282 ROInput::deserialize(&tx_bytes).expect("Failed to deserialize ROInput");
1283
1284 assert_eq!(
1285 tx_roi, deserialized_roi,
1286 "Serialized and deserialized ROInput do not match"
1287 );
1288 }
1289}