elements_miniscript/miniscript/types/
malleability.rs1use super::{ErrorKind, Property};
7use crate::{Extension, ScriptContext};
8
9#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
14pub enum Dissat {
15 None,
18 Unique,
23 Unknown,
28}
29
30impl Dissat {
31 fn is_subtype(&self, other: Self) -> bool {
34 match (*self, other) {
35 (x, y) if x == y => true,
36 (_, Dissat::Unknown) => true,
37 _ => false,
38 }
39 }
40}
41
42#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
45pub struct Malleability {
46 pub dissat: Dissat,
48 pub safe: bool,
53 pub non_malleable: bool,
56}
57
58impl Malleability {
59 pub fn is_subtype(&self, other: Self) -> bool {
64 self.dissat.is_subtype(other.dissat)
65 && self.safe >= other.safe
66 && self.non_malleable >= other.non_malleable
67 }
68}
69
70impl Property for Malleability {
71 fn from_true() -> Self {
72 Malleability {
73 dissat: Dissat::None,
74 safe: false,
75 non_malleable: true,
76 }
77 }
78
79 fn from_false() -> Self {
80 Malleability {
81 dissat: Dissat::Unique,
82 safe: true,
83 non_malleable: true,
84 }
85 }
86
87 fn from_pk_k<Ctx: ScriptContext>() -> Self {
88 Malleability {
89 dissat: Dissat::Unique,
90 safe: true,
91 non_malleable: true,
92 }
93 }
94
95 fn from_pk_h<Ctx: ScriptContext>() -> Self {
96 Malleability {
97 dissat: Dissat::Unique,
98 safe: true,
99 non_malleable: true,
100 }
101 }
102
103 fn from_multi(_: usize, _: usize) -> Self {
104 Malleability {
105 dissat: Dissat::Unique,
106 safe: true,
107 non_malleable: true,
108 }
109 }
110
111 fn from_multi_a(_: usize, _: usize) -> Self {
112 Malleability {
113 dissat: Dissat::Unique,
114 safe: true,
115 non_malleable: true,
116 }
117 }
118
119 fn from_hash() -> Self {
120 Malleability {
121 dissat: Dissat::Unknown,
122 safe: false,
123 non_malleable: true,
124 }
125 }
126
127 fn from_time(_: u32) -> Self {
128 Malleability {
129 dissat: Dissat::None,
130 safe: false,
131 non_malleable: true,
132 }
133 }
134
135 fn cast_alt(self) -> Result<Self, ErrorKind> {
136 Ok(self)
137 }
138
139 fn cast_swap(self) -> Result<Self, ErrorKind> {
140 Ok(self)
141 }
142
143 fn cast_check(self) -> Result<Self, ErrorKind> {
144 Ok(self)
145 }
146
147 fn cast_dupif(self) -> Result<Self, ErrorKind> {
148 Ok(Malleability {
149 dissat: if self.dissat == Dissat::None {
150 Dissat::Unique
151 } else {
152 Dissat::Unknown
153 },
154 safe: self.safe,
155 non_malleable: self.non_malleable,
156 })
157 }
158
159 fn cast_verify(self) -> Result<Self, ErrorKind> {
160 Ok(Malleability {
161 dissat: Dissat::None,
162 safe: self.safe,
163 non_malleable: self.non_malleable,
164 })
165 }
166
167 fn cast_nonzero(self) -> Result<Self, ErrorKind> {
168 Ok(Malleability {
169 dissat: if self.dissat == Dissat::None {
170 Dissat::Unique
171 } else {
172 Dissat::Unknown
173 },
174 safe: self.safe,
175 non_malleable: self.non_malleable,
176 })
177 }
178
179 fn cast_zeronotequal(self) -> Result<Self, ErrorKind> {
180 Ok(self)
181 }
182
183 fn cast_true(self) -> Result<Self, ErrorKind> {
184 Ok(Malleability {
185 dissat: Dissat::None,
186 safe: self.safe,
187 non_malleable: self.non_malleable,
188 })
189 }
190
191 fn cast_or_i_false(self) -> Result<Self, ErrorKind> {
192 Ok(Malleability {
193 dissat: if self.dissat == Dissat::None {
194 Dissat::Unique
195 } else {
196 Dissat::Unknown
197 },
198 safe: self.safe,
199 non_malleable: self.non_malleable,
200 })
201 }
202
203 fn and_b(left: Self, right: Self) -> Result<Self, ErrorKind> {
204 Ok(Malleability {
205 dissat: match (left.dissat, right.dissat) {
206 (Dissat::None, Dissat::None) => Dissat::None,
207 (Dissat::None, _) if left.safe => Dissat::None,
208 (_, Dissat::None) if right.safe => Dissat::None,
209 (Dissat::Unique, Dissat::Unique) => {
210 if left.safe && right.safe {
211 Dissat::Unique
212 } else {
213 Dissat::Unknown
214 }
215 }
216 _ => Dissat::Unknown,
217 },
218 safe: left.safe || right.safe,
219 non_malleable: left.non_malleable && right.non_malleable,
220 })
221 }
222
223 fn and_v(left: Self, right: Self) -> Result<Self, ErrorKind> {
224 Ok(Malleability {
225 dissat: match (left.safe, right.dissat) {
226 (_, Dissat::None) => Dissat::None, (true, _) => Dissat::None, _ => Dissat::Unknown,
229 },
230 safe: left.safe || right.safe,
231 non_malleable: left.non_malleable && right.non_malleable,
232 })
233 }
234
235 fn or_b(left: Self, right: Self) -> Result<Self, ErrorKind> {
236 Ok(Malleability {
237 dissat: Dissat::Unique,
238 safe: left.safe && right.safe,
239 non_malleable: left.non_malleable
240 && left.dissat == Dissat::Unique
241 && right.non_malleable
242 && right.dissat == Dissat::Unique
243 && (left.safe || right.safe),
244 })
245 }
246
247 fn or_d(left: Self, right: Self) -> Result<Self, ErrorKind> {
248 Ok(Malleability {
249 dissat: right.dissat,
250 safe: left.safe && right.safe,
251 non_malleable: left.non_malleable
252 && left.dissat == Dissat::Unique
253 && right.non_malleable
254 && (left.safe || right.safe),
255 })
256 }
257
258 fn or_c(left: Self, right: Self) -> Result<Self, ErrorKind> {
259 Ok(Malleability {
260 dissat: Dissat::None,
261 safe: left.safe && right.safe,
262 non_malleable: left.non_malleable
263 && left.dissat == Dissat::Unique
264 && right.non_malleable
265 && (left.safe || right.safe),
266 })
267 }
268
269 fn or_i(left: Self, right: Self) -> Result<Self, ErrorKind> {
270 Ok(Malleability {
271 dissat: match (left.dissat, right.dissat) {
272 (Dissat::None, Dissat::None) => Dissat::None,
273 (Dissat::Unique, Dissat::None) => Dissat::Unique,
274 (Dissat::None, Dissat::Unique) => Dissat::Unique,
275 _ => Dissat::Unknown,
276 },
277 safe: left.safe && right.safe,
278 non_malleable: left.non_malleable && right.non_malleable && (left.safe || right.safe),
279 })
280 }
281
282 fn and_or(a: Self, b: Self, c: Self) -> Result<Self, ErrorKind> {
283 Ok(Malleability {
284 dissat: match (a.safe, b.dissat, c.dissat) {
285 (_, Dissat::None, Dissat::Unique) => Dissat::Unique, (true, _, Dissat::Unique) => Dissat::Unique, (_, Dissat::None, Dissat::None) => Dissat::None, (true, _, Dissat::None) => Dissat::None, _ => Dissat::Unknown,
290 },
291 safe: (a.safe || b.safe) && c.safe,
292 non_malleable: a.non_malleable
293 && c.non_malleable
294 && a.dissat == Dissat::Unique
295 && b.non_malleable
296 && (a.safe || b.safe || c.safe),
297 })
298 }
299
300 fn from_ext<E: Extension>(e: &E) -> Self {
301 e.mall_prop()
302 }
303
304 fn threshold<S>(k: usize, n: usize, mut sub_ck: S) -> Result<Self, ErrorKind>
305 where
306 S: FnMut(usize) -> Result<Self, ErrorKind>,
307 {
308 let mut safe_count = 0;
309 let mut all_are_dissat_unique = true;
310 let mut all_are_non_malleable = true;
311 for i in 0..n {
312 let subtype = sub_ck(i)?;
313 safe_count += usize::from(subtype.safe);
314 all_are_dissat_unique &= subtype.dissat == Dissat::Unique;
315 all_are_non_malleable &= subtype.non_malleable;
316 }
317 Ok(Malleability {
318 dissat: if all_are_dissat_unique && safe_count == n {
319 Dissat::Unique
320 } else {
321 Dissat::Unknown
322 },
323 safe: safe_count > n - k,
324 non_malleable: all_are_non_malleable && safe_count >= n - k && all_are_dissat_unique,
325 })
326 }
327}