simplicity/merkle/
cmr.rs

1// SPDX-License-Identifier: CC0-1.0
2
3use crate::impl_midstate_wrapper;
4use crate::jet::Jet;
5use crate::node::{
6    CoreConstructible, DisconnectConstructible, JetConstructible, WitnessConstructible,
7};
8use crate::types::{self, Error};
9use crate::value::Word;
10use crate::{FailEntropy, Tmr};
11use hashes::sha256::Midstate;
12
13use super::bip340_iv;
14
15/// Commitment Merkle root
16///
17/// A Merkle root that commits to a node's combinator and recursively its children.
18///
19/// Importantly, witness data and right disconnect branches are _not_ included in the hash.
20/// This makes these elements malleable while preserving program identity (SegWit, delegation).
21///
22/// Uniquely identifies a program's structure in terms of combinators at commitment time.
23#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
24pub struct Cmr(pub(crate) Midstate);
25
26impl_midstate_wrapper!(Cmr);
27
28impl From<Tmr> for Cmr {
29    fn from(tmr: Tmr) -> Self {
30        Cmr::from_byte_array(tmr.to_byte_array())
31    }
32}
33
34impl Cmr {
35    /// Produce a CMR for an iden combinator
36    pub const fn iden() -> Self {
37        Self::IDEN_IV
38    }
39
40    /// Produce a CMR for a unit combinator
41    pub const fn unit() -> Self {
42        Self::UNIT_IV
43    }
44
45    /// Produce a CMR for an injl combinator
46    pub fn injl(child: Cmr) -> Self {
47        Self::INJL_IV.update_1(child)
48    }
49
50    /// Produce a CMR for an injr combinator
51    pub fn injr(child: Cmr) -> Self {
52        Self::INJR_IV.update_1(child)
53    }
54
55    /// Produce a CMR for a take combinator
56    pub fn take(child: Cmr) -> Self {
57        Self::TAKE_IV.update_1(child)
58    }
59
60    /// Produce a CMR for a drop combinator
61    pub fn drop(child: Cmr) -> Self {
62        Self::DROP_IV.update_1(child)
63    }
64
65    /// Produce a CMR for a comp combinator
66    pub fn comp(left: Cmr, right: Cmr) -> Self {
67        Self::COMP_IV.update(left, right)
68    }
69
70    /// Produce a CMR for a case combinator
71    pub fn case(left: Cmr, right: Cmr) -> Self {
72        Self::CASE_IV.update(left, right)
73    }
74
75    /// Produce a CMR for a pair combinator
76    pub fn pair(left: Cmr, right: Cmr) -> Self {
77        Self::PAIR_IV.update(left, right)
78    }
79
80    /// Produce a CMR for a disconnect combinator
81    pub fn disconnect(left: Cmr) -> Self {
82        Self::DISCONNECT_IV.update_1(left)
83    }
84
85    /// Produce a CMR for a witness combinator
86    pub fn witness() -> Self {
87        Self::WITNESS_IV
88    }
89
90    /// Produce a CMR for a fail combinator
91    pub fn fail(entropy: FailEntropy) -> Self {
92        Self::FAIL_IV.update_fail_entropy(entropy)
93    }
94
95    /// Produce a CMR for a jet
96    pub fn jet<J: Jet>(jet: J) -> Self {
97        jet.cmr()
98    }
99
100    /// Compute the CMR of a constant word jet
101    ///
102    /// This is equal to the IHR of the equivalent scribe, converted to a CMR in
103    /// the usual way for jets.
104    pub fn const_word(word: &Word) -> Self {
105        let w = 1 + word.n() as usize;
106
107        let mut cmr_stack = Vec::with_capacity(33);
108        // 1. Compute the CMR for the `scribe` corresponding to this word jet
109        for (bit_idx, bit) in word.iter().enumerate() {
110            cmr_stack.push(Cmr::BITS[usize::from(bit)]);
111            let mut j = bit_idx;
112            while j & 1 == 1 {
113                let right_cmr = cmr_stack.pop().unwrap();
114                let left_cmr = cmr_stack.pop().unwrap();
115                cmr_stack.push(Cmr::PAIR_IV.update(left_cmr, right_cmr));
116                j >>= 1;
117            }
118        }
119        assert_eq!(cmr_stack.len(), 1);
120
121        let ihr_iv = Self::CONST_WORD_IV;
122        let ihr_pass1 = ihr_iv.update_1(cmr_stack[0]);
123        // 2. Add TMRs to get the pass-two IHR
124        let ihr_pass2 = ihr_pass1.update(Tmr::unit().into(), Tmr::TWO_TWO_N[w - 1].into());
125        // 3. Convert to a jet CMR
126        Cmr(bip340_iv(b"Simplicity\x1fJet")).update_with_weight(word.len() as u64, ihr_pass2)
127    }
128
129    #[rustfmt::skip]
130    const UNIT_IV: Cmr = Cmr(Midstate([
131        0xc4, 0x0a, 0x10, 0x26, 0x3f, 0x74, 0x36, 0xb4,
132        0x16, 0x0a, 0xcb, 0xef, 0x1c, 0x36, 0xfb, 0xa4,
133        0xbe, 0x4d, 0x95, 0xdf, 0x18, 0x1a, 0x96, 0x8a,
134        0xfe, 0xab, 0x5e, 0xac, 0x24, 0x7a, 0xdf, 0xf7,
135    ]));
136
137    #[rustfmt::skip]
138    const IDEN_IV: Cmr = Cmr(Midstate([
139        0x54, 0x1a, 0x1a, 0x69, 0xbd, 0x4b, 0xcb, 0xda,
140        0x7f, 0x34, 0x31, 0x0e, 0x30, 0x78, 0xf7, 0x26,
141        0x44, 0x31, 0x22, 0xfb, 0xcc, 0x1c, 0xb5, 0x36,
142        0x0c, 0x78, 0x64, 0xec, 0x0d, 0x32, 0x3a, 0xc0,
143    ]));
144
145    #[rustfmt::skip]
146    const INJL_IV: Cmr = Cmr(Midstate([
147        0x54, 0xe9, 0x1d, 0x18, 0xd8, 0xf8, 0x1f, 0x6d,
148        0x29, 0x86, 0xbb, 0x58, 0x47, 0x9a, 0x54, 0xeb,
149        0x63, 0x0e, 0x95, 0x23, 0xb6, 0x9e, 0xe8, 0x53,
150        0x29, 0x80, 0xd0, 0x55, 0x58, 0x19, 0x4f, 0x15,
151    ]));
152
153    #[rustfmt::skip]
154    const INJR_IV: Cmr = Cmr(Midstate([
155        0xd7, 0x0f, 0xfd, 0xce, 0x97, 0x77, 0x7b, 0x4d,
156        0xfe, 0x31, 0xfd, 0x9f, 0xf5, 0xd0, 0x17, 0xa6,
157        0x30, 0x5d, 0x7e, 0xc6, 0x0d, 0xf3, 0xb1, 0xbf,
158        0x6d, 0x25, 0xe8, 0x16, 0x33, 0xde, 0xd4, 0xbf,
159    ]));
160
161    #[rustfmt::skip]
162    const TAKE_IV: Cmr = Cmr(Midstate([
163        0x50, 0x5f, 0xc0, 0x81, 0xb5, 0xba, 0x2a, 0xcd,
164        0x09, 0x50, 0x67, 0xc3, 0xdf, 0xb8, 0xea, 0x12,
165        0x6f, 0xa1, 0x5d, 0x55, 0xcb, 0x21, 0x1e, 0x6a,
166        0xed, 0x34, 0xe8, 0xd1, 0xe3, 0x7a, 0xf0, 0xfa,
167    ]));
168
169    #[rustfmt::skip]
170    const DROP_IV: Cmr = Cmr(Midstate([
171        0x8a, 0x30, 0x8d, 0x38, 0xa1, 0x13, 0xa2, 0x60,
172        0xb4, 0xc7, 0x14, 0x5a, 0xbd, 0xc5, 0x22, 0x4d,
173        0xeb, 0x70, 0x13, 0x79, 0x59, 0x0e, 0x0c, 0x8c,
174        0x38, 0x86, 0x0b, 0xab, 0x12, 0x71, 0xa8, 0xa8,
175    ]));
176
177    #[rustfmt::skip]
178    const COMP_IV: Cmr = Cmr(Midstate([
179        0x57, 0xec, 0x23, 0xa2, 0xa4, 0x77, 0x8e, 0x01,
180        0x58, 0xa6, 0x21, 0x7a, 0xea, 0x3e, 0xf7, 0x42,
181        0x8b, 0xa0, 0x90, 0x92, 0x73, 0xb9, 0x73, 0xfa,
182        0x14, 0x32, 0xa9, 0x27, 0x84, 0x3e, 0x92, 0x7a,
183    ]));
184
185    #[rustfmt::skip]
186    const CASE_IV: Cmr = Cmr(Midstate([
187        0x29, 0x5e, 0x2a, 0x6d, 0xc8, 0xc5, 0xce, 0x59,
188        0xe4, 0xed, 0xcf, 0xe9, 0xb4, 0xd8, 0xf7, 0x64,
189        0x13, 0x3a, 0xa5, 0x51, 0x4b, 0xd3, 0xee, 0x8b,
190        0x4b, 0x75, 0xec, 0x8f, 0x4d, 0xeb, 0x08, 0xbe,
191    ]));
192
193    #[rustfmt::skip]
194    const PAIR_IV: Cmr = Cmr(Midstate([
195        0x7d, 0x5e, 0x6d, 0xac, 0x15, 0xb1, 0x42, 0x8a,
196        0x0d, 0x26, 0x0c, 0x94, 0x29, 0xdb, 0xe8, 0x89,
197        0x65, 0x93, 0xf3, 0x1f, 0x70, 0x86, 0x27, 0xee,
198        0x75, 0xb2, 0x7e, 0xee, 0xfd, 0xd0, 0x50, 0x05,
199    ]));
200
201    #[rustfmt::skip]
202    const DISCONNECT_IV: Cmr = Cmr(Midstate([
203        0x35, 0x33, 0x8b, 0x5b, 0x81, 0x74, 0x0c, 0x6d,
204        0x67, 0xdc, 0x1e, 0xa3, 0xc8, 0x31, 0xe4, 0xc0,
205        0xaf, 0xd8, 0x64, 0x09, 0xbc, 0x04, 0xd0, 0xdd,
206        0x43, 0x24, 0xb7, 0xd9, 0xd5, 0x83, 0xf4, 0xeb,
207    ]));
208
209    #[rustfmt::skip]
210    const WITNESS_IV: Cmr = Cmr(Midstate([
211        0xa0, 0xfc, 0x8d, 0xeb, 0xd6, 0x79, 0x69, 0x17,
212        0xc8, 0x6b, 0x77, 0xad, 0xed, 0x82, 0xe6, 0xc6,
213        0x16, 0x49, 0x88, 0x9a, 0xe8, 0xf2, 0xed, 0x65,
214        0xb5, 0x7b, 0x41, 0xaa, 0x9d, 0x90, 0xe3, 0x75,
215    ]));
216
217    #[rustfmt::skip]
218    const FAIL_IV: Cmr = Cmr(Midstate([
219        0x22, 0x83, 0xc1, 0x81, 0x9e, 0x69, 0x2f, 0x96,
220        0x85, 0xfe, 0x95, 0x40, 0x76, 0xc5, 0x16, 0x7c,
221        0x03, 0xbd, 0xe7, 0xcc, 0xda, 0xab, 0x00, 0x5e,
222        0x55, 0x36, 0x12, 0x2e, 0x18, 0xf7, 0x23, 0x7a,
223    ]));
224
225    #[rustfmt::skip]
226    const CONST_WORD_IV: Cmr = Cmr(Midstate([
227        0x0c, 0x5b, 0xc1, 0xce, 0xc8, 0xf1, 0x41, 0x85,
228        0x0e, 0x33, 0x3e, 0x28, 0xea, 0x01, 0xc0, 0x5a,
229        0xc6, 0x42, 0xeb, 0x30, 0xb4, 0x9e, 0x69, 0x2c,
230        0x56, 0xb1, 0x22, 0xbb, 0x69, 0x49, 0xc5, 0xcd,
231    ]));
232
233    /// CMRs for the bits 0 and 1 -- injl(unit) and injr(unit) respectively
234    #[rustfmt::skip]
235    const BITS: [Cmr; 2] = [
236        Cmr(Midstate([
237            0x88, 0x81, 0xaf, 0xf5, 0x16, 0x0c, 0xc0, 0xc9,
238            0xf8, 0xec, 0xea, 0xd8, 0xb4, 0x01, 0xfa, 0x97,
239            0xee, 0xf5, 0xfc, 0x60, 0x75, 0x2e, 0x98, 0xd2,
240            0x47, 0x56, 0x1a, 0x4d, 0xa6, 0xce, 0x96, 0x5e,
241        ])),
242        Cmr(Midstate([
243            0xa0, 0x43, 0x8b, 0x72, 0x36, 0x48, 0x72, 0x7b,
244            0x3f, 0x2d, 0x18, 0x5f, 0xcd, 0x95, 0x69, 0xe0,
245            0x22, 0xa4, 0x47, 0x8e, 0xb2, 0x5f, 0xdf, 0xa5,
246            0x38, 0xea, 0xc5, 0x9d, 0x81, 0x7c, 0x31, 0x1c,
247        ])),
248    ];
249}
250
251/// Wrapper around a CMR which allows it to be constructed with the
252/// `*Constructible*` traits, allowing CMRs to be computed using the
253/// same generic construction code that nodes are.
254pub struct ConstructibleCmr<'brand> {
255    pub cmr: Cmr,
256    pub inference_context: types::Context<'brand>,
257}
258
259impl<'brand> CoreConstructible<'brand> for ConstructibleCmr<'brand> {
260    fn iden(inference_context: &types::Context<'brand>) -> Self {
261        ConstructibleCmr {
262            cmr: Cmr::iden(),
263            inference_context: inference_context.shallow_clone(),
264        }
265    }
266
267    fn unit(inference_context: &types::Context<'brand>) -> Self {
268        ConstructibleCmr {
269            cmr: Cmr::unit(),
270            inference_context: inference_context.shallow_clone(),
271        }
272    }
273
274    fn injl(child: &Self) -> Self {
275        ConstructibleCmr {
276            cmr: Cmr::injl(child.cmr),
277            inference_context: child.inference_context.shallow_clone(),
278        }
279    }
280
281    fn injr(child: &Self) -> Self {
282        ConstructibleCmr {
283            cmr: Cmr::injl(child.cmr),
284            inference_context: child.inference_context.shallow_clone(),
285        }
286    }
287
288    fn take(child: &Self) -> Self {
289        ConstructibleCmr {
290            cmr: Cmr::take(child.cmr),
291            inference_context: child.inference_context.shallow_clone(),
292        }
293    }
294
295    fn drop_(child: &Self) -> Self {
296        ConstructibleCmr {
297            cmr: Cmr::drop(child.cmr),
298            inference_context: child.inference_context.shallow_clone(),
299        }
300    }
301
302    fn comp(left: &Self, right: &Self) -> Result<Self, Error> {
303        left.inference_context.check_eq(&right.inference_context)?;
304        Ok(ConstructibleCmr {
305            cmr: Cmr::comp(left.cmr, right.cmr),
306            inference_context: left.inference_context.shallow_clone(),
307        })
308    }
309
310    fn case(left: &Self, right: &Self) -> Result<Self, Error> {
311        left.inference_context.check_eq(&right.inference_context)?;
312        Ok(ConstructibleCmr {
313            cmr: Cmr::case(left.cmr, right.cmr),
314            inference_context: left.inference_context.shallow_clone(),
315        })
316    }
317
318    fn assertl(left: &Self, right: Cmr) -> Result<Self, Error> {
319        Ok(ConstructibleCmr {
320            cmr: Cmr::case(left.cmr, right),
321            inference_context: left.inference_context.shallow_clone(),
322        })
323    }
324
325    fn assertr(left: Cmr, right: &Self) -> Result<Self, Error> {
326        Ok(ConstructibleCmr {
327            cmr: Cmr::case(left, right.cmr),
328            inference_context: right.inference_context.shallow_clone(),
329        })
330    }
331
332    fn pair(left: &Self, right: &Self) -> Result<Self, Error> {
333        left.inference_context.check_eq(&right.inference_context)?;
334        Ok(ConstructibleCmr {
335            cmr: Cmr::pair(left.cmr, right.cmr),
336            inference_context: left.inference_context.shallow_clone(),
337        })
338    }
339
340    fn fail(inference_context: &types::Context<'brand>, entropy: FailEntropy) -> Self {
341        ConstructibleCmr {
342            cmr: Cmr::fail(entropy),
343            inference_context: inference_context.shallow_clone(),
344        }
345    }
346
347    fn const_word(inference_context: &types::Context<'brand>, word: Word) -> Self {
348        ConstructibleCmr {
349            cmr: Cmr::const_word(&word),
350            inference_context: inference_context.shallow_clone(),
351        }
352    }
353
354    fn inference_context(&self) -> &types::Context<'brand> {
355        &self.inference_context
356    }
357}
358
359impl<'brand, X> DisconnectConstructible<'brand, X> for ConstructibleCmr<'brand> {
360    // Specifically with disconnect we don't check for consistency between the
361    // type inference context of the disconnected node, if any, and that of
362    // the left node. The idea is, from the point of view of (Constructible)Cmr,
363    // the right child of disconnect doesn't even exist.
364    fn disconnect(left: &Self, _right: &X) -> Result<Self, Error> {
365        Ok(ConstructibleCmr {
366            cmr: Cmr::disconnect(left.cmr),
367            inference_context: left.inference_context.shallow_clone(),
368        })
369    }
370}
371
372impl<'brand, W> WitnessConstructible<'brand, W> for ConstructibleCmr<'brand> {
373    fn witness(inference_context: &types::Context<'brand>, _witness: W) -> Self {
374        ConstructibleCmr {
375            cmr: Cmr::witness(),
376            inference_context: inference_context.shallow_clone(),
377        }
378    }
379}
380
381impl<'brand, J: Jet> JetConstructible<'brand, J> for ConstructibleCmr<'brand> {
382    fn jet(inference_context: &types::Context<'brand>, jet: J) -> Self {
383        ConstructibleCmr {
384            cmr: jet.cmr(),
385            inference_context: inference_context.shallow_clone(),
386        }
387    }
388}
389
390#[cfg(test)]
391mod tests {
392    use super::*;
393
394    use crate::jet::Core;
395    use crate::node::{ConstructNode, CoreConstructible};
396
397    use std::str::FromStr;
398    use std::sync::Arc;
399
400    #[test]
401    fn cmr_display_unit() {
402        types::Context::with_context(|ctx| {
403            let c = Arc::<ConstructNode<Core>>::unit(&ctx);
404
405            assert_eq!(
406                c.cmr().to_string(),
407                "c40a10263f7436b4160acbef1c36fba4be4d95df181a968afeab5eac247adff7"
408            );
409            assert_eq!(format!("{:.8}", c.cmr()), "c40a1026");
410
411            assert_eq!(
412                Cmr::from_str("c40a10263f7436b4160acbef1c36fba4be4d95df181a968afeab5eac247adff7"),
413                Ok(c.cmr()),
414            );
415        });
416    }
417
418    #[test]
419    fn fixed_const_word_cmr() {
420        // Checked against C implementation
421        let bit0 = Word::u1(0);
422        #[rustfmt::skip]
423        assert_eq!(
424            Cmr::const_word(&bit0),
425            Cmr::from_str("a51cfd799d0bc368f48208032fc3881953f35aa7fd2b985cb237cbad143e30d2").unwrap(),
426        );
427    }
428
429    #[test]
430    fn bit_cmr() {
431        types::Context::with_context(|ctx| {
432            let unit = Arc::<ConstructNode<Core>>::unit(&ctx);
433            let bit0 = Arc::<ConstructNode<Core>>::injl(&unit);
434            assert_eq!(bit0.cmr(), Cmr::BITS[0]);
435
436            let bit1 = Arc::<ConstructNode<_>>::injr(&unit);
437            assert_eq!(bit1.cmr(), Cmr::BITS[1]);
438        });
439    }
440
441    #[test]
442    fn ivs() {
443        fn check_iv(target: Cmr, s: &'static str) {
444            let name = s
445                .trim_start_matches("Simplicity\x1f")
446                .strip_prefix("Commitment\x1f")
447                .unwrap_or("const_word");
448            // Uncomment this if the IVs ever change
449            /*
450            let target = Cmr(bip340_iv(s.as_bytes()));
451            println!("    #[rustfmt::skip]");
452            println!("    const {}_IV: Cmr = Cmr(Midstate([", name.to_ascii_uppercase());
453            print!("       "); for ch in &target.0[0..8] { print!(" 0x{:02x},", ch); }; println!();
454            print!("       "); for ch in &target.0[8..16] { print!(" 0x{:02x},", ch); }; println!();
455            print!("       "); for ch in &target.0[16..24] { print!(" 0x{:02x},", ch); }; println!();
456            print!("       "); for ch in &target.0[24..32] { print!(" 0x{:02x},", ch); }; println!();
457            println!("    ]));");
458            println!();
459            */
460            assert_eq!(
461                target,
462                Cmr(bip340_iv(s.as_bytes())),
463                "mismatch on IV for {}",
464                name
465            );
466        }
467
468        check_iv(Cmr::UNIT_IV, "Simplicity\x1fCommitment\x1funit");
469        check_iv(Cmr::IDEN_IV, "Simplicity\x1fCommitment\x1fiden");
470        check_iv(Cmr::INJL_IV, "Simplicity\x1fCommitment\x1finjl");
471        check_iv(Cmr::INJR_IV, "Simplicity\x1fCommitment\x1finjr");
472        check_iv(Cmr::TAKE_IV, "Simplicity\x1fCommitment\x1ftake");
473        check_iv(Cmr::DROP_IV, "Simplicity\x1fCommitment\x1fdrop");
474        check_iv(Cmr::COMP_IV, "Simplicity\x1fCommitment\x1fcomp");
475        check_iv(Cmr::CASE_IV, "Simplicity\x1fCommitment\x1fcase");
476        check_iv(Cmr::PAIR_IV, "Simplicity\x1fCommitment\x1fpair");
477        check_iv(Cmr::DISCONNECT_IV, "Simplicity\x1fCommitment\x1fdisconnect");
478        check_iv(Cmr::WITNESS_IV, "Simplicity\x1fCommitment\x1fwitness");
479        check_iv(Cmr::FAIL_IV, "Simplicity\x1fCommitment\x1ffail");
480        check_iv(Cmr::CONST_WORD_IV, "Simplicity\x1fIdentity");
481    }
482
483    #[test]
484    fn const_bits() {
485        /// The scribe expression, as defined in the Simplicity tech report.
486        fn scribe<'brand>(
487            ctx: &types::Context<'brand>,
488            bit: u8,
489        ) -> Arc<ConstructNode<'brand, Core>> {
490            match bit {
491                0 => Arc::<ConstructNode<Core>>::injl(&Arc::<ConstructNode<Core>>::unit(ctx)),
492                1 => Arc::<ConstructNode<Core>>::injr(&Arc::<ConstructNode<Core>>::unit(ctx)),
493                _ => panic!("Unexpected bit {bit}"),
494            }
495        }
496
497        fn check_bit(target: Cmr, index: u8) {
498            // Uncomment this if the IVs ever change
499            /*
500            let target = scribe(index).cmr();
501            println!("    Cmr(Midstate([");
502            print!("       "); for ch in &target.0[0..8] { print!(" 0x{:02x},", ch); }; println!();
503            print!("       "); for ch in &target.0[8..16] { print!(" 0x{:02x},", ch); }; println!();
504            print!("       "); for ch in &target.0[16..24] { print!(" 0x{:02x},", ch); }; println!();
505            print!("       "); for ch in &target.0[24..32] { print!(" 0x{:02x},", ch); }; println!();
506            println!("    ])),");
507            */
508            types::Context::with_context(|ctx| {
509                assert_eq!(
510                    target,
511                    scribe(&ctx, index).cmr(),
512                    "mismatch on CMR for bit {index}",
513                );
514            });
515        }
516
517        for index in 0..2u8 {
518            check_bit(Cmr::BITS[usize::from(index)], index)
519        }
520    }
521}