Skip to main content

simplicity/merkle/
tmr.rs

1// SPDX-License-Identifier: CC0-1.0
2
3use crate::merkle::midstate::MidstateExt;
4use hashes::sha256::Midstate;
5
6super::impl_mr_type! {
7    /// Type Merkle root
8    ///
9    /// A Merkle root that commits to a type's primitive (unit, sum, product)
10    /// and recursively its sub-types.
11    ///
12    /// Uniquely identifies a type.
13    #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
14    pub struct Tmr([u8; 32]);
15}
16
17impl Tmr {
18    #[rustfmt::skip]
19    const UNIT_IV: Midstate = Midstate::new([
20        0x50, 0xb3, 0x8c, 0xd7, 0x64, 0x75, 0xff, 0x89,
21        0x29, 0x28, 0x8b, 0xfc, 0xd0, 0xd9, 0xdf, 0x0e,
22        0x4a, 0x24, 0x1c, 0x0a, 0x57, 0x08, 0x57, 0x2a,
23        0xd2, 0x64, 0x19, 0x2a, 0x4f, 0xe6, 0x7b, 0xee,
24    ], 64);
25
26    #[rustfmt::skip]
27    const SUM_IV: Midstate = Midstate::new([
28        0x92, 0x0c, 0xfd, 0x83, 0xcf, 0x96, 0xbb, 0x32,
29        0x73, 0x17, 0x36, 0x0f, 0x6d, 0x3a, 0xd7, 0x60,
30        0x1e, 0xef, 0x0a, 0x16, 0xdd, 0x53, 0x14, 0x6c,
31        0x2e, 0x5d, 0xe3, 0x5f, 0x51, 0xef, 0x8d, 0xa4,
32    ], 64);
33
34    #[rustfmt::skip]
35    const PROD_IV: Midstate = Midstate::new([
36        0xae, 0x99, 0x2a, 0x3e, 0xe0, 0x71, 0x3b, 0xf6,
37        0x19, 0x5d, 0x3b, 0xac, 0x1a, 0xf5, 0x05, 0xa7,
38        0x29, 0xc1, 0x4d, 0x47, 0x95, 0x58, 0xf0, 0xd6,
39        0x29, 0x96, 0x30, 0xf7, 0xfa, 0x97, 0x2e, 0xf8,
40    ], 64);
41
42    /// The TMRs of the types TWO^(2^n) for small values of n
43    #[rustfmt::skip]
44    pub const TWO_TWO_N: [Tmr; 32] = [
45        Tmr([
46            0x88, 0x5a, 0x22, 0xde, 0x3e, 0xdb, 0x3f, 0x40,
47            0xdb, 0x06, 0x09, 0xc2, 0x40, 0x23, 0x30, 0x3f,
48            0xec, 0x67, 0x87, 0xbe, 0x4d, 0x49, 0x21, 0xe4,
49            0x5e, 0xe9, 0xd9, 0x83, 0xac, 0xb5, 0xd8, 0x9d,
50        ]),
51        Tmr([
52            0x55, 0x22, 0xba, 0x1c, 0x92, 0x89, 0x4d, 0xf2,
53            0x57, 0x23, 0xcf, 0xeb, 0x5a, 0xf2, 0x59, 0xf4,
54            0xc5, 0x5a, 0x5c, 0xfc, 0x82, 0x00, 0xd5, 0x9b,
55            0xad, 0x09, 0x64, 0x99, 0x7f, 0x9b, 0x2b, 0x04,
56        ]),
57        Tmr([
58            0xfa, 0x28, 0xba, 0x9f, 0x0f, 0x07, 0xb4, 0xfa,
59            0xe4, 0xdd, 0x86, 0x23, 0x61, 0x41, 0x12, 0xff,
60            0x3b, 0xaf, 0xab, 0xe2, 0x9c, 0x41, 0x5d, 0x2e,
61            0x0c, 0x1e, 0xd3, 0xc4, 0x13, 0x51, 0x28, 0xe0,
62        ]),
63        Tmr([
64            0xd3, 0x43, 0xe4, 0xd5, 0xfa, 0xa4, 0xce, 0xa4,
65            0x4b, 0xb7, 0x11, 0xef, 0x4b, 0x1b, 0x96, 0xb7,
66            0xe0, 0xfb, 0x26, 0xcf, 0xa8, 0x5a, 0x96, 0x04,
67            0x39, 0xba, 0x84, 0x58, 0xc0, 0xb6, 0xc5, 0xc3,
68        ]),
69        Tmr([
70            0x62, 0x8c, 0x36, 0x1f, 0x09, 0xcb, 0x2e, 0x5b,
71            0xaa, 0xd9, 0xc6, 0xb7, 0x26, 0xa9, 0xfa, 0x95,
72            0xd1, 0xda, 0x67, 0x79, 0x7e, 0xe2, 0x4c, 0xcf,
73            0x01, 0x41, 0x0c, 0x97, 0x93, 0x39, 0x95, 0x00,
74        ]),
75        Tmr([
76            0xb1, 0xa9, 0xf9, 0x68, 0x78, 0x33, 0xdc, 0x44,
77            0xbc, 0x8f, 0x17, 0xd3, 0xcb, 0xc2, 0x55, 0xb7,
78            0xaa, 0x49, 0x9a, 0x78, 0xfe, 0xc8, 0x5c, 0xc9,
79            0x8a, 0x0c, 0x33, 0x5c, 0x86, 0xed, 0x26, 0xe9,
80        ]),
81        Tmr([
82            0xfd, 0x75, 0xbc, 0xd8, 0xcb, 0x55, 0xa5, 0xe4,
83            0x24, 0xe0, 0x92, 0x88, 0xac, 0x8e, 0xb4, 0x29,
84            0x42, 0x53, 0x4e, 0xc1, 0x09, 0x9b, 0x72, 0xbe,
85            0xce, 0x0e, 0xa2, 0xc5, 0x47, 0x9b, 0xf3, 0xe7,
86        ]),
87        Tmr([
88            0xe3, 0x94, 0xd2, 0xa0, 0x51, 0x6d, 0x73, 0x8d,
89            0x6e, 0x04, 0x59, 0xb9, 0x1b, 0xb0, 0xdd, 0x47,
90            0x1d, 0x0d, 0xaa, 0x77, 0x96, 0x71, 0xa5, 0x31,
91            0x3b, 0x62, 0x14, 0x0e, 0xc7, 0x0a, 0x22, 0x6e,
92        ]),
93        Tmr([
94            0xe4, 0xc4, 0x72, 0x8d, 0x87, 0x67, 0x49, 0xbe,
95            0xbe, 0x4d, 0x62, 0x97, 0xdf, 0xad, 0xd4, 0x2c,
96            0xe2, 0x68, 0x44, 0x50, 0x0d, 0x96, 0xc5, 0xe9,
97            0x14, 0x61, 0x57, 0x50, 0x8e, 0xb9, 0x09, 0x8f,
98        ]),
99        Tmr([
100            0x1a, 0xe5, 0x45, 0xb7, 0xc3, 0xfd, 0x85, 0xfe,
101            0x81, 0x6c, 0x70, 0xea, 0x4c, 0x78, 0xb7, 0x41,
102            0x9d, 0x8b, 0xe3, 0xc1, 0xfb, 0x3f, 0x72, 0x23,
103            0xfa, 0x7d, 0x8d, 0x50, 0x36, 0x75, 0x51, 0x8f,
104        ]),
105        Tmr([
106            0x6a, 0x9c, 0x72, 0x40, 0xe5, 0xd7, 0x1d, 0x5a,
107            0x83, 0x30, 0xb3, 0xb3, 0xb6, 0x65, 0x0b, 0xc3,
108            0x66, 0x6c, 0x3f, 0xef, 0x2e, 0x80, 0x3e, 0xd8,
109            0x64, 0xf1, 0x2f, 0xcd, 0x8f, 0xea, 0xc1, 0xca,
110        ]),
111        Tmr([
112            0x0a, 0x2a, 0x58, 0x7a, 0xeb, 0xc9, 0x6b, 0x0e,
113            0x3e, 0x26, 0x01, 0x38, 0x2e, 0xb3, 0x2a, 0x9f,
114            0x1e, 0x29, 0xc8, 0x50, 0x1c, 0xbd, 0xd8, 0x0e,
115            0x87, 0x05, 0xc0, 0xe7, 0xd3, 0xf5, 0xb3, 0x4f,
116        ]),
117        Tmr([
118            0xb3, 0xed, 0xb6, 0xfd, 0x83, 0x8e, 0xc4, 0x05,
119            0x7b, 0x76, 0x8c, 0x86, 0xb0, 0xe8, 0xa9, 0x6d,
120            0x1c, 0xe3, 0xf1, 0x69, 0x54, 0x31, 0x4d, 0xcd,
121            0x3d, 0xbf, 0x72, 0x85, 0xeb, 0xa5, 0x63, 0xa9,
122        ]),
123        Tmr([
124            0xd0, 0x47, 0x4c, 0x0c, 0x1e, 0x2c, 0x09, 0xd9,
125            0xc5, 0xf0, 0x50, 0x98, 0x93, 0x57, 0xce, 0x71,
126            0xab, 0x5d, 0x90, 0x4e, 0x8e, 0x2e, 0x82, 0x87,
127            0x42, 0x86, 0xc0, 0xc2, 0x12, 0xde, 0x3e, 0x71,
128        ]),
129        Tmr([
130            0x37, 0x92, 0x46, 0xdc, 0x86, 0x6d, 0x37, 0x0d,
131            0xbf, 0xc9, 0x70, 0x4f, 0xbc, 0x57, 0xcd, 0x7a,
132            0x6e, 0xb5, 0xed, 0xe7, 0x97, 0xa0, 0x0c, 0x4a,
133            0x72, 0xb3, 0xb4, 0xa5, 0xd9, 0xf0, 0x9f, 0xe1,
134        ]),
135        Tmr([
136            0x8a, 0x59, 0xe8, 0x3f, 0x43, 0xe2, 0xa1, 0xf9,
137            0x07, 0xd3, 0xa2, 0x96, 0x67, 0x53, 0x33, 0x6a,
138            0x1d, 0xa2, 0x0d, 0x23, 0xfe, 0x63, 0x63, 0x28,
139            0x58, 0xf9, 0x4e, 0xc0, 0x7d, 0x19, 0x13, 0xd2,
140        ]),
141        Tmr([
142            0x0f, 0x51, 0x95, 0x68, 0x9f, 0x55, 0x6d, 0x00,
143            0xbe, 0x92, 0xfc, 0x2d, 0xc5, 0x7b, 0xcb, 0xb1,
144            0x25, 0x62, 0x0f, 0xfc, 0x00, 0x96, 0x3c, 0x09,
145            0x14, 0xb1, 0x96, 0x15, 0x1a, 0x77, 0x84, 0x1c,
146        ]),
147        Tmr([
148            0x6d, 0x2a, 0x47, 0x99, 0xa1, 0x6e, 0xb6, 0x78,
149            0x4e, 0x49, 0x66, 0xb8, 0x1d, 0xa6, 0x27, 0xd3,
150            0x5a, 0xa7, 0x08, 0xfd, 0x97, 0x25, 0xd6, 0x04,
151            0x77, 0x7b, 0x14, 0x3e, 0x28, 0xd4, 0xac, 0xf0,
152        ]),
153        Tmr([
154            0x2a, 0x07, 0x5c, 0x50, 0xca, 0x10, 0xe5, 0x00,
155            0x92, 0x77, 0x86, 0xca, 0x86, 0xa5, 0x2b, 0xb7,
156            0xe5, 0x2d, 0xdb, 0x16, 0x42, 0xe3, 0x77, 0x45,
157            0xfb, 0x44, 0x14, 0x91, 0x39, 0xb3, 0x2d, 0x67,
158        ]),
159        Tmr([
160            0xf5, 0x67, 0xc8, 0x1b, 0x82, 0x5d, 0xc9, 0x00,
161            0xe0, 0xbc, 0x0c, 0x59, 0xce, 0xa6, 0xaa, 0x1f,
162            0x1f, 0x34, 0x28, 0x3f, 0xcb, 0xee, 0xff, 0x73,
163            0x2d, 0xb8, 0xe2, 0x17, 0x57, 0x6c, 0x22, 0x55,
164        ]),
165        Tmr([
166            0x0a, 0xee, 0x10, 0x39, 0xd3, 0xc8, 0xaf, 0x91,
167            0x41, 0xbc, 0xb9, 0xfd, 0xf3, 0xf8, 0x24, 0x1e,
168            0xf9, 0xfd, 0x4b, 0x85, 0x85, 0x3a, 0x79, 0xba,
169            0xbc, 0xfb, 0x2a, 0xb4, 0xdb, 0x8e, 0xf3, 0x8c,
170        ]),
171        Tmr([
172            0x30, 0xaa, 0xe9, 0xb8, 0xf2, 0xc6, 0xfa, 0xf0,
173            0x7a, 0x62, 0x07, 0x2f, 0x55, 0xb2, 0x96, 0x98,
174            0x5d, 0xd7, 0x3b, 0xc1, 0x04, 0x42, 0xc8, 0x02,
175            0x79, 0x32, 0xff, 0xf4, 0x1f, 0x2a, 0x2d, 0x72,
176        ]),
177        Tmr([
178            0xbc, 0x14, 0x6c, 0xb5, 0xae, 0x67, 0xe0, 0x0a,
179            0x6d, 0x8e, 0x3f, 0xd0, 0x56, 0xfb, 0x7a, 0x72,
180            0x82, 0x04, 0x84, 0xc6, 0x1a, 0xcf, 0x17, 0xfe,
181            0xcc, 0xf1, 0x30, 0xcb, 0xa6, 0x22, 0xd2, 0x7f,
182        ]),
183        Tmr([
184            0xa8, 0x67, 0xba, 0xcf, 0xf8, 0xd1, 0xc2, 0x5c,
185            0x9e, 0x82, 0x4f, 0x1b, 0x63, 0xa4, 0x9c, 0x17,
186            0x67, 0x9b, 0xba, 0x8a, 0xd8, 0x76, 0x99, 0xa0,
187            0xcd, 0xf7, 0x7d, 0xef, 0x0a, 0x1b, 0x75, 0x11,
188        ]),
189        Tmr([
190            0xc1, 0x28, 0xdc, 0x7e, 0x8d, 0x79, 0x4a, 0x7a,
191            0x48, 0x08, 0x14, 0x95, 0xa6, 0xeb, 0x2b, 0x2d,
192            0x3c, 0xb6, 0x6b, 0xc0, 0xe0, 0x33, 0x27, 0x3b,
193            0xf9, 0xdd, 0xbc, 0x98, 0x6c, 0x22, 0x68, 0x92,
194        ]),
195        Tmr([
196            0x19, 0x9f, 0xfd, 0xe4, 0x7d, 0x27, 0x91, 0xa3,
197            0x58, 0xf2, 0x3a, 0xe5, 0x08, 0x25, 0x16, 0xc6,
198            0x5e, 0x57, 0xf5, 0x5a, 0xe6, 0x6d, 0xdf, 0x44,
199            0x65, 0xba, 0xab, 0x4b, 0xfa, 0x3c, 0x3a, 0x5f,
200        ]),
201        Tmr([
202            0x40, 0x38, 0x09, 0x5d, 0xbb, 0x32, 0xe2, 0x7e,
203            0x6e, 0x31, 0x66, 0x52, 0x7b, 0xce, 0xdd, 0xa8,
204            0x4e, 0x8b, 0x21, 0xf6, 0xd4, 0x2f, 0x7e, 0x56,
205            0xea, 0xff, 0x21, 0x85, 0x6a, 0xd2, 0x04, 0xa2,
206        ]),
207        Tmr([
208            0xc3, 0xa0, 0xa6, 0xf8, 0x7e, 0x6c, 0x3f, 0x02,
209            0xbf, 0x98, 0x05, 0x1c, 0xe4, 0x5d, 0x6d, 0x69,
210            0x55, 0x38, 0x24, 0x78, 0xf1, 0x0f, 0xa0, 0x6a,
211            0xdd, 0x51, 0x30, 0xe5, 0x99, 0x17, 0xf8, 0xc7,
212        ]),
213        Tmr([
214            0x7c, 0x25, 0xbf, 0x44, 0x7a, 0x45, 0xba, 0x13,
215            0x23, 0xe8, 0xdb, 0x8b, 0x81, 0x78, 0x87, 0xa8,
216            0x85, 0x8b, 0xee, 0x25, 0x6e, 0x5c, 0xa3, 0x52,
217            0x8e, 0x79, 0xcf, 0xbc, 0x2d, 0x41, 0x9c, 0xe3,
218        ]),
219        Tmr([
220            0x75, 0xa7, 0x7a, 0x6c, 0x7b, 0x6d, 0xe9, 0x1d,
221            0x23, 0xc1, 0x00, 0x4d, 0x8e, 0xb0, 0xb3, 0x5d,
222            0x9c, 0xdf, 0x6f, 0xa1, 0xdf, 0xc7, 0xca, 0xbd,
223            0x04, 0x66, 0x92, 0xf1, 0xa2, 0x43, 0x14, 0x17,
224        ]),
225        Tmr([
226            0x9f, 0xc2, 0x4a, 0xb6, 0x99, 0x70, 0xf8, 0x66,
227            0x6d, 0x7b, 0x1e, 0x52, 0x5a, 0x3a, 0x8e, 0x79,
228            0x43, 0x99, 0x76, 0xe7, 0x79, 0x2b, 0xfe, 0x1a,
229            0x1b, 0x0d, 0x0d, 0x84, 0xff, 0x03, 0x84, 0x34,
230        ]),
231        Tmr([
232            0x64, 0x25, 0x1a, 0xb9, 0x70, 0x77, 0x17, 0x0e,
233            0x19, 0x91, 0x15, 0x76, 0x5e, 0x93, 0x43, 0xe7,
234            0x1b, 0x59, 0x0e, 0x41, 0x78, 0x88, 0xf2, 0xa8,
235            0x36, 0x43, 0x11, 0xd8, 0x65, 0x40, 0xed, 0xfa,
236        ]),
237    ];
238
239    /// The TMRs of the types (TWO^8)^<(2^(N + 1)) for small values of n
240    #[rustfmt::skip]
241    pub const BUFFER8_TWO_N_PLUS_ONE: [Tmr; 16] = [
242        Tmr([
243            0x66, 0x8c, 0x79, 0xa6, 0xf0, 0xe0, 0x86, 0xa6,
244            0x2d, 0x73, 0xf0, 0xc6, 0x52, 0xb1, 0x5c, 0x56,
245            0xb1, 0xd3, 0x53, 0x68, 0xe1, 0xff, 0xad, 0x76,
246            0xc9, 0xd4, 0xdb, 0xae, 0xb5, 0x2d, 0xe6, 0x2f,
247        ]),
248        Tmr([
249            0x9f, 0x91, 0xf5, 0x19, 0x9b, 0xb8, 0x16, 0x7a,
250            0x3b, 0x6c, 0xf8, 0xd0, 0x39, 0x75, 0x6e, 0x1b,
251            0x33, 0x18, 0x42, 0x6e, 0xef, 0x3a, 0x9b, 0xa0,
252            0x90, 0x2c, 0x91, 0xdc, 0x5f, 0x7e, 0x63, 0x39,
253        ]),
254        Tmr([
255            0x16, 0x98, 0x45, 0xb0, 0xe2, 0xf0, 0x4a, 0x83,
256            0x76, 0xfe, 0x91, 0x14, 0xbd, 0x35, 0x3a, 0x29,
257            0xe9, 0xb7, 0x80, 0x42, 0xb7, 0x70, 0x1b, 0xa1,
258            0x6d, 0x02, 0xc4, 0x62, 0x18, 0xef, 0x8b, 0xdf,
259        ]),
260        Tmr([
261            0xbd, 0x59, 0x57, 0x8c, 0x45, 0x78, 0xfe, 0xc4,
262            0xef, 0x2a, 0x29, 0xc1, 0xad, 0xea, 0x4c, 0xe1,
263            0x30, 0x6c, 0x1a, 0x2b, 0x10, 0xd6, 0x18, 0xbc,
264            0x58, 0x44, 0x67, 0x84, 0x17, 0x97, 0x3b, 0x8e,
265        ]),
266        Tmr([
267            0x88, 0xd1, 0x8c, 0x11, 0x5f, 0x86, 0x54, 0x40,
268            0x5f, 0xd7, 0x1d, 0xe8, 0x7e, 0x6f, 0xf0, 0x80,
269            0x6c, 0x5d, 0xa7, 0x97, 0xca, 0xaf, 0x48, 0xe2,
270            0x47, 0xea, 0xcc, 0x43, 0x99, 0x96, 0x89, 0x1a,
271        ]),
272        Tmr([
273            0x90, 0x65, 0x22, 0xe1, 0x6d, 0xf3, 0x6f, 0x83,
274            0xa4, 0x50, 0x32, 0x8a, 0xf8, 0x4e, 0x2f, 0x3e,
275            0x52, 0xf6, 0xd6, 0x49, 0xa7, 0x88, 0xe3, 0xb2,
276            0x1c, 0xca, 0xe3, 0xcd, 0x9a, 0x24, 0x66, 0x77,
277        ]),
278        Tmr([
279            0x3a, 0xba, 0x4c, 0xce, 0x0e, 0x46, 0xc5, 0x54,
280            0xb4, 0x4f, 0x70, 0x21, 0x3d, 0x4d, 0x8b, 0xd8,
281            0xe8, 0xf1, 0x7e, 0x2b, 0xd1, 0x7b, 0xdf, 0xb7,
282            0x15, 0x0a, 0xdf, 0xfd, 0x9a, 0xdf, 0x80, 0x9d,
283        ]),
284        Tmr([
285            0x7d, 0x81, 0x2a, 0xf0, 0x44, 0xcb, 0x04, 0xd2,
286            0xaf, 0x4f, 0xc8, 0xe9, 0xb5, 0x30, 0x66, 0x03,
287            0x9b, 0xd5, 0x89, 0x2a, 0x56, 0xa5, 0xd5, 0x64,
288            0x1c, 0x5c, 0x58, 0xc8, 0x6e, 0xed, 0x8a, 0x35,
289        ]),
290        Tmr([
291            0x23, 0x0e, 0xa9, 0x70, 0x03, 0x3e, 0x47, 0xc5,
292            0x61, 0x68, 0x1e, 0xe7, 0x20, 0x58, 0xb9, 0xc0,
293            0x75, 0x5b, 0x8d, 0x87, 0x22, 0x80, 0x18, 0x4f,
294            0x2e, 0x3f, 0xe3, 0x93, 0xc0, 0x47, 0x8f, 0x1a,
295        ]),
296        Tmr([
297            0x6e, 0x90, 0x88, 0x04, 0x20, 0x46, 0x2b, 0x84,
298            0xf2, 0x16, 0x30, 0x2a, 0x09, 0x56, 0x9c, 0xc8,
299            0xd4, 0x47, 0x54, 0x4a, 0xcd, 0x8a, 0xbc, 0x53,
300            0xd8, 0xa7, 0xcf, 0x21, 0x9b, 0x44, 0x9c, 0x95,
301        ]),
302        Tmr([
303            0x7a, 0xd1, 0x5d, 0xed, 0x85, 0x02, 0xa6, 0xf1,
304            0x1e, 0xb8, 0xa4, 0x9b, 0x25, 0xc8, 0xd7, 0x62,
305            0xa0, 0xfe, 0x00, 0x4f, 0xb5, 0x7d, 0x73, 0x43,
306            0xbd, 0xf4, 0x90, 0xed, 0x7e, 0xd2, 0xf4, 0x07,
307        ]),
308        Tmr([
309            0xaa, 0x30, 0x30, 0x15, 0x71, 0xcf, 0x8d, 0x2d,
310            0x64, 0xe9, 0x65, 0x4b, 0x0c, 0xbd, 0xe0, 0x54,
311            0x01, 0x77, 0xab, 0xc2, 0xf2, 0xef, 0xfb, 0x7f,
312            0x05, 0x2e, 0x27, 0xa8, 0xcc, 0xcc, 0xee, 0x62,
313        ]),
314        Tmr([
315            0x28, 0x6d, 0x4d, 0x57, 0x6d, 0xb8, 0xe8, 0x45,
316            0x00, 0x9c, 0x74, 0x84, 0xe0, 0x0a, 0x9f, 0xa3,
317            0xf3, 0x18, 0xa8, 0x21, 0x9e, 0x38, 0x66, 0x2c,
318            0xda, 0x11, 0x75, 0x78, 0x22, 0xe4, 0x53, 0xbb,
319        ]),
320        Tmr([
321            0x10, 0x56, 0xa7, 0x17, 0xdc, 0x0c, 0x86, 0xb7,
322            0x49, 0x97, 0x5e, 0x9c, 0x36, 0x4a, 0xb5, 0xa6,
323            0x64, 0x77, 0xc4, 0x2d, 0xe1, 0x6e, 0x5b, 0x05,
324            0x29, 0x81, 0x4f, 0x4c, 0xba, 0x95, 0x7c, 0xb3,
325        ]),
326        Tmr([
327            0x94, 0x59, 0x0e, 0xf5, 0x66, 0x10, 0xaa, 0x7f,
328            0xec, 0x46, 0x5b, 0x72, 0x32, 0xab, 0xa3, 0xf4,
329            0x7c, 0x94, 0x2b, 0x8e, 0x8d, 0xc8, 0x76, 0x82,
330            0x51, 0xd3, 0x70, 0x2c, 0x99, 0xb9, 0xef, 0xef,
331        ]),
332        Tmr([
333            0xd0, 0x7f, 0x71, 0xb7, 0xcd, 0x48, 0xb8, 0x50,
334            0xad, 0x09, 0x06, 0x8b, 0x9b, 0x48, 0xe0, 0xf8,
335            0x5f, 0x84, 0xc0, 0x1b, 0x34, 0x58, 0x6a, 0x51,
336            0x34, 0x61, 0xfa, 0xf7, 0x6d, 0x54, 0x34, 0x64,
337        ]),
338    ];
339
340    /// The TMR of the `Ctx8` type used by the SHA256 jets.
341    #[rustfmt::skip]
342    pub const CTX8: Tmr = Tmr([
343        0x8d, 0x5c, 0xe5, 0xf6, 0xeb, 0xfc, 0x70, 0x61,
344        0xe7, 0x91, 0x16, 0xbd, 0xf6, 0x6f, 0xb4, 0xe4,
345        0xc6, 0xca, 0x32, 0xa0, 0x1c, 0xda, 0x48, 0xf6,
346        0xed, 0xc1, 0x0a, 0xee, 0xfd, 0x31, 0x0e, 0x8c,
347    ]);
348
349    /// The TMR for the unit type
350    pub const fn unit() -> Tmr {
351        Self::from_byte_array(Self::UNIT_IV.to_parts().0)
352    }
353
354    /// The TMR for the successor of a type.
355    ///
356    /// Given a type `X`, we define its successor `S X` as `1 + X`.
357    /// In Rust notation this would be `Option<X>`.
358    pub fn successor(self) -> Tmr {
359        Self::SUM_IV
360            .zz_update_2x32(Tmr::unit(), self)
361            .into_merkle_root()
362    }
363
364    /// The TMR for the sum of two types, whose TMRs are given
365    pub fn sum(tmr1: Tmr, tmr2: Tmr) -> Tmr {
366        Self::SUM_IV
367            .update_64(&super::concat(tmr1, tmr2))
368            .into_merkle_root()
369    }
370
371    /// The TMR for the sum of two types, whose TMRs are given
372    ///
373    /// This function is slow but can be used in a const context. If you do not
374    /// need to run in a const context, use [`Self::sum`] instead.
375    pub const fn sum_unoptimized(tmr1: Tmr, tmr2: Tmr) -> Tmr {
376        Self::from_byte_array(
377            Self::SUM_IV
378                .update_2x32_unoptimized(tmr1.as_byte_array(), tmr2.as_byte_array())
379                .to_parts()
380                .0,
381        )
382    }
383
384    /// The TMR for the product of two types, whose TMRs are given
385    pub fn product(tmr1: Tmr, tmr2: Tmr) -> Tmr {
386        Self::PROD_IV.zz_update_2x32(tmr1, tmr2).into_merkle_root()
387    }
388
389    /// The TMR for the product of two types, whose TMRs are given
390    ///
391    /// This function is slow but can be used in a const context. If you do not
392    /// need to run in a const context, use [`Self::product`] instead.
393    pub const fn product_unoptimized(tmr1: Tmr, tmr2: Tmr) -> Tmr {
394        Self::from_byte_array(
395            Self::PROD_IV
396                .update_2x32_unoptimized(tmr1.as_byte_array(), tmr2.as_byte_array())
397                .to_parts()
398                .0,
399        )
400    }
401}
402
403#[cfg(test)]
404mod tests {
405    use super::*;
406
407    use crate::jet::Jet;
408    use crate::merkle::bip340_iv;
409    use crate::types::{self, Final};
410
411    #[test]
412    fn ivs() {
413        fn check_iv(target: Midstate, s: &'static str) {
414            let name = s.trim_start_matches("Simplicity\x1fType\x1f");
415            // Uncomment this if the IVs ever change
416            /*
417            let target = Tmr(bip340_iv(s.as_bytes()));
418            println!("    #[rustfmt::skip]");
419            println!("    const {}_IV: Midstate = Midstate::new([", name.to_ascii_uppercase());
420            print!("       "); for ch in &target.0[0..8] { print!(" 0x{:02x},", ch); }; println!();
421            print!("       "); for ch in &target.0[8..16] { print!(" 0x{:02x},", ch); }; println!();
422            print!("       "); for ch in &target.0[16..24] { print!(" 0x{:02x},", ch); }; println!();
423            print!("       "); for ch in &target.0[24..32] { print!(" 0x{:02x},", ch); }; println!();
424            println!("    ], 64);");
425            println!();
426            */
427            assert_eq!(
428                target,
429                bip340_iv(s.as_bytes()),
430                "mismatch on IV for {}",
431                name
432            );
433        }
434
435        check_iv(Tmr::UNIT_IV, "Simplicity\x1fType\x1funit");
436        check_iv(Tmr::SUM_IV, "Simplicity\x1fType\x1fsum");
437        check_iv(Tmr::PROD_IV, "Simplicity\x1fType\x1fprod");
438    }
439
440    #[test]
441    #[allow(clippy::needless_range_loop)]
442    fn const_powers_of_2() {
443        fn check_pow(target: Tmr, i: usize, expected_tmrs: &[Tmr]) {
444            // Uncomment this if the IVs ever change
445            /*
446            let target = tmrs[i];
447            println!("    Tmr([");
448            print!("       "); for ch in &target.0[0..8] { print!(" 0x{:02x},", ch); }; println!();
449            print!("       "); for ch in &target.0[8..16] { print!(" 0x{:02x},", ch); }; println!();
450            print!("       "); for ch in &target.0[16..24] { print!(" 0x{:02x},", ch); }; println!();
451            print!("       "); for ch in &target.0[24..32] { print!(" 0x{:02x},", ch); }; println!();
452            println!("    ]),");
453            */
454            assert_eq!(target, expected_tmrs[i], "mismatch on TMR for TWO^(2^{i})");
455        }
456
457        let n = Tmr::TWO_TWO_N.len();
458        types::Context::with_context(|ctx| {
459            let tmrs = types::Type::powers_of_two(&ctx, n)
460                .iter()
461                .filter_map(types::Type::tmr)
462                .collect::<Vec<Tmr>>();
463            debug_assert_eq!(tmrs.len(), n);
464            for i in 0..n {
465                check_pow(Tmr::TWO_TWO_N[i], i, &tmrs);
466            }
467        });
468    }
469
470    #[test]
471    fn direct_constructors() {
472        let unit = Tmr::unit();
473        let bit1 = Tmr::sum(unit, unit);
474        let bit2 = Tmr::sum_unoptimized(unit, unit);
475        assert_eq!(bit1, bit2);
476        assert_eq!(bit1, Tmr::TWO_TWO_N[0]);
477
478        let dbit1 = Tmr::product(bit1, bit1);
479        let dbit2 = Tmr::product_unoptimized(bit1, bit1);
480        assert_eq!(dbit1, dbit2);
481        assert_eq!(dbit1, Tmr::TWO_TWO_N[1]);
482    }
483
484    #[test]
485    fn const_buffer8() {
486        use std::sync::Arc;
487
488        let two_8_tmr = Tmr::TWO_TWO_N[3];
489        let buf_0_tmr = two_8_tmr.successor();
490
491        let two_8 = Final::two_two_n_fixed::<3>();
492        let buf_0 = Arc::clone(&two_8).successor();
493
494        assert_eq!(buf_0, Final::buffer8_two_n_plus_one(0).unwrap());
495        assert_eq!(two_8.tmr(), two_8_tmr);
496        assert_eq!(buf_0.tmr(), buf_0_tmr);
497        assert_eq!(buf_0_tmr, Tmr::BUFFER8_TWO_N_PLUS_ONE[0]);
498
499        let mut tmr = buf_0_tmr;
500        let mut fin = buf_0;
501        assert_eq!(Tmr::BUFFER8_TWO_N_PLUS_ONE.len(), 16);
502        for n in 1..Tmr::BUFFER8_TWO_N_PLUS_ONE.len() {
503            tmr = Tmr::product(Tmr::TWO_TWO_N[n + 3].successor(), tmr);
504            fin = Final::product(Final::two_two_n(n + 3).unwrap().successor(), fin);
505
506            assert_eq!(fin.tmr(), tmr);
507            assert_eq!(fin, Final::buffer8_two_n_plus_one(n).unwrap());
508            assert_eq!(tmr, Tmr::BUFFER8_TWO_N_PLUS_ONE[n]);
509
510            // For the case of n == 5, i.e. a 63-byte buffer (63 = 2^(n + 1) - 1),
511            // we can check against the SHA256 Ctx8 type to make sure that our
512            // computations are actually correct.
513            if n == 5 {
514                let extra_ctx_stuff = Final::product(
515                    Final::two_two_n_fixed::<6>(), // 2^64
516                    Final::two_two_n_fixed::<8>(), // 2^256
517                );
518                let synthetic_ctx_ty = Final::product(Arc::clone(&fin), extra_ctx_stuff);
519                let actual_ctx_ty = crate::jet::Core::Sha256Ctx8Init.target_ty().to_final();
520                assert_eq!(synthetic_ctx_ty, actual_ctx_ty,);
521                assert_eq!(synthetic_ctx_ty, Final::ctx8());
522                assert_eq!(synthetic_ctx_ty.tmr(), Tmr::CTX8);
523            }
524        }
525    }
526}