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