1use crate::Integer;
2use byteorder::{LittleEndian, WriteBytesExt};
3use serde_derive::{Deserialize, Serialize};
4use std::borrow::Cow;
5use std::hash::Hash;
6use std::marker::PhantomData;
7use std::ops::Deref;
8use std::sync::Arc;
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
11pub enum Function {
12 Plain,
13 Sha1,
14 Ripemd160,
15 Sha256,
16 Hash256,
17 Hash160,
18 Num2Bin,
19 EcdsaSign,
20 SchnorrSign,
21 ToDataSig,
22 UnexpectedSplit,
23 Reverse,
24}
25
26#[derive(Clone, Debug)]
27pub struct ByteArray {
28 data: Arc<[u8]>,
29 #[cfg(not(feature = "simple-bytearray"))]
30 name: Option<Arc<Cow<'static, str>>>,
31 #[cfg(not(feature = "simple-bytearray"))]
32 function: Function,
33 #[cfg(not(feature = "simple-bytearray"))]
34 preimage: Option<Arc<[ByteArray]>>,
35}
36
37#[derive(Clone, Debug)]
38pub struct FixedByteArray<T> {
39 phantom: PhantomData<T>,
40 byte_array: ByteArray,
41}
42
43#[derive(Clone, Debug)]
44pub struct FromSliceError {
45 pub expected: usize,
46 pub actual: usize,
47}
48
49impl Function {
50 pub fn should_keep_intact(self) -> bool {
51 use Function::*;
52 match self {
53 Plain | Num2Bin | EcdsaSign | SchnorrSign | ToDataSig => false,
54 _ => true,
55 }
56 }
57}
58
59impl ByteArray {
60 pub fn debug_enabled() -> bool {
61 true
62 }
63
64 #[cfg(not(feature = "simple-bytearray"))]
65 pub fn new(name: impl Into<Cow<'static, str>>, data: impl Into<Arc<[u8]>>) -> Self {
66 ByteArray {
67 data: data.into(),
68 name: Some(Arc::new(name.into())),
69 function: Function::Plain,
70 preimage: None,
71 }
72 }
73
74 #[cfg(feature = "simple-bytearray")]
75 pub fn new(_name: impl Into<Cow<'static, str>>, data: impl Into<Arc<[u8]>>) -> Self {
76 ByteArray { data: data.into() }
77 }
78
79 #[cfg(not(feature = "simple-bytearray"))]
80 pub fn new_unnamed(data: impl Into<Arc<[u8]>>) -> Self {
81 ByteArray {
82 data: data.into(),
83 name: None,
84 function: Function::Plain,
85 preimage: None,
86 }
87 }
88
89 #[cfg(feature = "simple-bytearray")]
90 pub fn new_unnamed(data: impl Into<Arc<[u8]>>) -> Self {
91 ByteArray { data: data.into() }
92 }
93
94 #[cfg(not(feature = "simple-bytearray"))]
95 pub fn from_preimage(
96 data: Arc<[u8]>,
97 name: Option<Arc<Cow<'static, str>>>,
98 function: Function,
99 preimage: Option<Arc<[ByteArray]>>,
100 ) -> Self {
101 ByteArray {
102 data,
103 name,
104 function,
105 preimage,
106 }
107 }
108
109 #[cfg(feature = "simple-bytearray")]
110 pub fn from_preimage(
111 data: Arc<[u8]>,
112 _name: Option<Arc<Cow<'static, str>>>,
113 _function: Function,
114 _preimage: Option<Arc<[ByteArray]>>,
115 ) -> Self {
116 ByteArray { data }
117 }
118
119 #[cfg(not(feature = "simple-bytearray"))]
120 pub fn from_slice(name: impl Into<Cow<'static, str>>, slice: &[u8]) -> Self {
121 ByteArray {
122 data: slice.into(),
123 name: Some(Arc::new(name.into())),
124 function: Function::Plain,
125 preimage: None,
126 }
127 }
128
129 #[cfg(feature = "simple-bytearray")]
130 pub fn from_slice(_name: impl Into<Cow<'static, str>>, slice: &[u8]) -> Self {
131 ByteArray { data: slice.into() }
132 }
133
134 #[cfg(not(feature = "simple-bytearray"))]
135 pub fn from_slice_unnamed(slice: &[u8]) -> Self {
136 ByteArray {
137 data: slice.into(),
138 name: None,
139 function: Function::Plain,
140 preimage: None,
141 }
142 }
143
144 #[cfg(feature = "simple-bytearray")]
145 pub fn from_slice_unnamed(slice: &[u8]) -> Self {
146 ByteArray { data: slice.into() }
147 }
148
149 #[cfg(not(feature = "simple-bytearray"))]
150 pub fn function(&self) -> Function {
151 self.function
152 }
153
154 #[cfg(feature = "simple-bytearray")]
155 pub fn function(&self) -> Function {
156 Function::Plain
157 }
158
159 #[cfg(not(feature = "simple-bytearray"))]
160 pub fn preimage(&self) -> Option<&[ByteArray]> {
161 self.preimage.as_ref().map(|preimage| preimage.as_ref())
162 }
163
164 #[cfg(feature = "simple-bytearray")]
165 pub fn preimage(&self) -> Option<&[ByteArray]> {
166 None
167 }
168
169 #[cfg(not(feature = "simple-bytearray"))]
170 pub fn preimage_arc(&self) -> Option<&Arc<[ByteArray]>> {
171 self.preimage.as_ref()
172 }
173
174 #[cfg(feature = "simple-bytearray")]
175 pub fn preimage_arc(&self) -> Option<&Arc<[ByteArray]>> {
176 None
177 }
178
179 #[cfg(not(feature = "simple-bytearray"))]
180 pub fn name(&self) -> Option<&str> {
181 self.name.as_ref().map(|name| (*(*name).as_ref()).as_ref())
182 }
183
184 #[cfg(feature = "simple-bytearray")]
185 pub fn name(&self) -> Option<&str> {
186 None
187 }
188
189 #[cfg(not(feature = "simple-bytearray"))]
190 pub fn name_arc(&self) -> Option<&Arc<Cow<'static, str>>> {
191 self.name.as_ref()
192 }
193
194 #[cfg(feature = "simple-bytearray")]
195 pub fn name_arc(&self) -> Option<&Arc<Cow<'static, str>>> {
196 None
197 }
198
199 pub fn data(&self) -> &Arc<[u8]> {
200 &self.data
201 }
202
203 #[cfg(not(feature = "simple-bytearray"))]
204 pub fn concat_named_option(
205 self,
206 other: impl Into<ByteArray>,
207 name: Option<Arc<Cow<'static, str>>>,
208 ) -> ByteArray {
209 let other = other.into();
210 let mut new_data = Vec::with_capacity(self.data.len() + other.data.len());
211 new_data.extend_from_slice(&self.data);
212 new_data.extend_from_slice(&other.data);
213 if self.function == Function::Plain && other.function == Function::Plain {
214 let mut new_preimage = if self.preimage.is_some() {
215 self.preimage.unwrap().to_vec()
216 } else {
217 vec![self]
218 };
219 new_preimage.append(&mut if other.preimage.is_some() {
220 other.preimage.unwrap().to_vec()
221 } else {
222 vec![other]
223 });
224 return ByteArray {
225 data: new_data.into(),
226 name,
227 function: Function::Plain,
228 preimage: Some(new_preimage.into()),
229 };
230 }
231 ByteArray {
232 data: new_data.into(),
233 name,
234 function: Function::Plain,
235 preimage: Some(vec![self, other].into()),
236 }
237 }
238
239 #[cfg(feature = "simple-bytearray")]
240 pub fn concat_named_option(
241 self,
242 other: impl Into<ByteArray>,
243 _name: Option<Arc<Cow<'static, str>>>,
244 ) -> ByteArray {
245 let other = other.into();
246 let mut new_data = Vec::with_capacity(self.data.len() + other.data.len());
247 new_data.extend_from_slice(&self.data);
248 new_data.extend_from_slice(&other.data);
249 ByteArray {
250 data: new_data.into(),
251 }
252 }
253
254 pub fn concat(self, other: impl Into<ByteArray>) -> ByteArray {
255 self.concat_named_option(other, None)
256 }
257
258 pub fn concat_named(
259 self,
260 name: impl Into<Arc<Cow<'static, str>>>,
261 other: impl Into<ByteArray>,
262 ) -> ByteArray {
263 self.concat_named_option(other, Some(name.into()))
264 }
265
266 #[cfg(not(feature = "simple-bytearray"))]
267 pub fn split(self, at: usize) -> Result<(ByteArray, ByteArray), String> {
268 if self.data.len() < at {
269 return Err(format!(
270 "Index {} is out of bounds for array with length {}, {}.",
271 at,
272 self.data.len(),
273 hex::encode(&self.data)
274 ));
275 }
276 let mut data = self.data.to_vec();
277 let other = data.split_off(at);
278 let mut function = Function::Plain;
279 let (left_preimage, right_preimage) = match self.preimage {
280 Some(preimage) if !self.function.should_keep_intact() => {
281 let mut left_preimage = Vec::new();
282 let mut right_preimage = Vec::new();
283 let mut is_left = true;
284 let mut len = 0;
285 for part in preimage.iter().cloned() {
286 let part_len = part.data.len();
287 if len == at {
288 is_left = false;
289 }
290 if len + part_len > at && is_left {
291 let part_function = part.function;
292 let (mut sub_left, mut sub_right) = part.split(at - len)?;
293 if part_function.should_keep_intact() {
294 sub_left.function = Function::UnexpectedSplit;
295 sub_right.function = Function::UnexpectedSplit;
296 }
297 left_preimage.push(sub_left);
298 right_preimage.push(sub_right);
299 is_left = false;
300 } else if is_left {
301 left_preimage.push(part);
302 } else {
303 right_preimage.push(part);
304 }
305 len += part_len;
306 }
307 (Some(left_preimage), Some(right_preimage))
308 }
309 Some(_) => {
310 function = Function::UnexpectedSplit;
311 (None, None)
312 }
313 None => (None, None),
314 };
315 Ok((
316 ByteArray {
317 data: data.into(),
318 name: None,
319 function,
320 preimage: left_preimage.map(Into::into),
321 },
322 ByteArray {
323 data: other.into(),
324 name: None,
325 function,
326 preimage: right_preimage.map(Into::into),
327 },
328 ))
329 }
330
331 #[cfg(feature = "simple-bytearray")]
332 pub fn split(self, at: usize) -> Result<(ByteArray, ByteArray), String> {
333 if self.data.len() < at {
334 return Err(format!(
335 "Index {} is out of bounds for array with length {}, {}.",
336 at,
337 self.data.len(),
338 hex::encode(&self.data)
339 ));
340 }
341 let mut data = self.data.to_vec();
342 let other = data.split_off(at);
343 Ok((
344 ByteArray { data: data.into() },
345 ByteArray { data: other.into() },
346 ))
347 }
348
349 #[cfg(not(feature = "simple-bytearray"))]
350 pub fn apply_function(self, data: impl Into<Arc<[u8]>>, function: Function) -> ByteArray {
351 ByteArray {
352 data: data.into(),
353 name: None,
354 function,
355 preimage: Some(vec![self].into()),
356 }
357 }
358
359 #[cfg(feature = "simple-bytearray")]
360 pub fn apply_function(self, data: impl Into<Arc<[u8]>>, _function: Function) -> ByteArray {
361 ByteArray { data: data.into() }
362 }
363
364 #[cfg(not(feature = "simple-bytearray"))]
365 pub fn named(self, name: impl Into<Cow<'static, str>>) -> ByteArray {
366 ByteArray {
367 name: Some(Arc::new(name.into())),
368 ..self
369 }
370 }
371
372 #[cfg(feature = "simple-bytearray")]
373 pub fn named(self, _name: impl Into<Cow<'static, str>>) -> ByteArray {
374 ByteArray { ..self }
375 }
376
377 #[cfg(not(feature = "simple-bytearray"))]
378 pub fn named_option(self, name: Option<Arc<Cow<'static, str>>>) -> ByteArray {
379 ByteArray { name, ..self }
380 }
381
382 pub fn from_int(int: Integer, n_bytes: Integer) -> Result<Self, String> {
383 if n_bytes <= 0 {
384 return Err(format!("n_bytes={} not valid", n_bytes));
385 }
386 let max_bits = (n_bytes * 8 - 1).min(31) as u128;
387 let max_num: u128 = 1 << max_bits;
388 let max_num = (max_num - 1) as Integer;
389 let min_num = -max_num;
390 if int < min_num || int > max_num {
391 return Err(format!("int={} not valid for n_bytes={}", int, n_bytes));
392 }
393 let mut bytes = Vec::new();
394 bytes.write_i32::<LittleEndian>(int.abs()).unwrap();
395 let n_bytes = n_bytes as usize;
396 if bytes.len() < n_bytes {
397 bytes.append(&mut vec![0; n_bytes - bytes.len()]);
398 } else if bytes.len() > n_bytes {
399 bytes.drain(n_bytes..);
400 }
401 if int < 0 {
402 let len = bytes.len();
403 bytes[len - 1] |= 0x80;
404 }
405 Ok(ByteArray::from_preimage(
406 bytes.into(),
407 None,
408 Function::Num2Bin,
409 None,
410 ))
411 }
412}
413
414impl<T> FixedByteArray<T> {
415 pub fn as_byte_array(&self) -> &ByteArray {
416 &self.byte_array
417 }
418
419 pub fn into_byte_array(self) -> ByteArray {
420 self.byte_array
421 }
422
423 pub fn named(self, name: impl Into<Cow<'static, str>>) -> FixedByteArray<T> {
424 FixedByteArray {
425 phantom: PhantomData,
426 byte_array: self.byte_array.named(name),
427 }
428 }
429}
430
431impl<T> FixedByteArray<T>
432where
433 T: AsRef<[u8]>,
434{
435 pub fn new(name: impl Into<Cow<'static, str>>, data: T) -> Self {
436 FixedByteArray {
437 phantom: PhantomData,
438 byte_array: ByteArray::from_preimage(
439 data.as_ref().into(),
440 Some(Arc::new(name.into())),
441 Function::Plain,
442 None,
443 ),
444 }
445 }
446
447 pub fn new_unnamed(data: T) -> Self {
448 FixedByteArray {
449 phantom: PhantomData,
450 byte_array: ByteArray::from_preimage(data.as_ref().into(), None, Function::Plain, None),
451 }
452 }
453}
454
455impl<T> FixedByteArray<T>
456where
457 T: Default + AsRef<[u8]>,
458{
459 pub fn from_slice(
460 name: impl Into<Cow<'static, str>>,
461 slice: &[u8],
462 ) -> Result<Self, FromSliceError> {
463 let array = T::default();
464 if array.as_ref().len() != slice.len() {
465 return Err(FromSliceError {
466 expected: array.as_ref().len(),
467 actual: slice.len(),
468 });
469 }
470 Ok(FixedByteArray {
471 phantom: PhantomData,
472 byte_array: ByteArray::from_preimage(
473 slice.into(),
474 Some(Arc::new(name.into())),
475 Function::Plain,
476 None,
477 ),
478 })
479 }
480
481 pub fn from_slice_unnamed(slice: &[u8]) -> Result<Self, FromSliceError> {
482 let array = T::default();
483 if array.as_ref().len() != slice.len() {
484 return Err(FromSliceError {
485 expected: array.as_ref().len(),
486 actual: slice.len(),
487 });
488 }
489 Ok(FixedByteArray {
490 phantom: PhantomData,
491 byte_array: ByteArray::from_preimage(slice.into(), None, Function::Plain, None),
492 })
493 }
494
495 pub fn from_byte_array(byte_array: ByteArray) -> Result<Self, FromSliceError> {
496 let array = T::default();
497 if array.as_ref().len() != byte_array.len() {
498 return Err(FromSliceError {
499 expected: array.as_ref().len(),
500 actual: byte_array.len(),
501 });
502 }
503 Ok(FixedByteArray {
504 phantom: PhantomData,
505 byte_array,
506 })
507 }
508}
509
510impl Default for ByteArray {
511 fn default() -> Self {
512 ByteArray::from_slice_unnamed(&[])
513 }
514}
515
516impl From<Vec<u8>> for ByteArray {
517 fn from(vec: Vec<u8>) -> Self {
518 ByteArray::new_unnamed(vec)
519 }
520}
521
522impl From<&[u8]> for ByteArray {
523 fn from(slice: &[u8]) -> Self {
524 ByteArray::from_slice_unnamed(slice)
525 }
526}
527
528macro_rules! array_impls {
529 ($($N:literal)+) => {
530 $(
531 impl From<[u8; $N]> for ByteArray {
532 fn from(array: [u8; $N]) -> Self {
533 ByteArray::from_slice_unnamed(array.as_ref())
534 }
535 }
536 impl From<&[u8; $N]> for ByteArray {
537 fn from(array: &[u8; $N]) -> Self {
538 ByteArray::from_slice_unnamed(array.as_ref())
539 }
540 }
541 )+
542 }
543}
544
545array_impls! {
546 0 1 2 3 4 5 6 7 8 9
547 10 11 12 13 14 15 16 17 18 19
548 20 21 22 23 24 25 26 27 28 29
549 30 31 32
550}
551
552impl Hash for ByteArray {
553 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
554 self.data.hash(state)
555 }
556}
557
558impl Deref for ByteArray {
559 type Target = [u8];
560 fn deref(&self) -> &Self::Target {
561 &self.data
562 }
563}
564
565impl AsRef<[u8]> for ByteArray {
566 fn as_ref(&self) -> &[u8] {
567 &self.data
568 }
569}
570
571impl<I: std::slice::SliceIndex<[u8]>> std::ops::Index<I> for ByteArray {
572 type Output = I::Output;
573 fn index(&self, index: I) -> &Self::Output {
574 &self.data[index]
575 }
576}
577
578impl PartialEq for ByteArray {
579 fn eq(&self, other: &ByteArray) -> bool {
580 self.data == other.data
581 }
582}
583
584impl Eq for ByteArray {}
585
586impl<'de> serde::Deserialize<'de> for ByteArray {
587 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
588 where
589 D: serde::Deserializer<'de>,
590 {
591 Ok(ByteArray::from_slice_unnamed(
592 <&[u8] as serde::Deserialize<'de>>::deserialize(deserializer)?,
593 ))
594 }
595}
596
597impl serde::Serialize for ByteArray {
598 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
599 where
600 S: serde::Serializer,
601 {
602 self.data.serialize(serializer)
603 }
604}
605
606impl<T: Default + AsRef<[u8]>> Default for FixedByteArray<T> {
607 fn default() -> Self {
608 FixedByteArray {
609 phantom: PhantomData,
610 byte_array: ByteArray::new_unnamed(T::default().as_ref()),
611 }
612 }
613}
614
615impl<T> Hash for FixedByteArray<T> {
616 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
617 self.byte_array.hash(state)
618 }
619}
620
621impl<T> Deref for FixedByteArray<T> {
622 type Target = [u8];
623 fn deref(&self) -> &Self::Target {
624 &self.byte_array.data
625 }
626}
627
628impl<T> AsRef<[u8]> for FixedByteArray<T> {
629 fn as_ref(&self) -> &[u8] {
630 &self.byte_array.data
631 }
632}
633
634impl<T, I: std::slice::SliceIndex<[u8]>> std::ops::Index<I> for FixedByteArray<T> {
635 type Output = I::Output;
636 fn index(&self, index: I) -> &Self::Output {
637 &self.byte_array.data[index]
638 }
639}
640
641impl<T> PartialEq for FixedByteArray<T> {
642 fn eq(&self, other: &FixedByteArray<T>) -> bool {
643 self.byte_array.data == other.byte_array.data
644 }
645}
646
647impl<T> Eq for FixedByteArray<T> {}
648
649impl<'de, T> serde::Deserialize<'de> for FixedByteArray<T>
650where
651 T: serde::Deserialize<'de> + AsRef<[u8]>,
652{
653 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
654 where
655 D: serde::Deserializer<'de>,
656 {
657 Ok(FixedByteArray::new_unnamed(T::deserialize(deserializer)?))
658 }
659}
660
661impl<T> serde::Serialize for FixedByteArray<T>
662where
663 T: serde::Serialize + Default + AsMut<[u8]>,
664{
665 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
666 where
667 S: serde::Serializer,
668 {
669 let mut array = T::default();
670 array.as_mut().copy_from_slice(self.byte_array.as_ref());
671 array.serialize(serializer)
672 }
673}
674
675#[cfg(not(feature = "simple-bytearray"))]
676#[cfg(test)]
677mod tests {
678 use super::{ByteArray, Function};
679 use sha2::Digest;
680
681 #[test]
682 fn test_cat() {
683 let a = ByteArray::from_slice_unnamed(b"A");
684 let b = ByteArray::from_slice_unnamed(b"B");
685 let c = ByteArray::from_slice_unnamed(b"C");
686 let d = ByteArray::from_slice_unnamed(b"D");
687 let ab = a.concat(b);
688 {
689 assert_eq!(ab.data.as_ref(), b"AB");
690 let preimage = ab.preimage.as_ref().expect("No preimage");
691 assert_eq!(preimage[0].data.as_ref(), b"A");
692 assert_eq!(preimage[0].preimage, None);
693 assert_eq!(preimage[1].data.as_ref(), b"B");
694 assert_eq!(preimage[1].preimage, None);
695 }
696 let abcd = ab.concat(c.concat(d));
697 {
698 assert_eq!(abcd.data.as_ref(), b"ABCD");
699 let preimage = abcd.preimage.as_ref().expect("No preimage");
700 assert_eq!(preimage.len(), 4);
701 assert_eq!(preimage[0].data.as_ref(), b"A");
702 assert_eq!(preimage[0].preimage, None);
703 assert_eq!(preimage[1].data.as_ref(), b"B");
704 assert_eq!(preimage[1].preimage, None);
705 assert_eq!(preimage[2].data.as_ref(), b"C");
706 assert_eq!(preimage[2].preimage, None);
707 assert_eq!(preimage[3].data.as_ref(), b"D");
708 assert_eq!(preimage[3].preimage, None);
709 }
710 }
711
712 #[test]
713 fn test_hash() {
714 let a = ByteArray::from_slice_unnamed(b"A");
715 let b = ByteArray::from_slice_unnamed(b"B");
716 let c = ByteArray::from_slice_unnamed(b"C");
717 let cat = a.concat(b).concat(c);
718 let hash = sha2::Sha256::digest(&cat.data);
719 let hashed = cat.apply_function(hash.as_ref(), Function::Sha256);
720 let hash_preimage = hashed.preimage.as_ref().expect("No hash_preimage");
721 assert_eq!(hashed.data.as_ref(), hash.as_slice());
722 assert_eq!(hash_preimage.len(), 1);
723 assert_eq!(hash_preimage[0].data.as_ref(), b"ABC");
724 let preimage = hash_preimage[0].preimage.as_ref().expect("No preimage");
725 assert_eq!(preimage[0].data.as_ref(), b"A");
726 assert_eq!(preimage[0].preimage, None);
727 assert_eq!(preimage[1].data.as_ref(), b"B");
728 assert_eq!(preimage[1].preimage, None);
729 assert_eq!(preimage[2].data.as_ref(), b"C");
730 assert_eq!(preimage[2].preimage, None);
731 }
732
733 #[test]
734 fn test_hash_nested() {
735 let a = ByteArray::from_slice_unnamed(b"A");
736 let b = ByteArray::from_slice_unnamed(b"B");
737 let inner = a.concat(b);
738 let inner_hash = sha2::Sha256::digest(&inner.data);
739 let inner_hashed = inner.apply_function(inner_hash.as_ref(), Function::Sha256);
740 let c = ByteArray::from_slice_unnamed(b"C");
741 let d = ByteArray::from_slice_unnamed(b"D");
742 let outer = c.concat(inner_hashed).concat(d);
743 let outer_hash = sha2::Sha256::digest(&outer.data);
744 let outer_hashed = outer.apply_function(outer_hash.as_ref(), Function::Sha256);
745 assert_eq!(outer_hashed.data.as_ref(), outer_hash.as_slice());
746
747 let outer_preimage = outer_hashed.preimage.as_ref().expect("No preimage");
748
749 assert_eq!(outer_preimage.len(), 1);
750 let outer_preimage0 = &outer_preimage[0];
751 assert_eq!(
752 outer_preimage0.data.as_ref(),
753 [b"C", inner_hash.as_slice(), b"D"].concat().as_slice()
754 );
755 let outer_preimages = outer_preimage0.preimage.as_ref().expect("No preimage");
756 assert_eq!(outer_preimages.len(), 3);
757 assert_eq!(outer_preimages[0].preimage, None);
758 assert_eq!(outer_preimages[1].data.as_ref(), inner_hash.as_slice());
759 assert!(outer_preimages[1].preimage.is_some());
760 assert_eq!(outer_preimages[2].data.as_ref(), b"D");
761 assert_eq!(outer_preimages[2].preimage, None);
762
763 let inner_hash_preimage = outer_preimages[1].preimage.as_ref().expect("No preimage");
764 assert_eq!(inner_hash_preimage.len(), 1);
765 assert_eq!(inner_hash_preimage[0].data.as_ref(), b"AB");
766 let inner_preimage = inner_hash_preimage[0]
767 .preimage
768 .as_ref()
769 .expect("No preimage");
770 assert_eq!(inner_preimage[0].data.as_ref(), b"A");
771 assert_eq!(inner_preimage[0].preimage, None);
772 assert_eq!(inner_preimage[1].data.as_ref(), b"B");
773 assert_eq!(inner_preimage[1].preimage, None);
774 }
775
776 #[test]
777 fn test_split_a_b() {
778 let a = ByteArray::from_slice_unnamed(b"A");
779 let b = ByteArray::from_slice_unnamed(b"B");
780 let cat = a.concat(b);
781 let (left, right) = cat.split(1).unwrap();
782 let left_preimage = left.preimage.as_ref().expect("No preimage");
783 let right_preimage = right.preimage.as_ref().expect("No preimage");
784 assert_eq!(left.function, Function::Plain);
785 assert_eq!(left.data.as_ref(), b"A");
786 assert_eq!(left_preimage.len(), 1);
787 assert_eq!(left_preimage[0].data.as_ref(), b"A");
788 assert_eq!(right.function, Function::Plain);
789 assert_eq!(right.data.as_ref(), b"B");
790 assert_eq!(right_preimage.len(), 1);
791 assert_eq!(right_preimage[0].data.as_ref(), b"B");
792 }
793
794 #[test]
795 fn test_split_nested() {
796 let a = ByteArray::from_slice_unnamed(b"A");
797 let b = ByteArray::from_slice_unnamed(b"B");
798 let inner = a.concat(b);
799 let inner_hash = sha2::Sha256::digest(&inner.data);
800 let inner_hashed = inner.apply_function(inner_hash.as_ref(), Function::Sha256);
801 let c = ByteArray::from_slice_unnamed(b"C");
802 let d = ByteArray::from_slice_unnamed(b"D");
803 let outer = c.concat(inner_hashed.clone()).concat(d);
804
805 {
807 let (left, right) = outer.clone().split(1).unwrap();
808 let left_preimage = left.preimage.as_ref().expect("No preimage");
809 let right_preimage = right.preimage.as_ref().expect("No preimage");
810 assert_eq!(left.function, Function::Plain);
811 assert_eq!(left.data.as_ref(), b"C");
812 assert_eq!(left_preimage.len(), 1);
813 assert_eq!(left_preimage[0].data.as_ref(), b"C");
814 assert_eq!(left_preimage[0].preimage, None);
815 assert_eq!(right.function, Function::Plain);
816 assert_eq!(
817 right.data.as_ref(),
818 [inner_hash.as_slice(), b"D"].concat().as_slice()
819 );
820 assert_eq!(right_preimage.len(), 2);
821 assert_eq!(right_preimage[0].function, Function::Sha256);
822 assert_eq!(right_preimage[0].data.as_ref(), inner_hash.as_slice());
823 assert_eq!(right_preimage[1].function, Function::Plain);
824 assert_eq!(right_preimage[1].data.as_ref(), b"D");
825 let right_preimage2 = right_preimage[0].preimage.as_ref().expect("No preimage");
826 assert_eq!(right_preimage2[0].function, Function::Plain);
827 assert_eq!(right_preimage2[0].data.as_ref(), b"AB");
828 let right_preimage3 = right_preimage2[0].preimage.as_ref().expect("No preimage");
829 assert_eq!(right_preimage3[0].function, Function::Plain);
830 assert_eq!(right_preimage3[0].data.as_ref(), b"A");
831 assert_eq!(right_preimage3[0].preimage, None);
832 assert_eq!(right_preimage3[1].function, Function::Plain);
833 assert_eq!(right_preimage3[1].data.as_ref(), b"B");
834 assert_eq!(right_preimage3[1].preimage, None);
835 }
836
837 {
839 let (left, right) = outer.clone().split(3).unwrap();
840 let left_preimage = left.preimage.as_ref().expect("No preimage");
841 let right_preimage = right.preimage.as_ref().expect("No preimage");
842 assert_eq!(left.function, Function::Plain);
843 assert_eq!(
844 left.data.as_ref(),
845 [b"C", &inner_hash[..2]].concat().as_slice()
846 );
847 assert_eq!(left_preimage.len(), 2);
848 assert_eq!(left_preimage[0].function, Function::Plain);
849 assert_eq!(left_preimage[0].data.as_ref(), b"C");
850 assert_eq!(left_preimage[0].preimage, None);
851 assert_eq!(left_preimage[1].function, Function::UnexpectedSplit);
852 assert_eq!(left_preimage[1].data.as_ref(), &inner_hash[..2]);
853 assert_eq!(left_preimage[1].preimage, None);
854 assert_eq!(right.function, Function::Plain);
855 assert_eq!(
856 right.data.as_ref(),
857 [&inner_hash[2..], b"D"].concat().as_slice()
858 );
859 assert_eq!(right_preimage[0].data.as_ref(), &inner_hash[2..]);
860 assert_eq!(right_preimage[0].preimage, None);
861 assert_eq!(right_preimage[1].data.as_ref(), b"D");
862 assert_eq!(right_preimage[1].preimage, None);
863 }
864
865 {
867 let (left, right) = outer.clone().split(33).unwrap();
868 let left_preimage = left.preimage.as_ref().expect("No preimage");
869 let right_preimage = right.preimage.as_ref().expect("No preimage");
870 assert_eq!(left.function, Function::Plain);
871 assert_eq!(
872 left.data.as_ref(),
873 [b"C", inner_hash.as_slice()].concat().as_slice()
874 );
875 assert_eq!(left_preimage.len(), 2);
876 assert_eq!(left_preimage[0].function, Function::Plain);
877 assert_eq!(left_preimage[0].data.as_ref(), b"C");
878 assert_eq!(left_preimage[0].preimage, None);
879 assert_eq!(left_preimage[1].function, Function::Sha256);
880 assert_eq!(left_preimage[1].data.as_ref(), inner_hash.as_slice());
881 assert_eq!(&left_preimage[1], &inner_hashed);
882 assert_eq!(right.function, Function::Plain);
883 assert_eq!(right.data.as_ref(), b"D");
884 assert_eq!(right_preimage[0].data.as_ref(), b"D");
885 assert_eq!(right_preimage[0].preimage, None);
886 }
887 }
888}