1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use std::io;
use bc::{TapCode, TapScript, LIB_NAME_BP};
use commit_verify::{mpc, strategies, CommitEncode, CommitStrategy, CommitVerify};
use super::Lnpbp12;
pub const TAPRET_SCRIPT_COMMITMENT_PREFIX: [u8; 31] = [
    0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
    0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x6a, 0x21,
];
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_BP)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))]
pub struct TapretCommitment {
    pub mpc: mpc::Commitment,
    pub nonce: u8,
}
impl TapretCommitment {
    pub fn with(mpc: mpc::Commitment, nonce: u8) -> Self { Self { mpc, nonce } }
}
impl CommitStrategy for TapretCommitment {
    type Strategy = strategies::Strict;
}
impl CommitVerify<TapretCommitment, Lnpbp12> for TapScript {
    fn commit(commitment: &TapretCommitment) -> Self {
        let mut tapret = TapScript::with_capacity(64);
        for _ in 0..29 {
            tapret.push_opcode(TapCode::Reserved);
        }
        tapret.push_opcode(TapCode::Return);
        let mut data = io::Cursor::new([0u8; 33]);
        commitment.commit_encode(&mut data);
        tapret.push_slice(&data.into_inner());
        tapret
    }
}
#[cfg(test)]
mod test {
    use strict_encoding::StrictDumb;
    use super::*;
    pub fn commitment() -> TapretCommitment {
        TapretCommitment {
            mpc: mpc::Commitment::strict_dumb(),
            nonce: 8,
        }
    }
    #[test]
    pub fn commitment_prefix() {
        let script = TapScript::commit(&commitment());
        assert_eq!(TAPRET_SCRIPT_COMMITMENT_PREFIX, script[0..31]);
    }
    #[test]
    pub fn commiment_serialization() {
        let commitment = commitment();
        let script = TapScript::commit(&commitment);
        eprintln!("{script:x}");
        assert_eq!(script[63], commitment.nonce);
        assert_eq!(&script[31..63], commitment.mpc.as_slice());
    }
}