1mod midstate;
9
10pub mod amr;
11pub mod cmr;
12pub mod ihr;
13pub mod tmr;
14
15use self::midstate::MidstateExt;
16use crate::bit_encoding::BitCollector;
17use crate::Value;
18use hashes::{sha256, HashEngine};
19use std::fmt;
20
21pub trait HasCmr {
23 fn cmr(&self) -> cmr::Cmr;
25}
26
27#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
29pub struct FailEntropy([u8; 64]);
30
31impl FailEntropy {
32 pub const ZERO: Self = FailEntropy([0; 64]);
34
35 pub const fn from_byte_array(data: [u8; 64]) -> Self {
37 FailEntropy(data)
38 }
39
40 pub const fn to_byte_array(self) -> [u8; 64] {
42 self.0
43 }
44}
45
46impl fmt::Display for FailEntropy {
47 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48 fmt::Display::fmt(&hex::DisplayHex::as_hex(&self.0[..]), f)
49 }
50}
51
52impl AsRef<[u8]> for FailEntropy {
53 fn as_ref(&self) -> &[u8] {
54 self.0.as_ref()
55 }
56}
57
58fn compact_value(value: &Value) -> [u8; 32] {
61 let (mut bytes, bit_length) = value.iter_compact().collect_bits();
62
63 if bit_length % 8 == 0 {
66 bytes.push(0x80);
67 } else {
68 let delimiter_index = bit_length % 8;
69 *bytes.last_mut().unwrap() |= 1 << (7 - delimiter_index);
70 }
71
72 let k = if bytes.len() % 64 > 56 {
74 56 + (64 - (bytes.len() % 64))
77 } else {
78 56 - (bytes.len() % 64)
80 };
81 bytes.resize(bytes.len() + k, 0x00);
82 debug_assert!(bytes.len() % 64 == 56);
83
84 let bit_length_bytes = (bit_length as u64).to_be_bytes();
86 bytes.extend(bit_length_bytes.iter());
87 debug_assert!(bytes.len() % 16 == 0);
88
89 let mut consumed = 0;
91 let mut engine = sha256::HashEngine::default();
92 while consumed < bytes.len() {
93 engine.input(&bytes[consumed..(consumed + 16)]);
94 consumed += 16;
95 }
96 debug_assert!(consumed == bytes.len());
97 engine
98 .midstate()
99 .expect("hash input length was a multiple of 64")
100 .to_parts()
101 .0
102}
103
104#[inline]
106fn concat<MR: AsRef<[u8]>>(mr1: MR, mr2: MR) -> [u8; 64] {
107 core::array::from_fn(|i| {
108 if i < 32 {
109 mr1.as_ref()[i]
110 } else {
111 mr2.as_ref()[i - 32]
112 }
113 })
114}
115
116const fn bip340_iv(tag: &[u8]) -> sha256::Midstate {
117 sha256::Midstate::hash_tag(tag)
118}
119
120macro_rules! impl_mr_type {
125 {
126 $(#[$($struct_attr:tt)*])*
127 pub struct $wrapper:ident([u8; 32]);
128 } => {
129 $(#[$($struct_attr)*])*
130 pub struct $wrapper([u8; 32]);
131
132 impl AsRef<[u8]> for $wrapper {
133 fn as_ref(&self) -> &[u8] {
134 self.0.as_ref()
135 }
136 }
137
138 impl std::fmt::Debug for $wrapper {
139 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
140 std::fmt::Display::fmt(&hex::DisplayHex::as_hex(self.as_ref()), f)
141 }
142 }
143
144 impl std::fmt::Display for $wrapper {
145 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
146 std::fmt::Debug::fmt(self, f)
147 }
148 }
149
150 impl std::str::FromStr for $wrapper {
151 type Err = hex::error::DecodeFixedLengthBytesError;
152
153 fn from_str(s: &str) -> Result<Self, Self::Err> {
154 let x: [u8; 32] = hex::decode_to_array(s)?;
155 Ok($wrapper(x))
156 }
157 }
158
159 impl $wrapper {
160 pub const fn from_byte_array(data: [u8; 32]) -> Self {
162 $wrapper(data)
163 }
164
165 pub const fn to_byte_array(self) -> [u8; 32] {
167 self.0
168 }
169
170 pub const fn as_byte_array(&self) -> &[u8; 32] {
172 &self.0
173 }
174 }
175
176 impl_serde_string!($wrapper);
177 };
178}
179use impl_mr_type;