1use crate::jet::Jet;
4#[cfg(feature = "elements")]
5use crate::node::{CoreConstructible, WitnessConstructible};
6#[cfg(feature = "elements")]
7use crate::types::{self, Arrow, Error};
8use crate::value::Word;
9use crate::{FailEntropy, Tmr};
10use hashes::sha256::Midstate;
11
12use super::{bip340_iv, impl_mr_type, MidstateExt as _};
13
14impl_mr_type! {
15 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
24 pub struct Cmr([u8; 32]);
25}
26
27impl From<Tmr> for Cmr {
28 fn from(tmr: Tmr) -> Self {
29 Cmr::from_byte_array(tmr.to_byte_array())
30 }
31}
32
33impl Cmr {
34 pub const fn iden() -> Self {
36 Self::from_byte_array(Self::IDEN_IV.to_parts().0)
37 }
38
39 pub const fn unit() -> Self {
41 Self::from_byte_array(Self::UNIT_IV.to_parts().0)
42 }
43
44 pub fn injl(child: Cmr) -> Self {
46 Self::INJL_IV.update_0_then_32(child).into_merkle_root()
47 }
48
49 pub fn injr(child: Cmr) -> Self {
51 Self::INJR_IV.update_0_then_32(child).into_merkle_root()
52 }
53
54 pub fn take(child: Cmr) -> Self {
56 Self::TAKE_IV.update_0_then_32(child).into_merkle_root()
57 }
58
59 pub fn drop(child: Cmr) -> Self {
61 Self::DROP_IV.update_0_then_32(child).into_merkle_root()
62 }
63
64 pub fn comp(left: Cmr, right: Cmr) -> Self {
66 Self::COMP_IV.zz_update_2x32(left, right).into_merkle_root()
67 }
68
69 pub fn case(left: Cmr, right: Cmr) -> Self {
71 Self::CASE_IV.zz_update_2x32(left, right).into_merkle_root()
72 }
73
74 pub fn pair(left: Cmr, right: Cmr) -> Self {
76 Self::PAIR_IV.zz_update_2x32(left, right).into_merkle_root()
77 }
78
79 pub fn disconnect(left: Cmr) -> Self {
81 Self::DISCONNECT_IV
82 .update_0_then_32(left)
83 .into_merkle_root()
84 }
85
86 pub const fn witness() -> Self {
88 Self::from_byte_array(Self::WITNESS_IV.to_parts().0)
89 }
90
91 pub fn fail(entropy: FailEntropy) -> Self {
93 Self::FAIL_IV
94 .zz_update_64(entropy.to_byte_array())
95 .into_merkle_root()
96 }
97
98 pub fn jet(jet: &dyn Jet) -> Self {
100 jet.cmr()
101 }
102
103 pub fn const_word(word: &Word) -> Self {
108 let w = 1 + word.n();
109
110 let mut cmr_stack = Vec::with_capacity(33);
111 for (bit_idx, bit) in word.iter().enumerate() {
113 cmr_stack.push(Cmr::BITS[usize::from(bit)]);
114 let mut j = bit_idx;
115 while j & 1 == 1 {
116 let right_cmr = cmr_stack.pop().unwrap();
117 let left_cmr = cmr_stack.pop().unwrap();
118 cmr_stack.push(Cmr::pair(left_cmr, right_cmr));
119 j >>= 1;
120 }
121 }
122 assert_eq!(cmr_stack.len(), 1);
123
124 let ihr_iv = Self::CONST_WORD_IV;
125 let ihr_pass1 = ihr_iv.update_0_then_32(cmr_stack[0]);
126 let ihr_pass2 = ihr_pass1.zz_update_2x32(Tmr::unit(), Tmr::TWO_TWO_N[w - 1]);
128 bip340_iv(b"Simplicity\x1fJet")
130 .update_weight_then_32(word.len() as u64, ihr_pass2.to_parts().0)
131 .into_merkle_root()
132 }
133
134 #[rustfmt::skip]
135 const UNIT_IV: Midstate = Midstate::new([
136 0xc4, 0x0a, 0x10, 0x26, 0x3f, 0x74, 0x36, 0xb4,
137 0x16, 0x0a, 0xcb, 0xef, 0x1c, 0x36, 0xfb, 0xa4,
138 0xbe, 0x4d, 0x95, 0xdf, 0x18, 0x1a, 0x96, 0x8a,
139 0xfe, 0xab, 0x5e, 0xac, 0x24, 0x7a, 0xdf, 0xf7,
140 ], 64);
141
142 #[rustfmt::skip]
143 const IDEN_IV: Midstate = Midstate::new([
144 0x54, 0x1a, 0x1a, 0x69, 0xbd, 0x4b, 0xcb, 0xda,
145 0x7f, 0x34, 0x31, 0x0e, 0x30, 0x78, 0xf7, 0x26,
146 0x44, 0x31, 0x22, 0xfb, 0xcc, 0x1c, 0xb5, 0x36,
147 0x0c, 0x78, 0x64, 0xec, 0x0d, 0x32, 0x3a, 0xc0,
148 ], 64);
149
150 #[rustfmt::skip]
151 const INJL_IV: Midstate = Midstate::new([
152 0x54, 0xe9, 0x1d, 0x18, 0xd8, 0xf8, 0x1f, 0x6d,
153 0x29, 0x86, 0xbb, 0x58, 0x47, 0x9a, 0x54, 0xeb,
154 0x63, 0x0e, 0x95, 0x23, 0xb6, 0x9e, 0xe8, 0x53,
155 0x29, 0x80, 0xd0, 0x55, 0x58, 0x19, 0x4f, 0x15,
156 ], 64);
157
158 #[rustfmt::skip]
159 const INJR_IV: Midstate = Midstate::new([
160 0xd7, 0x0f, 0xfd, 0xce, 0x97, 0x77, 0x7b, 0x4d,
161 0xfe, 0x31, 0xfd, 0x9f, 0xf5, 0xd0, 0x17, 0xa6,
162 0x30, 0x5d, 0x7e, 0xc6, 0x0d, 0xf3, 0xb1, 0xbf,
163 0x6d, 0x25, 0xe8, 0x16, 0x33, 0xde, 0xd4, 0xbf,
164 ], 64);
165
166 #[rustfmt::skip]
167 const TAKE_IV: Midstate = Midstate::new([
168 0x50, 0x5f, 0xc0, 0x81, 0xb5, 0xba, 0x2a, 0xcd,
169 0x09, 0x50, 0x67, 0xc3, 0xdf, 0xb8, 0xea, 0x12,
170 0x6f, 0xa1, 0x5d, 0x55, 0xcb, 0x21, 0x1e, 0x6a,
171 0xed, 0x34, 0xe8, 0xd1, 0xe3, 0x7a, 0xf0, 0xfa,
172 ], 64);
173
174 #[rustfmt::skip]
175 const DROP_IV: Midstate = Midstate::new([
176 0x8a, 0x30, 0x8d, 0x38, 0xa1, 0x13, 0xa2, 0x60,
177 0xb4, 0xc7, 0x14, 0x5a, 0xbd, 0xc5, 0x22, 0x4d,
178 0xeb, 0x70, 0x13, 0x79, 0x59, 0x0e, 0x0c, 0x8c,
179 0x38, 0x86, 0x0b, 0xab, 0x12, 0x71, 0xa8, 0xa8,
180 ], 64);
181
182 #[rustfmt::skip]
183 const COMP_IV: Midstate = Midstate::new([
184 0x57, 0xec, 0x23, 0xa2, 0xa4, 0x77, 0x8e, 0x01,
185 0x58, 0xa6, 0x21, 0x7a, 0xea, 0x3e, 0xf7, 0x42,
186 0x8b, 0xa0, 0x90, 0x92, 0x73, 0xb9, 0x73, 0xfa,
187 0x14, 0x32, 0xa9, 0x27, 0x84, 0x3e, 0x92, 0x7a,
188 ], 64);
189
190 #[rustfmt::skip]
191 const CASE_IV: Midstate = Midstate::new([
192 0x29, 0x5e, 0x2a, 0x6d, 0xc8, 0xc5, 0xce, 0x59,
193 0xe4, 0xed, 0xcf, 0xe9, 0xb4, 0xd8, 0xf7, 0x64,
194 0x13, 0x3a, 0xa5, 0x51, 0x4b, 0xd3, 0xee, 0x8b,
195 0x4b, 0x75, 0xec, 0x8f, 0x4d, 0xeb, 0x08, 0xbe,
196 ], 64);
197
198 #[rustfmt::skip]
199 const PAIR_IV: Midstate = Midstate::new([
200 0x7d, 0x5e, 0x6d, 0xac, 0x15, 0xb1, 0x42, 0x8a,
201 0x0d, 0x26, 0x0c, 0x94, 0x29, 0xdb, 0xe8, 0x89,
202 0x65, 0x93, 0xf3, 0x1f, 0x70, 0x86, 0x27, 0xee,
203 0x75, 0xb2, 0x7e, 0xee, 0xfd, 0xd0, 0x50, 0x05,
204 ], 64);
205
206 #[rustfmt::skip]
207 const DISCONNECT_IV: Midstate = Midstate::new([
208 0x35, 0x33, 0x8b, 0x5b, 0x81, 0x74, 0x0c, 0x6d,
209 0x67, 0xdc, 0x1e, 0xa3, 0xc8, 0x31, 0xe4, 0xc0,
210 0xaf, 0xd8, 0x64, 0x09, 0xbc, 0x04, 0xd0, 0xdd,
211 0x43, 0x24, 0xb7, 0xd9, 0xd5, 0x83, 0xf4, 0xeb,
212 ], 64);
213
214 #[rustfmt::skip]
215 const WITNESS_IV: Midstate = Midstate::new([
216 0xa0, 0xfc, 0x8d, 0xeb, 0xd6, 0x79, 0x69, 0x17,
217 0xc8, 0x6b, 0x77, 0xad, 0xed, 0x82, 0xe6, 0xc6,
218 0x16, 0x49, 0x88, 0x9a, 0xe8, 0xf2, 0xed, 0x65,
219 0xb5, 0x7b, 0x41, 0xaa, 0x9d, 0x90, 0xe3, 0x75,
220 ], 64);
221
222 #[rustfmt::skip]
223 const FAIL_IV: Midstate = Midstate::new([
224 0x22, 0x83, 0xc1, 0x81, 0x9e, 0x69, 0x2f, 0x96,
225 0x85, 0xfe, 0x95, 0x40, 0x76, 0xc5, 0x16, 0x7c,
226 0x03, 0xbd, 0xe7, 0xcc, 0xda, 0xab, 0x00, 0x5e,
227 0x55, 0x36, 0x12, 0x2e, 0x18, 0xf7, 0x23, 0x7a,
228 ], 64);
229
230 #[rustfmt::skip]
231 const CONST_WORD_IV: Midstate = Midstate::new([
232 0x0c, 0x5b, 0xc1, 0xce, 0xc8, 0xf1, 0x41, 0x85,
233 0x0e, 0x33, 0x3e, 0x28, 0xea, 0x01, 0xc0, 0x5a,
234 0xc6, 0x42, 0xeb, 0x30, 0xb4, 0x9e, 0x69, 0x2c,
235 0x56, 0xb1, 0x22, 0xbb, 0x69, 0x49, 0xc5, 0xcd,
236 ], 64);
237
238 #[rustfmt::skip]
240 const BITS: [Cmr; 2] = [
241 Cmr([
242 0x88, 0x81, 0xaf, 0xf5, 0x16, 0x0c, 0xc0, 0xc9,
243 0xf8, 0xec, 0xea, 0xd8, 0xb4, 0x01, 0xfa, 0x97,
244 0xee, 0xf5, 0xfc, 0x60, 0x75, 0x2e, 0x98, 0xd2,
245 0x47, 0x56, 0x1a, 0x4d, 0xa6, 0xce, 0x96, 0x5e,
246 ]),
247 Cmr([
248 0xa0, 0x43, 0x8b, 0x72, 0x36, 0x48, 0x72, 0x7b,
249 0x3f, 0x2d, 0x18, 0x5f, 0xcd, 0x95, 0x69, 0xe0,
250 0x22, 0xa4, 0x47, 0x8e, 0xb2, 0x5f, 0xdf, 0xa5,
251 0x38, 0xea, 0xc5, 0x9d, 0x81, 0x7c, 0x31, 0x1c,
252 ]),
253 ];
254}
255
256#[cfg(feature = "elements")] pub struct ConstructibleCmr<'brand> {
261 pub cmr: Cmr,
262 pub arrow: Arrow<'brand>,
263}
264
265#[cfg(feature = "elements")] impl<'brand> CoreConstructible<'brand> for ConstructibleCmr<'brand> {
267 fn iden(inference_context: &types::Context<'brand>) -> Self {
268 ConstructibleCmr {
269 cmr: Cmr::iden(),
270 arrow: Arrow::iden(inference_context),
271 }
272 }
273
274 fn unit(inference_context: &types::Context<'brand>) -> Self {
275 ConstructibleCmr {
276 cmr: Cmr::unit(),
277 arrow: Arrow::unit(inference_context),
278 }
279 }
280
281 fn injl(child: &Self) -> Self {
282 ConstructibleCmr {
283 cmr: Cmr::injl(child.cmr),
284 arrow: Arrow::injl(child.arrow()),
285 }
286 }
287
288 fn injr(child: &Self) -> Self {
289 ConstructibleCmr {
290 cmr: Cmr::injr(child.cmr),
291 arrow: Arrow::injr(child.arrow()),
292 }
293 }
294
295 fn take(child: &Self) -> Self {
296 ConstructibleCmr {
297 cmr: Cmr::take(child.cmr),
298 arrow: Arrow::take(child.arrow()),
299 }
300 }
301
302 fn drop_(child: &Self) -> Self {
303 ConstructibleCmr {
304 cmr: Cmr::drop(child.cmr),
305 arrow: Arrow::drop_(child.arrow()),
306 }
307 }
308
309 fn comp(left: &Self, right: &Self) -> Result<Self, Error> {
310 Ok(ConstructibleCmr {
311 cmr: Cmr::comp(left.cmr, right.cmr),
312 arrow: Arrow::comp(left.arrow(), right.arrow())?,
313 })
314 }
315
316 fn case(left: &Self, right: &Self) -> Result<Self, Error> {
317 Ok(ConstructibleCmr {
318 cmr: Cmr::case(left.cmr, right.cmr),
319 arrow: Arrow::case(left.arrow(), right.arrow())?,
320 })
321 }
322
323 fn assertl(left: &Self, right: Cmr) -> Result<Self, Error> {
324 Ok(ConstructibleCmr {
325 cmr: Cmr::case(left.cmr, right),
326 arrow: Arrow::assertl(left.arrow())?,
327 })
328 }
329
330 fn assertr(left: Cmr, right: &Self) -> Result<Self, Error> {
331 Ok(ConstructibleCmr {
332 cmr: Cmr::case(left, right.cmr),
333 arrow: Arrow::assertr(right.arrow())?,
334 })
335 }
336
337 fn pair(left: &Self, right: &Self) -> Result<Self, Error> {
338 Ok(ConstructibleCmr {
339 cmr: Cmr::pair(left.cmr, right.cmr),
340 arrow: Arrow::pair(left.arrow(), right.arrow())?,
341 })
342 }
343
344 fn fail(inference_context: &types::Context<'brand>, entropy: FailEntropy) -> Self {
345 ConstructibleCmr {
346 cmr: Cmr::fail(entropy),
347 arrow: Arrow::fail(inference_context),
348 }
349 }
350
351 fn const_word(inference_context: &types::Context<'brand>, word: Word) -> Self {
352 ConstructibleCmr {
353 cmr: Cmr::const_word(&word),
354 arrow: Arrow::const_word(inference_context, &word),
355 }
356 }
357
358 fn jet(inference_context: &types::Context<'brand>, jet: &dyn Jet) -> Self {
359 ConstructibleCmr {
360 cmr: jet.cmr(),
361 arrow: Arrow::jet(inference_context, jet),
362 }
363 }
364
365 fn arrow(&self) -> &Arrow<'brand> {
366 &self.arrow
367 }
368}
369
370#[cfg(feature = "elements")] impl<'brand, W> WitnessConstructible<'brand, W> for ConstructibleCmr<'brand> {
372 fn witness(inference_context: &types::Context<'brand>, _witness: W) -> Self {
373 ConstructibleCmr {
374 arrow: Arrow::witness(inference_context),
375 cmr: Cmr::witness(),
376 }
377 }
378}
379
380#[cfg(test)]
381mod tests {
382 use super::*;
383
384 use crate::node::{ConstructNode, CoreConstructible};
385 use crate::types;
386
387 use std::str::FromStr;
388 use std::sync::Arc;
389
390 #[test]
391 fn cmr_display_unit() {
392 types::Context::with_context(|ctx| {
393 let c = Arc::<ConstructNode>::unit(&ctx);
394
395 assert_eq!(
396 c.cmr().to_string(),
397 "c40a10263f7436b4160acbef1c36fba4be4d95df181a968afeab5eac247adff7"
398 );
399 assert_eq!(format!("{:.8}", c.cmr()), "c40a1026");
400
401 assert_eq!(
402 Cmr::from_str("c40a10263f7436b4160acbef1c36fba4be4d95df181a968afeab5eac247adff7"),
403 Ok(c.cmr()),
404 );
405 });
406 }
407
408 #[test]
409 fn fixed_const_word_cmr() {
410 let bit0 = Word::u1(0);
412 #[rustfmt::skip]
413 assert_eq!(
414 Cmr::const_word(&bit0),
415 Cmr::from_str("a51cfd799d0bc368f48208032fc3881953f35aa7fd2b985cb237cbad143e30d2").unwrap(),
416 );
417 }
418
419 #[test]
420 fn bit_cmr() {
421 types::Context::with_context(|ctx| {
422 let unit = Arc::<ConstructNode>::unit(&ctx);
423 let bit0 = Arc::<ConstructNode>::injl(&unit);
424 assert_eq!(bit0.cmr(), Cmr::BITS[0]);
425
426 let bit1 = Arc::<ConstructNode>::injr(&unit);
427 assert_eq!(bit1.cmr(), Cmr::BITS[1]);
428 });
429 }
430
431 #[test]
432 fn ivs() {
433 fn check_iv(target: Midstate, s: &'static str) {
434 let name = s
435 .trim_start_matches("Simplicity\x1f")
436 .strip_prefix("Commitment\x1f")
437 .unwrap_or("const_word");
438 assert_eq!(
451 target,
452 bip340_iv(s.as_bytes()),
453 "mismatch on IV for {}",
454 name
455 );
456 }
457
458 check_iv(Cmr::UNIT_IV, "Simplicity\x1fCommitment\x1funit");
459 check_iv(Cmr::IDEN_IV, "Simplicity\x1fCommitment\x1fiden");
460 check_iv(Cmr::INJL_IV, "Simplicity\x1fCommitment\x1finjl");
461 check_iv(Cmr::INJR_IV, "Simplicity\x1fCommitment\x1finjr");
462 check_iv(Cmr::TAKE_IV, "Simplicity\x1fCommitment\x1ftake");
463 check_iv(Cmr::DROP_IV, "Simplicity\x1fCommitment\x1fdrop");
464 check_iv(Cmr::COMP_IV, "Simplicity\x1fCommitment\x1fcomp");
465 check_iv(Cmr::CASE_IV, "Simplicity\x1fCommitment\x1fcase");
466 check_iv(Cmr::PAIR_IV, "Simplicity\x1fCommitment\x1fpair");
467 check_iv(Cmr::DISCONNECT_IV, "Simplicity\x1fCommitment\x1fdisconnect");
468 check_iv(Cmr::WITNESS_IV, "Simplicity\x1fCommitment\x1fwitness");
469 check_iv(Cmr::FAIL_IV, "Simplicity\x1fCommitment\x1ffail");
470 check_iv(Cmr::CONST_WORD_IV, "Simplicity\x1fIdentity");
471 }
472
473 #[test]
474 fn const_bits() {
475 fn scribe<'brand>(ctx: &types::Context<'brand>, bit: u8) -> Arc<ConstructNode<'brand>> {
477 match bit {
478 0 => Arc::<ConstructNode>::injl(&Arc::<ConstructNode>::unit(ctx)),
479 1 => Arc::<ConstructNode>::injr(&Arc::<ConstructNode>::unit(ctx)),
480 _ => panic!("Unexpected bit {bit}"),
481 }
482 }
483
484 fn check_bit(target: Cmr, index: u8) {
485 types::Context::with_context(|ctx| {
496 assert_eq!(
497 target,
498 scribe(&ctx, index).cmr(),
499 "mismatch on CMR for bit {index}",
500 );
501 });
502 }
503
504 for index in 0..2u8 {
505 check_bit(Cmr::BITS[usize::from(index)], index)
506 }
507 }
508}