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_eq!(roi.bits.len(), 1);
331 assert_eq!(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_eq!(roi.bits.len(), 2);
338 assert_eq!(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_eq!(roi.bits.len(), 5);
350 assert_eq!(roi.bits.as_raw_slice(), [0x12]);
351 }
352
353 #[test]
354 fn append_byte() {
355 let roi = ROInput::new().append_bytes(&[0x01]);
356 assert_eq!(roi.bits.len(), 8);
357 assert_eq!(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_eq!(roi.bits.len(), 16);
364 assert_eq!(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_eq!(roi.bits.len(), 40);
371 assert_eq!(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_eq!(roi.bits.len(), 263);
406 assert_eq!(
407 roi.bits.as_raw_slice(),
408 [
409 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa, 0x28,
410 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5, 0xdd, 0x6f,
411 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_eq!(roi.bits.len(), 510);
426 assert_eq!(
427 roi.bits.as_raw_slice(),
428 [
429 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa, 0x28,
430 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5, 0xdd, 0x6f,
431 0x17, 0x44, 0x42, 0x96, 0xd0, 0xd8, 0x74, 0xa4, 0xc1, 0xad, 0xf1, 0xa0, 0x93, 0x3a,
432 0xa4, 0x09, 0x27, 0x87, 0xff, 0xd5, 0xed, 0xe5, 0xca, 0x5b, 0x21, 0xf4, 0xe2, 0xf4,
433 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_eq!(roi.bits.len(), 518);
451 assert_eq!(
452 roi.bits.as_raw_slice(),
453 [
454 0x60, 0xdb, 0x6f, 0x4f, 0x5b, 0x8c, 0xe1, 0xc7, 0xcb, 0x74, 0x7f, 0xba, 0x9e, 0x32,
455 0x4c, 0xc3, 0x26, 0x8c, 0x7a, 0x6e, 0x3f, 0x43, 0xcd, 0x82, 0xd4, 0x51, 0xae, 0x99,
456 0xa7, 0xb2, 0xbd, 0x1f, 0x15, 0xff, 0xbb, 0xba, 0x58, 0x03, 0xde, 0x75, 0xac, 0x79,
457 0x71, 0x1f, 0x2d, 0xa7, 0xdc, 0x4f, 0xa0, 0x25, 0x47, 0xec, 0x67, 0x15, 0xff, 0x77,
458 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_eq!(roi.bits.len(), 32);
509 assert_eq!(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_eq!(roi.bits.len(), 65);
519 assert_eq!(
520 roi.bits.as_raw_slice(),
521 [0xc1, 0x06, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01]
522 );
523 }
524
525 #[test]
526 fn append_u64() {
527 let roi = ROInput::new().append_u64(6174u64);
528 assert_eq!(roi.bits.len(), 64);
529 assert_eq!(
530 roi.bits.as_raw_slice(),
531 [0x1e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
532 );
533 }
534
535 #[test]
536 fn append_two_u64_and_bits() {
537 let roi = ROInput::new()
538 .append_bool(true)
539 .append_u64(u64::MAX / 6174u64)
540 .append_bool(false)
541 .append_u64(u64::MAX / 1111u64);
542 assert_eq!(roi.bits.len(), 130);
543 assert_eq!(
544 roi.bits.as_raw_slice(),
545 [
546 0xe1, 0x29, 0x89, 0xd6, 0xcb, 0x3a, 0x15, 0x00, 0x08, 0x17, 0xc4, 0x9b, 0x04, 0xf4,
547 0xeb, 0x00, 0x00
548 ]
549 );
550 }
551
552 #[test]
553 fn all_1() {
554 let roi = ROInput::new()
555 .append_bool(true)
556 .append_scalar(
557 Fq::from_hex("01d1755db21c8cd2a9cf5a3436178da3d70f484cd4b4c8834b799921e7d7a102")
558 .expect("failed to create scalar"),
559 )
560 .append_u64(18_446_744_073_709_551_557)
561 .append_bytes(&[0xba, 0xdc, 0x0f, 0xfe])
562 .append_scalar(
563 Fq::from_hex("e70187e9b125524489d0433da76fd8287fa652eaebde147b45fa0cd86f171810")
564 .expect("failed to create scalar"),
565 )
566 .append_bool(false)
567 .append_u32(2_147_483_647)
568 .append_bool(true);
569
570 assert_eq!(roi.bits.len(), 641);
571 assert_eq!(
572 roi.bits.as_raw_slice(),
573 [
574 0x03, 0xa2, 0xeb, 0xba, 0x64, 0x39, 0x18, 0xa5, 0x53, 0x9f, 0xb5, 0x68, 0x6c, 0x2e,
575 0x1a, 0x47, 0xaf, 0x1f, 0x90, 0x98, 0xa8, 0x69, 0x91, 0x07, 0x97, 0xf2, 0x32, 0x43,
576 0xce, 0xaf, 0x43, 0x05, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xba, 0xdc,
577 0x0f, 0xfe, 0xe7, 0x01, 0x87, 0xe9, 0xb1, 0x25, 0x52, 0x44, 0x89, 0xd0, 0x43, 0x3d,
578 0xa7, 0x6f, 0xd8, 0x28, 0x7f, 0xa6, 0x52, 0xea, 0xeb, 0xde, 0x14, 0x7b, 0x45, 0xfa,
579 0x0c, 0xd8, 0x6f, 0x17, 0x18, 0x10, 0xff, 0xff, 0xff, 0x7f, 0x01
580 ]
581 );
582 }
583
584 #[test]
585 fn transaction_bits() {
586 let roi = ROInput::new()
587 .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(
602 Fq::from_hex("de217a3017ca0b7a278e75f63c09890e3894be532d8dbadd30a7d450055f6d2d")
603 .expect("failed to create scalar"),
604 )
605 .append_bytes(&[0x01]);
606 assert_eq!(roi.bits.len(), 862);
607 assert_eq!(
608 roi.bits.as_raw_slice(),
609 [
610 0x40, 0x42, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
611 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
614 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x02,
615 0x95, 0x00, 0x00, 0x00, 0x00, 0xef, 0x10, 0x3d, 0x98, 0x0b, 0xe5, 0x05, 0xbd, 0x13,
616 0xc7, 0x3a, 0x7b, 0x9e, 0x84, 0x44, 0x07, 0x1c, 0x4a, 0xdf, 0xa9, 0x96, 0x46, 0xdd,
617 0x6e, 0x98, 0x53, 0x6a, 0xa8, 0x82, 0xaf, 0xb6, 0x56, 0x00
618 ]
619 );
620 }
621
622 #[test]
623 fn append_field() {
624 let roi = ROInput::new().append_field(
625 Fp::from_hex("2eaedae42a7461d5952d27b97ecad068b698ebb94e8a0e4c45388bb613de7e08")
626 .expect("failed to create field"),
627 );
628
629 assert_eq!(
630 roi.to_bytes(),
631 [
632 0x2e, 0xae, 0xda, 0xe4, 0x2a, 0x74, 0x61, 0xd5, 0x95, 0x2d, 0x27, 0xb9, 0x7e, 0xca,
633 0xd0, 0x68, 0xb6, 0x98, 0xeb, 0xb9, 0x4e, 0x8a, 0x0e, 0x4c, 0x45, 0x38, 0x8b, 0xb6,
634 0x13, 0xde, 0x7e, 0x08
635 ]
636 );
637 }
638
639 #[test]
640 fn append_two_fields() {
641 let roi = ROInput::new()
642 .append_field(
643 Fp::from_hex("0cdaf334e9632268a5aa959c2781fb32bf45565fe244ae42c849d3fdc7c6441d")
644 .expect("failed to create field"),
645 )
646 .append_field(
647 Fp::from_hex("2eaedae42a7461d5952d27b97ecad068b698ebb94e8a0e4c45388bb613de7e08")
648 .expect("failed to create field"),
649 );
650
651 assert_eq!(
652 roi.to_bytes(),
653 [
654 0x0c, 0xda, 0xf3, 0x34, 0xe9, 0x63, 0x22, 0x68, 0xa5, 0xaa, 0x95, 0x9c, 0x27, 0x81,
655 0xfb, 0x32, 0xbf, 0x45, 0x56, 0x5f, 0xe2, 0x44, 0xae, 0x42, 0xc8, 0x49, 0xd3, 0xfd,
656 0xc7, 0xc6, 0x44, 0x1d, 0x17, 0x57, 0x6d, 0x72, 0x15, 0xba, 0xb0, 0xea, 0xca, 0x96,
657 0x93, 0x5c, 0x3f, 0x65, 0x68, 0x34, 0x5b, 0xcc, 0xf5, 0x5c, 0x27, 0x45, 0x07, 0xa6,
658 0x22, 0x9c, 0x45, 0xdb, 0x09, 0x6f, 0x3f, 0x04
659 ]
660 );
661 }
662
663 #[test]
664 fn append_three_fields() {
665 let roi = ROInput::new()
666 .append_field(
667 Fp::from_hex("1f3f142986041b54427aa2032632e34df2fa9bde9bce70c04c5034266619e529")
668 .expect("failed to create field"),
669 )
670 .append_field(
671 Fp::from_hex("37f4433b85e753a91a1d79751645f1448954c433f9492e36a933ca7f3df61a04")
672 .expect("failed to create field"),
673 )
674 .append_field(
675 Fp::from_hex("6cf4772d3e1aab98a2b514b73a4f6e0df1fb4f703ecfa762196b22c26da4341c")
676 .expect("failed to create field"),
677 );
678
679 assert_eq!(
680 roi.to_bytes(),
681 [
682 0x1f, 0x3f, 0x14, 0x29, 0x86, 0x04, 0x1b, 0x54, 0x42, 0x7a, 0xa2, 0x03, 0x26, 0x32,
683 0xe3, 0x4d, 0xf2, 0xfa, 0x9b, 0xde, 0x9b, 0xce, 0x70, 0xc0, 0x4c, 0x50, 0x34, 0x26,
684 0x66, 0x19, 0xe5, 0xa9, 0x1b, 0xfa, 0xa1, 0x9d, 0xc2, 0xf3, 0xa9, 0x54, 0x8d, 0x8e,
685 0xbc, 0x3a, 0x8b, 0xa2, 0x78, 0xa2, 0x44, 0x2a, 0xe2, 0x99, 0xfc, 0x24, 0x17, 0x9b,
686 0xd4, 0x19, 0xe5, 0xbf, 0x1e, 0x7b, 0x0d, 0x02, 0x1b, 0xfd, 0x5d, 0x8b, 0x8f, 0xc6,
687 0x2a, 0xa6, 0x68, 0x2d, 0xc5, 0xad, 0xce, 0x93, 0x5b, 0x43, 0xfc, 0xfe, 0x13, 0x9c,
688 0xcf, 0xf3, 0xa9, 0x58, 0xc6, 0x9a, 0x88, 0x70, 0x1b, 0x29, 0x0d, 0x07
689 ]
690 );
691 }
692
693 #[test]
694 fn append_field_and_scalar() {
695 let roi = ROInput::new()
696 .append_field(
697 Fp::from_hex("64cde530327a36fcb88b6d769adca9b7c5d266e7d0042482203f3fd3a0d71721")
698 .expect("failed to create field"),
699 )
700 .append_scalar(
701 Fq::from_hex("604355d0daa455db783fd7ee11c5bd9b04d67ba64c27c95bef95e379f98c6432")
702 .expect("failed to create scalar"),
703 );
704
705 assert_eq!(
706 roi.to_bytes(),
707 [
708 0x64, 0xcd, 0xe5, 0x30, 0x32, 0x7a, 0x36, 0xfc, 0xb8, 0x8b, 0x6d, 0x76, 0x9a, 0xdc,
709 0xa9, 0xb7, 0xc5, 0xd2, 0x66, 0xe7, 0xd0, 0x04, 0x24, 0x82, 0x20, 0x3f, 0x3f, 0xd3,
710 0xa0, 0xd7, 0x17, 0x21, 0xb0, 0xa1, 0x2a, 0x68, 0x6d, 0xd2, 0xaa, 0x6d, 0xbc, 0x9f,
711 0x6b, 0xf7, 0x88, 0xe2, 0xde, 0x4d, 0x02, 0xeb, 0x3d, 0x53, 0xa6, 0x93, 0xe4, 0xad,
712 0xf7, 0xca, 0xf1, 0xbc, 0x7c, 0x46, 0x32, 0x19
713 ]
714 );
715 }
716
717 #[test]
718 fn append_field_bit_and_scalar() {
719 let roi = ROInput::new()
720 .append_field(
721 Fp::from_hex("d897c7a8b811d8acd3eeaa4adf42292802eed80031c2ad7c8989aea1fe94322c")
722 .expect("failed to create field"),
723 )
724 .append_bool(false)
725 .append_scalar(
726 Fq::from_hex("79586cc6b8b53c8991b2abe0ca76508f056ca50f06836ce4d818c2ff73d42b28")
727 .expect("failed to create scalar"),
728 );
729
730 assert_eq!(
731 roi.to_bytes(),
732 [
733 0xd8, 0x97, 0xc7, 0xa8, 0xb8, 0x11, 0xd8, 0xac, 0xd3, 0xee, 0xaa, 0x4a, 0xdf, 0x42,
734 0x29, 0x28, 0x02, 0xee, 0xd8, 0x00, 0x31, 0xc2, 0xad, 0x7c, 0x89, 0x89, 0xae, 0xa1,
735 0xfe, 0x94, 0x32, 0x2c, 0x79, 0x58, 0x6c, 0xc6, 0xb8, 0xb5, 0x3c, 0x89, 0x91, 0xb2,
736 0xab, 0xe0, 0xca, 0x76, 0x50, 0x8f, 0x05, 0x6c, 0xa5, 0x0f, 0x06, 0x83, 0x6c, 0xe4,
737 0xd8, 0x18, 0xc2, 0xff, 0x73, 0xd4, 0x2b, 0x28
738 ]
739 );
740 }
741
742 #[test]
743 fn to_bytes() {
744 let roi = ROInput::new()
745 .append_field(
746 Fp::from_hex("a5984f2bd00906f9a86e75bfb4b2c3625f1a0d1cfacc1501e8e82ae7041efc14")
747 .expect("failed to create field"),
748 )
749 .append_field(
750 Fp::from_hex("8af0bc770d49a5b9fcabfcdd033bab470b2a211ef80b710efe71315cfa818c0a")
751 .expect("failed to create field"),
752 )
753 .append_bool(false)
754 .append_u32(314u32)
755 .append_scalar(
756 Fq::from_hex("c23c43a23ddc1516578b0f0d81b93cdbbc97744acc697cfc8c5dfd01cc448323")
757 .expect("failed to create scalar"),
758 );
759
760 assert_eq!(
761 roi.to_bytes(),
762 [
763 0xa5, 0x98, 0x4f, 0x2b, 0xd0, 0x09, 0x06, 0xf9, 0xa8, 0x6e, 0x75, 0xbf, 0xb4, 0xb2,
764 0xc3, 0x62, 0x5f, 0x1a, 0x0d, 0x1c, 0xfa, 0xcc, 0x15, 0x01, 0xe8, 0xe8, 0x2a, 0xe7,
765 0x04, 0x1e, 0xfc, 0x14, 0x45, 0x78, 0xde, 0xbb, 0x86, 0xa4, 0xd2, 0x5c, 0xfe, 0x55,
766 0xfe, 0xee, 0x81, 0x9d, 0xd5, 0xa3, 0x05, 0x95, 0x10, 0x0f, 0xfc, 0x85, 0x38, 0x07,
767 0xff, 0xb8, 0x18, 0x2e, 0xfd, 0x40, 0x46, 0x05, 0x9d, 0x00, 0x00, 0x00, 0x61, 0x9e,
768 0x21, 0xd1, 0x1e, 0xee, 0x0a, 0x8b, 0xab, 0xc5, 0x87, 0x86, 0xc0, 0x5c, 0x9e, 0x6d,
769 0xde, 0x4b, 0x3a, 0x25, 0xe6, 0x34, 0x3e, 0x7e, 0xc6, 0xae, 0xfe, 0x00, 0x66, 0xa2,
770 0xc1, 0x11
771 ]
772 );
773 }
774
775 #[test]
776 fn to_fields_1_scalar() {
777 let roi = ROInput::new().append_scalar(
778 Fq::from_hex("5d496dd8ff63f640c006887098092b16bc8c78504f84fa1ee3a0b54f85f0a625")
779 .expect("failed to create scalar"),
780 );
781
782 assert_eq!(
783 roi.to_bytes(),
784 [
785 0x5d, 0x49, 0x6d, 0xd8, 0xff, 0x63, 0xf6, 0x40, 0xc0, 0x06, 0x88, 0x70, 0x98, 0x09,
786 0x2b, 0x16, 0xbc, 0x8c, 0x78, 0x50, 0x4f, 0x84, 0xfa, 0x1e, 0xe3, 0xa0, 0xb5, 0x4f,
787 0x85, 0xf0, 0xa6, 0x25
788 ]
789 );
790
791 assert_eq!(
792 roi.to_fields(),
793 [
794 Fp::from_hex("5d496dd8ff63f640c006887098092b16bc8c78504f84fa1ee3a0b54f85f0a625")
795 .expect("failed to create field"),
796 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
797 .expect("failed to create field"),
798 ]
799 );
800 }
801
802 #[test]
803 fn to_fields_1_scalar_2_bits() {
804 let roi = ROInput::new()
805 .append_scalar(
806 Fq::from_hex("e8a9961c8c417b0d0e3d7366f6b0e6ef90a6dad123070f715e8a9eaa02e47330")
807 .expect("failed to create scalar"),
808 )
809 .append_bool(false)
810 .append_bool(true);
811
812 assert_eq!(
813 roi.to_bytes(),
814 [
815 0xe8, 0xa9, 0x96, 0x1c, 0x8c, 0x41, 0x7b, 0x0d, 0x0e, 0x3d, 0x73, 0x66, 0xf6, 0xb0,
816 0xe6, 0xef, 0x90, 0xa6, 0xda, 0xd1, 0x23, 0x07, 0x0f, 0x71, 0x5e, 0x8a, 0x9e, 0xaa,
817 0x02, 0xe4, 0x73, 0x30, 0x01
818 ]
819 );
820
821 assert_eq!(
822 roi.to_fields(),
823 [
824 Fp::from_hex("e8a9961c8c417b0d0e3d7366f6b0e6ef90a6dad123070f715e8a9eaa02e47330")
825 .expect("failed to create field"),
826 Fp::from_hex("0400000000000000000000000000000000000000000000000000000000000000")
827 .expect("failed to create field"),
828 ]
829 );
830 }
831
832 #[test]
833 fn to_fields_2_scalars() {
834 let roi = ROInput::new()
835 .append_scalar(
836 Fq::from_hex("e05c25d2c17ec20d6bc8fd21204af52808451076cff687407164a21d352ddd22")
837 .expect("failed to create scalar"),
838 )
839 .append_scalar(
840 Fq::from_hex("c356dbb39478508818e0320dffa6c1ef512564366ec885ee2fc4d385dd36df0f")
841 .expect("failed to create scalar"),
842 );
843
844 assert_eq!(
845 roi.to_bytes(),
846 [
847 0xe0, 0x5c, 0x25, 0xd2, 0xc1, 0x7e, 0xc2, 0x0d, 0x6b, 0xc8, 0xfd, 0x21, 0x20, 0x4a,
848 0xf5, 0x28, 0x08, 0x45, 0x10, 0x76, 0xcf, 0xf6, 0x87, 0x40, 0x71, 0x64, 0xa2, 0x1d,
849 0x35, 0x2d, 0xdd, 0xa2, 0x61, 0xab, 0xed, 0x59, 0x4a, 0x3c, 0x28, 0x44, 0x0c, 0x70,
850 0x99, 0x86, 0x7f, 0xd3, 0xe0, 0xf7, 0xa8, 0x12, 0x32, 0x1b, 0x37, 0xe4, 0x42, 0xf7,
851 0x17, 0xe2, 0xe9, 0xc2, 0x6e, 0x9b, 0xef, 0x07
852 ]
853 );
854
855 assert_eq!(
856 roi.to_fields(),
857 [
858 Fp::from_hex("e05c25d2c17ec20d6bc8fd21204af52808451076cff687407164a21d352ddd22")
859 .expect("failed to create field"),
860 Fp::from_hex("86adb66729f1a01031c0651afe4d83dfa34ac86cdc900bdd5f88a70bbb6dbe1f")
861 .expect("failed to create field"),
862 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
863 .expect("failed to create field"),
864 ]
865 );
866 }
867
868 #[test]
869 fn to_fields_2_bits_scalar_u32() {
870 let roi = ROInput::new()
871 .append_bool(true)
872 .append_bool(false)
873 .append_scalar(
874 Fq::from_hex("689634de233b06251a80ac7df64483922727757eea1adc6f0c8f184441cfe10d")
875 .expect("failed to create scalar"),
876 )
877 .append_u32(834_803);
878
879 assert_eq!(
880 roi.to_bytes(),
881 [
882 0xa1, 0x59, 0xd2, 0x78, 0x8f, 0xec, 0x18, 0x94, 0x68, 0x00, 0xb2, 0xf6, 0xd9, 0x13,
883 0x0d, 0x4a, 0x9e, 0x9c, 0xd4, 0xf9, 0xa9, 0x6b, 0x70, 0xbf, 0x31, 0x3c, 0x62, 0x10,
884 0x05, 0x3d, 0x87, 0x37, 0xe6, 0x79, 0x19, 0x00, 0x00
885 ]
886 );
887
888 assert_eq!(
889 roi.to_fields(),
890 [
891 Fp::from_hex("a159d2788fec18946800b2f6d9130d4a9e9cd4f9a96b70bf313c6210053d8737")
892 .expect("failed to create field"),
893 Fp::from_hex("98e7650000000000000000000000000000000000000000000000000000000000")
894 .expect("failed to create field"),
895 ]
896 );
897 }
898
899 #[test]
900 fn to_fields_2_bits_field_scalar() {
901 let roi = ROInput::new()
902 .append_bool(false)
903 .append_bool(true)
904 .append_field(
905 Fp::from_hex("90926b620ad09ed616d5df158504faed42928719c58ae619d9eccc062f920411")
906 .expect("failed to create field"),
907 )
908 .append_scalar(
909 Fq::from_hex("689634de233b06251a80ac7df64483922727757eea1adc6f0c8f184441cfe10d")
910 .expect("failed to create scalar"),
911 );
912
913 assert_eq!(
914 roi.to_bytes(),
915 [
916 0x90, 0x92, 0x6b, 0x62, 0x0a, 0xd0, 0x9e, 0xd6, 0x16, 0xd5, 0xdf, 0x15, 0x85, 0x04,
917 0xfa, 0xed, 0x42, 0x92, 0x87, 0x19, 0xc5, 0x8a, 0xe6, 0x19, 0xd9, 0xec, 0xcc, 0x06,
918 0x2f, 0x92, 0x04, 0x11, 0xd1, 0x2c, 0x69, 0xbc, 0x47, 0x76, 0x0c, 0x4a, 0x34, 0x00,
919 0x59, 0xfb, 0xec, 0x89, 0x06, 0x25, 0x4f, 0x4e, 0xea, 0xfc, 0xd4, 0x35, 0xb8, 0xdf,
920 0x18, 0x1e, 0x31, 0x88, 0x82, 0x9e, 0xc3, 0x1b
921 ]
922 );
923
924 assert_eq!(
925 roi.to_fields(),
926 [
927 Fp::from_hex("90926b620ad09ed616d5df158504faed42928719c58ae619d9eccc062f920411")
928 .expect("failed to create field"),
929 Fp::from_hex("a259d2788fec18946800b2f6d9130d4a9e9cd4f9a96b70bf313c6210053d8737")
930 .expect("failed to create field"),
931 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
932 .expect("failed to create field"),
933 ]
934 );
935 }
936
937 #[test]
938 fn transaction_test_1() {
939 let roi = ROInput::new()
940 .append_field(
941 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
942 .expect("failed to create field"),
943 ) .append_field(
945 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
946 .expect("failed to create field"),
947 ) .append_field(
949 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
950 .expect("failed to create field"),
951 ) .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);
967 assert_eq!(
968 roi.to_bytes(),
969 [
970 0x41, 0x20, 0x3c, 0x6b, 0xba, 0xc1, 0x4b, 0x35, 0x73, 0x01, 0xe1, 0xf3, 0x86, 0xd8,
971 0x0f, 0x52, 0x12, 0x3f, 0xd0, 0x0f, 0x02, 0x19, 0x74, 0x91, 0xb6, 0x90, 0xbd, 0xdf,
972 0xa7, 0x42, 0xca, 0xa2, 0x4c, 0x16, 0x6d, 0xf9, 0x4f, 0xff, 0x0a, 0x59, 0x5e, 0xf5,
973 0x2e, 0x00, 0x72, 0xcc, 0xf6, 0xa7, 0xff, 0xe8, 0x8b, 0xe0, 0x4b, 0xf8, 0xfc, 0x42,
974 0x43, 0xf2, 0x82, 0x7b, 0x17, 0x7c, 0x47, 0xc0, 0x8f, 0xee, 0xd3, 0xe9, 0x86, 0x73,
975 0x43, 0xff, 0x7d, 0x02, 0xf6, 0x89, 0x11, 0x8c, 0x8d, 0x75, 0x0a, 0x05, 0xd6, 0xf7,
976 0xfb, 0xdd, 0x8b, 0xbd, 0xd7, 0x61, 0x6f, 0xdb, 0x86, 0x87, 0x81, 0x0a, 0x48, 0xe8,
977 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
978 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
979 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
980 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
981 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x5f, 0xa0, 0x12, 0x00,
982 0x00, 0x00, 0x00
983 ]
984 );
985
986 assert_eq!(
987 roi.to_fields(),
988 [
989 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
990 .expect("failed to create field"),
991 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
992 .expect("failed to create field"),
993 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
994 .expect("failed to create field"),
995 Fp::from_hex("40420f0000000000010000000000000001000000feffffff0100000000000000")
996 .expect("failed to create field"),
997 Fp::from_hex("0000000000000000000000000000000000000000000000000000400100000000")
998 .expect("failed to create field"),
999 Fp::from_hex("00000000902f5009000000000000000000000000000000000000000000000000")
1000 .expect("failed to create field"),
1001 ]
1002 );
1003 }
1004
1005 #[test]
1006 fn nested_roinput_test() {
1007 #[derive(Clone, Debug)]
1008 struct A {
1009 x: u32,
1010 y: bool,
1011 z: u32,
1012 }
1013
1014 impl Hashable for A {
1015 type D = ();
1016
1017 fn to_roinput(&self) -> ROInput {
1018 ROInput::new()
1019 .append_u32(self.x)
1020 .append_bool(self.y)
1021 .append_u32(self.z)
1022 }
1023
1024 fn domain_string((): Self::D) -> Option<String> {
1025 "A".to_string().into()
1026 }
1027 }
1028
1029 #[derive(Clone, Debug)]
1030 struct B1 {
1031 a: A,
1032 b: u64,
1033 c: bool,
1034 }
1035
1036 impl Hashable for B1 {
1037 type D = ();
1038
1039 fn to_roinput(&self) -> ROInput {
1040 self.a.to_roinput().append_u64(self.b).append_bool(self.c)
1041 }
1042
1043 fn domain_string((): Self::D) -> Option<String> {
1044 "B".to_string().into()
1045 }
1046 }
1047
1048 #[derive(Clone, Debug)]
1049 struct B2 {
1050 a: A,
1051 b: u64,
1052 c: bool,
1053 }
1054
1055 impl Hashable for B2 {
1056 type D = ();
1057
1058 fn to_roinput(&self) -> ROInput {
1059 self.a
1060 .to_roinput()
1061 .append_roinput(ROInput::new().append_u64(self.b).append_bool(self.c))
1062 }
1063
1064 fn domain_string((): Self::D) -> Option<String> {
1065 "B".to_string().into()
1066 }
1067 }
1068
1069 let a = A {
1070 x: 16_830_533,
1071 y: false,
1072 z: 39_827_791,
1073 };
1074 let b1 = B1 {
1075 a,
1076 b: 124_819,
1077 c: true,
1078 };
1079 let b2 = B2 {
1080 a: b1.a.clone(),
1081 b: b1.b,
1082 c: b1.c,
1083 };
1084
1085 assert_eq!(b1.to_roinput(), b2.to_roinput());
1086
1087 let b2 = B2 {
1088 a: b1.a.clone(),
1089 b: b1.b,
1090 c: false,
1091 };
1092 assert_ne!(b1.to_roinput(), b2.to_roinput());
1093
1094 let b2 = B2 {
1095 a: b1.a.clone(),
1096 b: b1.b + 1,
1097 c: b1.c,
1098 };
1099 assert_ne!(b1.to_roinput(), b2.to_roinput());
1100 }
1101
1102 #[test]
1103 fn serialize_empty() {
1104 let roi = ROInput::new();
1105
1106 let serialized = roi.serialize();
1107
1108 assert_eq!(
1109 serialized,
1110 vec![0; SER_HEADER_SIZE],
1111 "Serialized empty ROInput should be zero bytes"
1112 );
1113
1114 let deserialized_roi =
1115 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput");
1116 assert_eq!(
1117 roi, deserialized_roi,
1118 "Serialized and deserialized ROInput do not match"
1119 );
1120 }
1121
1122 #[test]
1123 fn serialize_single_field() {
1124 let roi = ROInput::new().append_field(
1125 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
1126 .expect("failed to create field"),
1127 );
1128
1129 let serialized = roi.serialize();
1130 let expected_length = SER_HEADER_SIZE + 32; assert_eq!(
1132 serialized.len(),
1133 expected_length,
1134 "Serialized ROInput length mismatch"
1135 );
1136 assert_eq!(
1137 serialized,
1138 [
1139 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x3c, 0x6b, 0xba, 0xc1, 0x4b, 0x35, 0x73, 0x01, 0xe1, 0xf3, 0x86, 0xd8,
1142 0x0f, 0x52, 0x12, 0x3f, 0xd0, 0x0f, 0x02, 0x19, 0x74, 0x91, 0xb6, 0x90, 0xbd, 0xdf,
1143 0xa7, 0x42, 0xca, 0x22
1144 ]
1145 .to_vec(),
1146 "Serialized ROInput does not match expected output"
1147 );
1148
1149 assert_eq!(
1150 roi,
1151 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput"),
1152 "Serialized and deserialized ROInput do not match"
1153 );
1154 }
1155
1156 #[test]
1157 fn serialize_single_bool() {
1158 let roi = ROInput::new().append_bool(true);
1159
1160 let serialized = roi.serialize();
1161 let expected_length = SER_HEADER_SIZE + 1; assert_eq!(
1163 serialized.len(),
1164 expected_length,
1165 "Serialized ROInput length mismatch"
1166 );
1167 assert_eq!(
1168 serialized,
1169 [
1170 0x00, 0x00, 0x00, 0x00,
1171 0x01, 0x00, 0x00, 0x00,
1172 0x01 ]
1174 .to_vec(),
1175 "Serialized ROInput does not match expected output"
1176 );
1177
1178 assert_eq!(
1179 roi,
1180 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput"),
1181 "Serialized and deserialized ROInput do not match"
1182 );
1183 }
1184
1185 #[test]
1186 fn serialize_multiple_bools_length() {
1187 for i in 0..1024 {
1188 let roi = ROInput::new().append_bool(i % 2 == 0);
1189 let serialized = roi.serialize();
1190
1191 let deserialized_roi =
1193 ROInput::deserialize(&serialized).expect("Failed to deserialize ROInput");
1194 assert_eq!(
1195 roi, deserialized_roi,
1196 "Serialized and deserialized ROInput do not match for i={i}"
1197 );
1198 }
1199 }
1200
1201 #[test]
1202 fn deserialize_invalid() {
1203 let invalid_data = vec![0x01, 0x00, 0x00, 0x00]; let result = ROInput::deserialize(&invalid_data);
1206 assert!(
1207 result.is_err(),
1208 "Deserialization should fail for invalid data"
1209 );
1210 }
1211
1212 #[test]
1213 fn deserialize_invalid_inconsistent_bitlen() {
1214 let invalid_data = vec![
1215 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, ];
1220
1221 let result = ROInput::deserialize(&invalid_data);
1222 assert!(
1223 result.is_err(),
1224 "Deserialization should fail for inconsistent bit length"
1225 );
1226 }
1227
1228 #[test]
1229 fn deserialize_invalid_message() {
1230 let msg = b"Test message for Mina compatibility".to_vec();
1231 let result = ROInput::deserialize(&msg);
1232 assert!(
1233 result.is_err(),
1234 "Deserialization should fail for invalid message format"
1235 );
1236 }
1237
1238 #[test]
1239 fn deserialize_invalid_fieldheader() {
1240 let invalid_data = vec![
1241 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x01, ];
1246
1247 let result = ROInput::deserialize(&invalid_data);
1248 assert!(
1249 result.is_err(),
1250 "Deserialization should fail for overflow in field header"
1251 );
1252 }
1253
1254 #[test]
1255 fn serialize_tx() {
1256 let tx_roi = ROInput::new()
1257 .append_field(
1258 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
1259 .expect("failed to create field"),
1260 )
1261 .append_field(
1262 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
1263 .expect("failed to create field"),
1264 ) .append_field(
1266 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
1267 .expect("failed to create field"),
1268 ) .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();
1285
1286 let deserialized_roi =
1287 ROInput::deserialize(&tx_bytes).expect("Failed to deserialize ROInput");
1288
1289 assert_eq!(
1290 tx_roi, deserialized_roi,
1291 "Serialized and deserialized ROInput do not match"
1292 );
1293 }
1294}