1use super::Hashable;
7use alloc::{vec, vec::Vec};
8use ark_ff::PrimeField;
9use bitvec::{prelude::*, view::AsBits};
10use mina_curves::pasta::{Fp, Fq};
11use o1_utils::FieldHelpers;
12
13#[derive(Default, Debug, Clone, PartialEq, Eq)]
57pub struct ROInput {
58 fields: Vec<Fp>,
59 bits: BitVec<u8>,
60}
61
62impl ROInput {
63 pub fn new() -> Self {
65 ROInput {
66 fields: vec![],
67 bits: BitVec::new(),
68 }
69 }
70
71 pub fn append_hashable(self, input: &impl Hashable) -> Self {
73 self.append_roinput(input.to_roinput())
74 }
75
76 pub fn append_roinput(mut self, mut roi: ROInput) -> Self {
78 self.fields.append(&mut roi.fields);
79 self.bits.extend(roi.bits);
80 self
81 }
82
83 pub fn append_field(mut self, f: Fp) -> Self {
85 self.fields.push(f);
86 self
87 }
88
89 pub fn append_scalar(mut self, s: Fq) -> Self {
91 let bytes = s.to_bytes();
93 let bits = &bytes.as_bits::<Lsb0>()[..Fq::MODULUS_BIT_SIZE as usize];
94 self.bits.extend(bits);
95 self
96 }
97
98 pub fn append_bool(mut self, b: bool) -> Self {
100 self.bits.push(b);
101 self
102 }
103
104 pub fn append_bytes(mut self, bytes: &[u8]) -> Self {
106 self.bits.extend_from_bitslice(bytes.as_bits::<Lsb0>());
107 self
108 }
109
110 pub fn append_u32(self, x: u32) -> Self {
112 self.append_bytes(&x.to_le_bytes())
113 }
114
115 pub fn append_u64(self, x: u64) -> Self {
117 self.append_bytes(&x.to_le_bytes())
118 }
119
120 pub fn to_bytes(&self) -> Vec<u8> {
122 let mut bits: BitVec<u8> = self.fields.iter().fold(BitVec::new(), |mut acc, fe| {
123 acc.extend_from_bitslice(
124 &fe.to_bytes().as_bits::<Lsb0>()[..Fp::MODULUS_BIT_SIZE as usize],
125 );
126
127 acc
128 });
129
130 bits.extend(&self.bits);
131
132 bits.into()
133 }
134
135 pub fn to_fields(&self) -> Vec<Fp> {
137 let mut fields: Vec<Fp> = self.fields.clone();
138
139 let bits_as_fields =
140 self.bits
141 .chunks(Fp::MODULUS_BIT_SIZE as usize - 1)
142 .fold(vec![], |mut acc, chunk| {
143 let mut bv = BitVec::<u8>::new();
157 bv.resize(chunk.len(), false);
158 bv.clone_from_bitslice(chunk);
159
160 bv.resize(Fp::MODULUS_BIT_SIZE as usize, false);
162
163 acc.push(
164 Fp::from_bytes(&bv.into_vec())
165 .expect("failed to create base field element"),
166 );
167
168 acc
169 });
170
171 fields.extend(bits_as_fields);
172
173 fields
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use super::*;
180 use crate::{
181 alloc::string::{String, ToString},
182 Hashable,
183 };
184
185 #[test]
186 fn append_bool() {
187 let roi = ROInput::new().append_bool(true);
188 assert!(roi.bits.len() == 1);
189 assert!(roi.bits.as_raw_slice() == [0x01]);
190 }
191
192 #[test]
193 fn append_two_bits() {
194 let roi = ROInput::new().append_bool(false).append_bool(true);
195 assert!(roi.bits.len() == 2);
196 assert!(roi.bits.as_raw_slice() == [0x02]);
197 }
198
199 #[test]
200 fn append_five_bits() {
201 let roi = ROInput::new()
202 .append_bool(false)
203 .append_bool(true)
204 .append_bool(false)
205 .append_bool(false)
206 .append_bool(true);
207 assert!(roi.bits.len() == 5);
208 assert!(roi.bits.as_raw_slice() == [0x12]);
209 }
210
211 #[test]
212 fn append_byte() {
213 let roi = ROInput::new().append_bytes(&[0x01]);
214 assert!(roi.bits.len() == 8);
215 assert!(roi.bits.as_raw_slice() == [0x01]);
216 }
217
218 #[test]
219 fn append_two_bytes() {
220 let roi = ROInput::new().append_bytes(&[0x10, 0xac]);
221 assert!(roi.bits.len() == 16);
222 assert!(roi.bits.as_raw_slice() == [0x10, 0xac]);
223 }
224
225 #[test]
226 fn append_five_bytes() {
227 let roi = ROInput::new().append_bytes(&[0x10, 0xac, 0x01, 0xeb, 0xca]);
228 assert!(roi.bits.len() == 40);
229 assert!(roi.bits.as_raw_slice() == [0x10, 0xac, 0x01, 0xeb, 0xca]);
230 }
231
232 #[test]
233 fn append_scalar() {
234 let scalar =
235 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
236 .expect("failed to create scalar");
237 let roi = ROInput::new().append_scalar(scalar);
238 assert_eq!(roi.bits.len(), 255);
239 assert_eq!(
240 roi.bits.as_raw_slice(),
241 [
242 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa, 0x28,
243 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5, 0xdd, 0x6f,
244 0x17, 0x44, 0x42, 0x16
245 ]
246 );
247 assert_eq!(
248 roi.to_bytes(),
249 [
250 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa, 0x28,
251 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5, 0xdd, 0x6f,
252 0x17, 0x44, 0x42, 0x16
253 ]
254 );
255 }
256
257 #[test]
258 fn append_scalar_and_byte() {
259 let scalar =
260 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
261 .expect("failed to create scalar");
262 let roi = ROInput::new().append_scalar(scalar).append_bytes(&[0x01]);
263 assert!(roi.bits.len() == 263);
264 assert!(
265 roi.bits.as_raw_slice()
266 == [
267 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa,
268 0x28, 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5,
269 0xdd, 0x6f, 0x17, 0x44, 0x42, 0x96, 0x00
270 ]
271 );
272 }
273
274 #[test]
275 fn append_two_scalars() {
276 let scalar1 =
277 Fq::from_hex("18b7ef420128e69623c0c0dcfa28d47a029d462720deb769d7b5dd6f17444216")
278 .expect("failed to create scalar");
279 let scalar2 =
280 Fq::from_hex("a1b1e948835be341277548134e0effabdbcb95b742e8c5e967e9bf13eb4ae805")
281 .expect("failed to create scalar");
282 let roi = ROInput::new().append_scalar(scalar1).append_scalar(scalar2);
283 assert!(roi.bits.len() == 510);
284 assert!(
285 roi.bits.as_raw_slice()
286 == [
287 0x18, 0xb7, 0xef, 0x42, 0x01, 0x28, 0xe6, 0x96, 0x23, 0xc0, 0xc0, 0xdc, 0xfa,
288 0x28, 0xd4, 0x7a, 0x02, 0x9d, 0x46, 0x27, 0x20, 0xde, 0xb7, 0x69, 0xd7, 0xb5,
289 0xdd, 0x6f, 0x17, 0x44, 0x42, 0x96, 0xd0, 0xd8, 0x74, 0xa4, 0xc1, 0xad, 0xf1,
290 0xa0, 0x93, 0x3a, 0xa4, 0x09, 0x27, 0x87, 0xff, 0xd5, 0xed, 0xe5, 0xca, 0x5b,
291 0x21, 0xf4, 0xe2, 0xf4, 0xb3, 0xf4, 0xdf, 0x89, 0x75, 0x25, 0xf4, 0x02
292 ]
293 );
294 }
295
296 #[test]
297 fn append_two_scalars_and_byte() {
298 let scalar1 =
299 Fq::from_hex("60db6f4f5b8ce1c7cb747fba9e324cc3268c7a6e3f43cd82d451ae99a7b2bd1f")
300 .expect("failed to create scalar");
301 let scalar2 =
302 Fq::from_hex("fe7775b106bceb58f3e23e5a4eb99f404b8ed8cf2afeef9c9d1800f12138cd07")
303 .expect("failed to create scalar");
304 let roi = ROInput::new()
305 .append_scalar(scalar1)
306 .append_bytes(&[0x2a])
307 .append_scalar(scalar2);
308 assert!(roi.bits.len() == 518);
309 assert!(
310 roi.bits.as_raw_slice()
311 == [
312 0x60, 0xdb, 0x6f, 0x4f, 0x5b, 0x8c, 0xe1, 0xc7, 0xcb, 0x74, 0x7f, 0xba, 0x9e,
313 0x32, 0x4c, 0xc3, 0x26, 0x8c, 0x7a, 0x6e, 0x3f, 0x43, 0xcd, 0x82, 0xd4, 0x51,
314 0xae, 0x99, 0xa7, 0xb2, 0xbd, 0x1f, 0x15, 0xff, 0xbb, 0xba, 0x58, 0x03, 0xde,
315 0x75, 0xac, 0x79, 0x71, 0x1f, 0x2d, 0xa7, 0xdc, 0x4f, 0xa0, 0x25, 0x47, 0xec,
316 0x67, 0x15, 0xff, 0x77, 0xce, 0x4e, 0x0c, 0x80, 0xf8, 0x10, 0x9c, 0xe6, 0x03
317 ]
318 );
319 }
320
321 #[test]
322 fn append_u32() {
323 let roi = ROInput::new().append_u32(1984u32);
324 assert!(roi.bits.len() == 32);
325 assert!(roi.bits.as_raw_slice() == [0xc0, 0x07, 0x00, 0x00]);
326 }
327
328 #[test]
329 fn append_two_u32_and_bit() {
330 let roi = ROInput::new()
331 .append_u32(1729u32)
332 .append_bool(false)
333 .append_u32(u32::MAX);
334 assert!(roi.bits.len() == 65);
335 assert!(roi.bits.as_raw_slice() == [0xc1, 0x06, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01]);
336 }
337
338 #[test]
339 fn append_u64() {
340 let roi = ROInput::new().append_u64(6174u64);
341 assert!(roi.bits.len() == 64);
342 assert!(roi.bits.as_raw_slice() == [0x1e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
343 }
344
345 #[test]
346 fn append_two_u64_and_bits() {
347 let roi = ROInput::new()
348 .append_bool(true)
349 .append_u64(u64::MAX / 6174u64)
350 .append_bool(false)
351 .append_u64(u64::MAX / 1111u64);
352 assert!(roi.bits.len() == 130);
353 assert!(
354 roi.bits.as_raw_slice()
355 == [
356 0xe1, 0x29, 0x89, 0xd6, 0xcb, 0x3a, 0x15, 0x00, 0x08, 0x17, 0xc4, 0x9b, 0x04,
357 0xf4, 0xeb, 0x00, 0x00
358 ]
359 );
360 }
361
362 #[test]
363 fn all_1() {
364 let roi = ROInput::new()
365 .append_bool(true)
366 .append_scalar(
367 Fq::from_hex("01d1755db21c8cd2a9cf5a3436178da3d70f484cd4b4c8834b799921e7d7a102")
368 .expect("failed to create scalar"),
369 )
370 .append_u64(18446744073709551557)
371 .append_bytes(&[0xba, 0xdc, 0x0f, 0xfe])
372 .append_scalar(
373 Fq::from_hex("e70187e9b125524489d0433da76fd8287fa652eaebde147b45fa0cd86f171810")
374 .expect("failed to create scalar"),
375 )
376 .append_bool(false)
377 .append_u32(2147483647)
378 .append_bool(true);
379
380 assert!(roi.bits.len() == 641);
381 assert!(
382 roi.bits.as_raw_slice()
383 == [
384 0x03, 0xa2, 0xeb, 0xba, 0x64, 0x39, 0x18, 0xa5, 0x53, 0x9f, 0xb5, 0x68, 0x6c,
385 0x2e, 0x1a, 0x47, 0xaf, 0x1f, 0x90, 0x98, 0xa8, 0x69, 0x91, 0x07, 0x97, 0xf2,
386 0x32, 0x43, 0xce, 0xaf, 0x43, 0x05, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
387 0xff, 0xba, 0xdc, 0x0f, 0xfe, 0xe7, 0x01, 0x87, 0xe9, 0xb1, 0x25, 0x52, 0x44,
388 0x89, 0xd0, 0x43, 0x3d, 0xa7, 0x6f, 0xd8, 0x28, 0x7f, 0xa6, 0x52, 0xea, 0xeb,
389 0xde, 0x14, 0x7b, 0x45, 0xfa, 0x0c, 0xd8, 0x6f, 0x17, 0x18, 0x10, 0xff, 0xff,
390 0xff, 0x7f, 0x01
391 ]
392 );
393 }
394
395 #[test]
396 fn transaction_bits() {
397 let roi = ROInput::new()
398 .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(
413 Fq::from_hex("de217a3017ca0b7a278e75f63c09890e3894be532d8dbadd30a7d450055f6d2d")
414 .expect("failed to create scalar"),
415 )
416 .append_bytes(&[0x01]);
417 assert_eq!(roi.bits.len(), 862);
418 assert_eq!(
419 roi.bits.as_raw_slice(),
420 [
421 0x40, 0x42, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
422 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x02,
426 0x95, 0x00, 0x00, 0x00, 0x00, 0xef, 0x10, 0x3d, 0x98, 0x0b, 0xe5, 0x05, 0xbd, 0x13,
427 0xc7, 0x3a, 0x7b, 0x9e, 0x84, 0x44, 0x07, 0x1c, 0x4a, 0xdf, 0xa9, 0x96, 0x46, 0xdd,
428 0x6e, 0x98, 0x53, 0x6a, 0xa8, 0x82, 0xaf, 0xb6, 0x56, 0x00
429 ]
430 )
431 }
432
433 #[test]
434 fn append_field() {
435 let roi = ROInput::new().append_field(
436 Fp::from_hex("2eaedae42a7461d5952d27b97ecad068b698ebb94e8a0e4c45388bb613de7e08")
437 .expect("failed to create field"),
438 );
439
440 assert_eq!(
441 roi.to_bytes(),
442 [
443 0x2e, 0xae, 0xda, 0xe4, 0x2a, 0x74, 0x61, 0xd5, 0x95, 0x2d, 0x27, 0xb9, 0x7e, 0xca,
444 0xd0, 0x68, 0xb6, 0x98, 0xeb, 0xb9, 0x4e, 0x8a, 0x0e, 0x4c, 0x45, 0x38, 0x8b, 0xb6,
445 0x13, 0xde, 0x7e, 0x08
446 ]
447 );
448 }
449
450 #[test]
451 fn append_two_fields() {
452 let roi = ROInput::new()
453 .append_field(
454 Fp::from_hex("0cdaf334e9632268a5aa959c2781fb32bf45565fe244ae42c849d3fdc7c6441d")
455 .expect("failed to create field"),
456 )
457 .append_field(
458 Fp::from_hex("2eaedae42a7461d5952d27b97ecad068b698ebb94e8a0e4c45388bb613de7e08")
459 .expect("failed to create field"),
460 );
461
462 assert_eq!(
463 roi.to_bytes(),
464 [
465 0x0c, 0xda, 0xf3, 0x34, 0xe9, 0x63, 0x22, 0x68, 0xa5, 0xaa, 0x95, 0x9c, 0x27, 0x81,
466 0xfb, 0x32, 0xbf, 0x45, 0x56, 0x5f, 0xe2, 0x44, 0xae, 0x42, 0xc8, 0x49, 0xd3, 0xfd,
467 0xc7, 0xc6, 0x44, 0x1d, 0x17, 0x57, 0x6d, 0x72, 0x15, 0xba, 0xb0, 0xea, 0xca, 0x96,
468 0x93, 0x5c, 0x3f, 0x65, 0x68, 0x34, 0x5b, 0xcc, 0xf5, 0x5c, 0x27, 0x45, 0x07, 0xa6,
469 0x22, 0x9c, 0x45, 0xdb, 0x09, 0x6f, 0x3f, 0x04
470 ]
471 );
472 }
473
474 #[test]
475 fn append_three_fields() {
476 let roi = ROInput::new()
477 .append_field(
478 Fp::from_hex("1f3f142986041b54427aa2032632e34df2fa9bde9bce70c04c5034266619e529")
479 .expect("failed to create field"),
480 )
481 .append_field(
482 Fp::from_hex("37f4433b85e753a91a1d79751645f1448954c433f9492e36a933ca7f3df61a04")
483 .expect("failed to create field"),
484 )
485 .append_field(
486 Fp::from_hex("6cf4772d3e1aab98a2b514b73a4f6e0df1fb4f703ecfa762196b22c26da4341c")
487 .expect("failed to create field"),
488 );
489
490 assert_eq!(
491 roi.to_bytes(),
492 [
493 0x1f, 0x3f, 0x14, 0x29, 0x86, 0x04, 0x1b, 0x54, 0x42, 0x7a, 0xa2, 0x03, 0x26, 0x32,
494 0xe3, 0x4d, 0xf2, 0xfa, 0x9b, 0xde, 0x9b, 0xce, 0x70, 0xc0, 0x4c, 0x50, 0x34, 0x26,
495 0x66, 0x19, 0xe5, 0xa9, 0x1b, 0xfa, 0xa1, 0x9d, 0xc2, 0xf3, 0xa9, 0x54, 0x8d, 0x8e,
496 0xbc, 0x3a, 0x8b, 0xa2, 0x78, 0xa2, 0x44, 0x2a, 0xe2, 0x99, 0xfc, 0x24, 0x17, 0x9b,
497 0xd4, 0x19, 0xe5, 0xbf, 0x1e, 0x7b, 0x0d, 0x02, 0x1b, 0xfd, 0x5d, 0x8b, 0x8f, 0xc6,
498 0x2a, 0xa6, 0x68, 0x2d, 0xc5, 0xad, 0xce, 0x93, 0x5b, 0x43, 0xfc, 0xfe, 0x13, 0x9c,
499 0xcf, 0xf3, 0xa9, 0x58, 0xc6, 0x9a, 0x88, 0x70, 0x1b, 0x29, 0x0d, 0x07
500 ]
501 );
502 }
503
504 #[test]
505 fn append_field_and_scalar() {
506 let roi = ROInput::new()
507 .append_field(
508 Fp::from_hex("64cde530327a36fcb88b6d769adca9b7c5d266e7d0042482203f3fd3a0d71721")
509 .expect("failed to create field"),
510 )
511 .append_scalar(
512 Fq::from_hex("604355d0daa455db783fd7ee11c5bd9b04d67ba64c27c95bef95e379f98c6432")
513 .expect("failed to create scalar"),
514 );
515
516 assert_eq!(
517 roi.to_bytes(),
518 [
519 0x64, 0xcd, 0xe5, 0x30, 0x32, 0x7a, 0x36, 0xfc, 0xb8, 0x8b, 0x6d, 0x76, 0x9a, 0xdc,
520 0xa9, 0xb7, 0xc5, 0xd2, 0x66, 0xe7, 0xd0, 0x04, 0x24, 0x82, 0x20, 0x3f, 0x3f, 0xd3,
521 0xa0, 0xd7, 0x17, 0x21, 0xb0, 0xa1, 0x2a, 0x68, 0x6d, 0xd2, 0xaa, 0x6d, 0xbc, 0x9f,
522 0x6b, 0xf7, 0x88, 0xe2, 0xde, 0x4d, 0x02, 0xeb, 0x3d, 0x53, 0xa6, 0x93, 0xe4, 0xad,
523 0xf7, 0xca, 0xf1, 0xbc, 0x7c, 0x46, 0x32, 0x19
524 ]
525 );
526 }
527
528 #[test]
529 fn append_field_bit_and_scalar() {
530 let roi = ROInput::new()
531 .append_field(
532 Fp::from_hex("d897c7a8b811d8acd3eeaa4adf42292802eed80031c2ad7c8989aea1fe94322c")
533 .expect("failed to create field"),
534 )
535 .append_bool(false)
536 .append_scalar(
537 Fq::from_hex("79586cc6b8b53c8991b2abe0ca76508f056ca50f06836ce4d818c2ff73d42b28")
538 .expect("failed to create scalar"),
539 );
540
541 assert_eq!(
542 roi.to_bytes(),
543 [
544 0xd8, 0x97, 0xc7, 0xa8, 0xb8, 0x11, 0xd8, 0xac, 0xd3, 0xee, 0xaa, 0x4a, 0xdf, 0x42,
545 0x29, 0x28, 0x02, 0xee, 0xd8, 0x00, 0x31, 0xc2, 0xad, 0x7c, 0x89, 0x89, 0xae, 0xa1,
546 0xfe, 0x94, 0x32, 0x2c, 0x79, 0x58, 0x6c, 0xc6, 0xb8, 0xb5, 0x3c, 0x89, 0x91, 0xb2,
547 0xab, 0xe0, 0xca, 0x76, 0x50, 0x8f, 0x05, 0x6c, 0xa5, 0x0f, 0x06, 0x83, 0x6c, 0xe4,
548 0xd8, 0x18, 0xc2, 0xff, 0x73, 0xd4, 0x2b, 0x28
549 ]
550 );
551 }
552
553 #[test]
554 fn to_bytes() {
555 let roi = ROInput::new()
556 .append_field(
557 Fp::from_hex("a5984f2bd00906f9a86e75bfb4b2c3625f1a0d1cfacc1501e8e82ae7041efc14")
558 .expect("failed to create field"),
559 )
560 .append_field(
561 Fp::from_hex("8af0bc770d49a5b9fcabfcdd033bab470b2a211ef80b710efe71315cfa818c0a")
562 .expect("failed to create field"),
563 )
564 .append_bool(false)
565 .append_u32(314u32)
566 .append_scalar(
567 Fq::from_hex("c23c43a23ddc1516578b0f0d81b93cdbbc97744acc697cfc8c5dfd01cc448323")
568 .expect("failed to create scalar"),
569 );
570
571 assert_eq!(
572 roi.to_bytes(),
573 [
574 0xa5, 0x98, 0x4f, 0x2b, 0xd0, 0x09, 0x06, 0xf9, 0xa8, 0x6e, 0x75, 0xbf, 0xb4, 0xb2,
575 0xc3, 0x62, 0x5f, 0x1a, 0x0d, 0x1c, 0xfa, 0xcc, 0x15, 0x01, 0xe8, 0xe8, 0x2a, 0xe7,
576 0x04, 0x1e, 0xfc, 0x14, 0x45, 0x78, 0xde, 0xbb, 0x86, 0xa4, 0xd2, 0x5c, 0xfe, 0x55,
577 0xfe, 0xee, 0x81, 0x9d, 0xd5, 0xa3, 0x05, 0x95, 0x10, 0x0f, 0xfc, 0x85, 0x38, 0x07,
578 0xff, 0xb8, 0x18, 0x2e, 0xfd, 0x40, 0x46, 0x05, 0x9d, 0x00, 0x00, 0x00, 0x61, 0x9e,
579 0x21, 0xd1, 0x1e, 0xee, 0x0a, 0x8b, 0xab, 0xc5, 0x87, 0x86, 0xc0, 0x5c, 0x9e, 0x6d,
580 0xde, 0x4b, 0x3a, 0x25, 0xe6, 0x34, 0x3e, 0x7e, 0xc6, 0xae, 0xfe, 0x00, 0x66, 0xa2,
581 0xc1, 0x11
582 ]
583 );
584 }
585
586 #[test]
587 fn to_fields_1_scalar() {
588 let roi = ROInput::new().append_scalar(
589 Fq::from_hex("5d496dd8ff63f640c006887098092b16bc8c78504f84fa1ee3a0b54f85f0a625")
590 .expect("failed to create scalar"),
591 );
592
593 assert_eq!(
594 roi.to_bytes(),
595 [
596 0x5d, 0x49, 0x6d, 0xd8, 0xff, 0x63, 0xf6, 0x40, 0xc0, 0x06, 0x88, 0x70, 0x98, 0x09,
597 0x2b, 0x16, 0xbc, 0x8c, 0x78, 0x50, 0x4f, 0x84, 0xfa, 0x1e, 0xe3, 0xa0, 0xb5, 0x4f,
598 0x85, 0xf0, 0xa6, 0x25
599 ]
600 );
601
602 assert_eq!(
603 roi.to_fields(),
604 [
605 Fp::from_hex("5d496dd8ff63f640c006887098092b16bc8c78504f84fa1ee3a0b54f85f0a625")
606 .expect("failed to create field"),
607 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
608 .expect("failed to create field"),
609 ]
610 );
611 }
612
613 #[test]
614 fn to_fields_1_scalar_2_bits() {
615 let roi = ROInput::new()
616 .append_scalar(
617 Fq::from_hex("e8a9961c8c417b0d0e3d7366f6b0e6ef90a6dad123070f715e8a9eaa02e47330")
618 .expect("failed to create scalar"),
619 )
620 .append_bool(false)
621 .append_bool(true);
622
623 assert_eq!(
624 roi.to_bytes(),
625 [
626 0xe8, 0xa9, 0x96, 0x1c, 0x8c, 0x41, 0x7b, 0x0d, 0x0e, 0x3d, 0x73, 0x66, 0xf6, 0xb0,
627 0xe6, 0xef, 0x90, 0xa6, 0xda, 0xd1, 0x23, 0x07, 0x0f, 0x71, 0x5e, 0x8a, 0x9e, 0xaa,
628 0x02, 0xe4, 0x73, 0x30, 0x01
629 ]
630 );
631
632 assert_eq!(
633 roi.to_fields(),
634 [
635 Fp::from_hex("e8a9961c8c417b0d0e3d7366f6b0e6ef90a6dad123070f715e8a9eaa02e47330")
636 .expect("failed to create field"),
637 Fp::from_hex("0400000000000000000000000000000000000000000000000000000000000000")
638 .expect("failed to create field"),
639 ]
640 );
641 }
642
643 #[test]
644 fn to_fields_2_scalars() {
645 let roi = ROInput::new()
646 .append_scalar(
647 Fq::from_hex("e05c25d2c17ec20d6bc8fd21204af52808451076cff687407164a21d352ddd22")
648 .expect("failed to create scalar"),
649 )
650 .append_scalar(
651 Fq::from_hex("c356dbb39478508818e0320dffa6c1ef512564366ec885ee2fc4d385dd36df0f")
652 .expect("failed to create scalar"),
653 );
654
655 assert_eq!(
656 roi.to_bytes(),
657 [
658 0xe0, 0x5c, 0x25, 0xd2, 0xc1, 0x7e, 0xc2, 0x0d, 0x6b, 0xc8, 0xfd, 0x21, 0x20, 0x4a,
659 0xf5, 0x28, 0x08, 0x45, 0x10, 0x76, 0xcf, 0xf6, 0x87, 0x40, 0x71, 0x64, 0xa2, 0x1d,
660 0x35, 0x2d, 0xdd, 0xa2, 0x61, 0xab, 0xed, 0x59, 0x4a, 0x3c, 0x28, 0x44, 0x0c, 0x70,
661 0x99, 0x86, 0x7f, 0xd3, 0xe0, 0xf7, 0xa8, 0x12, 0x32, 0x1b, 0x37, 0xe4, 0x42, 0xf7,
662 0x17, 0xe2, 0xe9, 0xc2, 0x6e, 0x9b, 0xef, 0x07
663 ]
664 );
665
666 assert_eq!(
667 roi.to_fields(),
668 [
669 Fp::from_hex("e05c25d2c17ec20d6bc8fd21204af52808451076cff687407164a21d352ddd22")
670 .expect("failed to create field"),
671 Fp::from_hex("86adb66729f1a01031c0651afe4d83dfa34ac86cdc900bdd5f88a70bbb6dbe1f")
672 .expect("failed to create field"),
673 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
674 .expect("failed to create field"),
675 ]
676 );
677 }
678
679 #[test]
680 fn to_fields_2_bits_scalar_u32() {
681 let roi = ROInput::new()
682 .append_bool(true)
683 .append_bool(false)
684 .append_scalar(
685 Fq::from_hex("689634de233b06251a80ac7df64483922727757eea1adc6f0c8f184441cfe10d")
686 .expect("failed to create scalar"),
687 )
688 .append_u32(834803);
689
690 assert_eq!(
691 roi.to_bytes(),
692 [
693 0xa1, 0x59, 0xd2, 0x78, 0x8f, 0xec, 0x18, 0x94, 0x68, 0x00, 0xb2, 0xf6, 0xd9, 0x13,
694 0x0d, 0x4a, 0x9e, 0x9c, 0xd4, 0xf9, 0xa9, 0x6b, 0x70, 0xbf, 0x31, 0x3c, 0x62, 0x10,
695 0x05, 0x3d, 0x87, 0x37, 0xe6, 0x79, 0x19, 0x00, 0x00
696 ]
697 );
698
699 assert_eq!(
700 roi.to_fields(),
701 [
702 Fp::from_hex("a159d2788fec18946800b2f6d9130d4a9e9cd4f9a96b70bf313c6210053d8737")
703 .expect("failed to create field"),
704 Fp::from_hex("98e7650000000000000000000000000000000000000000000000000000000000")
705 .expect("failed to create field"),
706 ]
707 );
708 }
709
710 #[test]
711 fn to_fields_2_bits_field_scalar() {
712 let roi = ROInput::new()
713 .append_bool(false)
714 .append_bool(true)
715 .append_field(
716 Fp::from_hex("90926b620ad09ed616d5df158504faed42928719c58ae619d9eccc062f920411")
717 .expect("failed to create field"),
718 )
719 .append_scalar(
720 Fq::from_hex("689634de233b06251a80ac7df64483922727757eea1adc6f0c8f184441cfe10d")
721 .expect("failed to create scalar"),
722 );
723
724 assert_eq!(
725 roi.to_bytes(),
726 [
727 0x90, 0x92, 0x6b, 0x62, 0x0a, 0xd0, 0x9e, 0xd6, 0x16, 0xd5, 0xdf, 0x15, 0x85, 0x04,
728 0xfa, 0xed, 0x42, 0x92, 0x87, 0x19, 0xc5, 0x8a, 0xe6, 0x19, 0xd9, 0xec, 0xcc, 0x06,
729 0x2f, 0x92, 0x04, 0x11, 0xd1, 0x2c, 0x69, 0xbc, 0x47, 0x76, 0x0c, 0x4a, 0x34, 0x00,
730 0x59, 0xfb, 0xec, 0x89, 0x06, 0x25, 0x4f, 0x4e, 0xea, 0xfc, 0xd4, 0x35, 0xb8, 0xdf,
731 0x18, 0x1e, 0x31, 0x88, 0x82, 0x9e, 0xc3, 0x1b
732 ]
733 );
734
735 assert_eq!(
736 roi.to_fields(),
737 [
738 Fp::from_hex("90926b620ad09ed616d5df158504faed42928719c58ae619d9eccc062f920411")
739 .expect("failed to create field"),
740 Fp::from_hex("a259d2788fec18946800b2f6d9130d4a9e9cd4f9a96b70bf313c6210053d8737")
741 .expect("failed to create field"),
742 Fp::from_hex("0000000000000000000000000000000000000000000000000000000000000000")
743 .expect("failed to create field"),
744 ]
745 );
746 }
747
748 #[test]
749 fn transaction_test_1() {
750 let roi = ROInput::new()
751 .append_field(
752 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
753 .expect("failed to create field"),
754 ) .append_field(
756 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
757 .expect("failed to create field"),
758 ) .append_field(
760 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
761 .expect("failed to create field"),
762 ) .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);
778 assert_eq!(
779 roi.to_bytes(),
780 [
781 0x41, 0x20, 0x3c, 0x6b, 0xba, 0xc1, 0x4b, 0x35, 0x73, 0x01, 0xe1, 0xf3, 0x86, 0xd8,
782 0x0f, 0x52, 0x12, 0x3f, 0xd0, 0x0f, 0x02, 0x19, 0x74, 0x91, 0xb6, 0x90, 0xbd, 0xdf,
783 0xa7, 0x42, 0xca, 0xa2, 0x4c, 0x16, 0x6d, 0xf9, 0x4f, 0xff, 0x0a, 0x59, 0x5e, 0xf5,
784 0x2e, 0x00, 0x72, 0xcc, 0xf6, 0xa7, 0xff, 0xe8, 0x8b, 0xe0, 0x4b, 0xf8, 0xfc, 0x42,
785 0x43, 0xf2, 0x82, 0x7b, 0x17, 0x7c, 0x47, 0xc0, 0x8f, 0xee, 0xd3, 0xe9, 0x86, 0x73,
786 0x43, 0xff, 0x7d, 0x02, 0xf6, 0x89, 0x11, 0x8c, 0x8d, 0x75, 0x0a, 0x05, 0xd6, 0xf7,
787 0xfb, 0xdd, 0x8b, 0xbd, 0xd7, 0x61, 0x6f, 0xdb, 0x86, 0x87, 0x81, 0x0a, 0x48, 0xe8,
788 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
789 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
792 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x5f, 0xa0, 0x12, 0x00,
793 0x00, 0x00, 0x00
794 ]
795 );
796
797 assert_eq!(
798 roi.to_fields(),
799 [
800 Fp::from_hex("41203c6bbac14b357301e1f386d80f52123fd00f02197491b690bddfa742ca22")
801 .expect("failed to create field"),
802 Fp::from_hex("992cdaf29ffe15b2bcea5d00e498ed4fffd117c197f0f98586e405f72ef88e00")
803 .expect("failed to create field"),
804 Fp::from_hex("3fba4fa71bce0dfdf709d827463036d6291458dfef772ff65e87bd6d1b1e062a")
805 .expect("failed to create field"),
806 Fp::from_hex("40420f0000000000010000000000000001000000feffffff0100000000000000")
807 .expect("failed to create field"),
808 Fp::from_hex("0000000000000000000000000000000000000000000000000000400100000000")
809 .expect("failed to create field"),
810 Fp::from_hex("00000000902f5009000000000000000000000000000000000000000000000000")
811 .expect("failed to create field"),
812 ]
813 );
814 }
815
816 #[test]
817 fn nested_roinput_test() {
818 #[derive(Clone, Debug)]
819 struct A {
820 x: u32,
821 y: bool,
822 z: u32,
823 }
824
825 impl Hashable for A {
826 type D = ();
827
828 fn to_roinput(&self) -> ROInput {
829 ROInput::new()
830 .append_u32(self.x)
831 .append_bool(self.y)
832 .append_u32(self.z)
833 }
834
835 fn domain_string(_: Self::D) -> Option<String> {
836 "A".to_string().into()
837 }
838 }
839
840 #[derive(Clone, Debug)]
841 struct B1 {
842 a: A,
843 b: u64,
844 c: bool,
845 }
846
847 impl Hashable for B1 {
848 type D = ();
849
850 fn to_roinput(&self) -> ROInput {
851 self.a.to_roinput().append_u64(self.b).append_bool(self.c)
852 }
853
854 fn domain_string(_: Self::D) -> Option<String> {
855 "B".to_string().into()
856 }
857 }
858
859 #[derive(Clone, Debug)]
860 struct B2 {
861 a: A,
862 b: u64,
863 c: bool,
864 }
865
866 impl Hashable for B2 {
867 type D = ();
868
869 fn to_roinput(&self) -> ROInput {
870 self.a
871 .to_roinput()
872 .append_roinput(ROInput::new().append_u64(self.b).append_bool(self.c))
873 }
874
875 fn domain_string(_: Self::D) -> Option<String> {
876 "B".to_string().into()
877 }
878 }
879
880 let a = A {
881 x: 16830533,
882 y: false,
883 z: 39827791,
884 };
885 let b1 = B1 {
886 a,
887 b: 124819,
888 c: true,
889 };
890 let b2 = B2 {
891 a: b1.a.clone(),
892 b: b1.b,
893 c: b1.c,
894 };
895
896 assert_eq!(b1.to_roinput(), b2.to_roinput());
897
898 let b2 = B2 {
899 a: b1.a.clone(),
900 b: b1.b,
901 c: false,
902 };
903 assert_ne!(b1.to_roinput(), b2.to_roinput());
904
905 let b2 = B2 {
906 a: b1.a.clone(),
907 b: b1.b + 1,
908 c: b1.c,
909 };
910 assert_ne!(b1.to_roinput(), b2.to_roinput());
911 }
912}