1#![deny(
24 non_upper_case_globals,
25 non_camel_case_types,
26 non_snake_case,
27 unused_mut,
28 unused_imports,
29 dead_code,
30 )]
32#![cfg_attr(docsrs, feature(doc_auto_cfg))]
33
34#[macro_use]
35extern crate amplify;
36#[macro_use]
37extern crate strict_encoding;
38#[macro_use]
39extern crate commit_encoding_derive;
40#[cfg(feature = "serde")]
41#[macro_use]
42extern crate serde;
43
44#[cfg(feature = "derive")]
45pub use commit_encoding_derive::CommitEncode;
46
47mod commit;
48mod conceal;
49mod convolve;
50mod embed;
51mod id;
52#[cfg(feature = "stl")]
53pub mod stl;
54
55pub mod merkle;
56pub mod mpc;
57mod digest;
58pub mod vesper;
59
60pub use commit::{CommitVerify, TryCommitVerify, VerifyError};
61pub use conceal::Conceal;
62pub use convolve::{ConvolveCommit, ConvolveCommitProof, ConvolveVerifyError};
63pub use digest::{Digest, DigestExt, Ripemd160, Sha256};
64pub use embed::{EmbedCommitProof, EmbedCommitVerify, EmbedVerifyError, VerifyEq};
65pub use id::{
66 CommitColType, CommitEncode, CommitEngine, CommitId, CommitLayout, CommitStep, CommitmentId,
67 CommitmentLayout, StrictHash,
68};
69pub use merkle::{MerkleBuoy, MerkleHash, MerkleLeaves, MerkleNode, NodeBranching};
70
71pub const LIB_NAME_COMMIT_VERIFY: &str = "CommitVerify";
72
73pub trait CommitmentProtocol {}
84
85pub struct UntaggedProtocol;
88impl CommitmentProtocol for UntaggedProtocol {}
89
90#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
92#[display("reserved")]
93#[derive(StrictType, StrictEncode)]
94#[strict_type(lib = LIB_NAME_COMMIT_VERIFY)]
95pub struct ReservedBytes<const LEN: usize, const VAL: u8 = 0>([u8; LEN]);
96
97impl<const LEN: usize, const VAL: u8> Default for ReservedBytes<LEN, VAL> {
98 fn default() -> Self { Self([VAL; LEN]) }
99}
100
101impl<const LEN: usize, const VAL: u8> From<[u8; LEN]> for ReservedBytes<LEN, VAL> {
102 fn from(value: [u8; LEN]) -> Self {
103 assert_eq!(value, [VAL; LEN]);
104 Self(value)
105 }
106}
107
108mod _reserved {
109 use strict_encoding::{DecodeError, ReadTuple, StrictDecode, TypedRead};
110
111 use crate::{CommitEncode, CommitEngine, ReservedBytes, StrictHash};
112
113 impl<const LEN: usize, const VAL: u8> CommitEncode for ReservedBytes<LEN, VAL> {
114 type CommitmentId = StrictHash;
115
116 fn commit_encode(&self, e: &mut CommitEngine) { e.commit_to_serialized(self) }
117 }
118
119 impl<const LEN: usize, const VAL: u8> StrictDecode for ReservedBytes<LEN, VAL> {
120 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
121 let reserved = reader.read_tuple(|r| r.read_field().map(Self))?;
122 if reserved != ReservedBytes::<LEN, VAL>::default() {
123 Err(DecodeError::DataIntegrityError(format!(
124 "unsupported reserved byte value indicating a future RGB version. Please \
125 update your software, or, if the problem persists, contact your vendor \
126 providing the following version information: {reserved}"
127 )))
128 } else {
129 Ok(reserved)
130 }
131 }
132 }
133
134 #[cfg(feature = "serde")]
135 mod _serde {
136 use std::fmt;
137
138 use serde::de::Visitor;
139 use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
140
141 use super::*;
142
143 impl<const LEN: usize, const VAL: u8> Serialize for ReservedBytes<LEN, VAL> {
144 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
145 where S: Serializer {
146 serializer.serialize_unit()
148 }
149 }
150
151 impl<'de, const LEN: usize, const VAL: u8> Deserialize<'de> for ReservedBytes<LEN, VAL> {
152 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
153 where D: Deserializer<'de> {
154 #[derive(Default)]
155 pub struct UntaggedUnitVisitor;
156
157 impl Visitor<'_> for UntaggedUnitVisitor {
158 type Value = ();
159
160 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
161 write!(formatter, "reserved unit")
162 }
163
164 fn visit_none<E>(self) -> Result<(), E>
165 where E: de::Error {
166 Ok(())
167 }
168
169 fn visit_unit<E>(self) -> Result<(), E>
170 where E: de::Error {
171 Ok(())
172 }
173 }
174
175 deserializer.deserialize_unit(UntaggedUnitVisitor)?;
176 Ok(default!())
177 }
178 }
179 }
180}
181
182#[cfg(test)]
184pub mod test_helpers {
185 use amplify::confinement::SmallVec;
186 use amplify::hex::FromHex;
187
188 pub use super::commit::test_helpers::*;
189 pub use super::embed::test_helpers::*;
190 use super::*;
191
192 pub fn gen_messages() -> Vec<SmallVec<u8>> {
197 vec![
198 b"".to_vec(),
200 b"\x00".to_vec(),
202 b"test".to_vec(),
204 b"test*".to_vec(),
206 Vec::from_hex("deadbeef").unwrap(),
208 Vec::from_hex("deadbeef00").unwrap(),
210 Vec::from_hex("00deadbeef").unwrap(),
212 b"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798".to_vec(),
214 Vec::from_hex("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")
216 .unwrap(),
217 Vec::from_hex("02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9")
219 .unwrap(),
220 ]
221 .into_iter()
222 .map(|v| SmallVec::try_from(v).unwrap())
223 .collect()
224 }
225}