#![deny(
unsafe_code,
dead_code,
missing_docs,
unused_variables,
unused_mut,
unused_imports,
non_upper_case_globals,
non_camel_case_types,
non_snake_case
)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
#[macro_use]
extern crate amplify;
#[macro_use]
extern crate strict_encoding;
#[macro_use]
extern crate commit_encoding_derive;
#[cfg(feature = "serde")]
#[macro_use]
extern crate serde;
#[cfg(feature = "derive")]
pub use commit_encoding_derive::CommitEncode;
mod commit;
mod conceal;
mod convolve;
mod embed;
mod id;
#[cfg(feature = "stl")]
pub mod stl;
pub mod merkle;
pub mod mpc;
mod digest;
#[cfg(feature = "vesper")]
pub mod vesper;
pub use commit::{CommitVerify, TryCommitVerify, VerifyError};
pub use conceal::Conceal;
pub use convolve::{ConvolveCommit, ConvolveCommitProof, ConvolveVerifyError};
pub use digest::{Digest, DigestExt, Ripemd160, Sha256};
pub use embed::{EmbedCommitProof, EmbedCommitVerify, EmbedVerifyError, VerifyEq};
pub use id::{
CommitColType, CommitEncode, CommitEngine, CommitId, CommitLayout, CommitStep, CommitmentId,
CommitmentLayout, StrictHash,
};
pub use merkle::{MerkleBuoy, MerkleHash, MerkleLeaves, MerkleNode, NodeBranching};
pub const LIB_NAME_COMMIT_VERIFY: &str = "CommitVerify";
pub trait CommitmentProtocol {}
pub struct UntaggedProtocol;
impl CommitmentProtocol for UntaggedProtocol {}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
#[display("reserved")]
#[derive(StrictType, StrictEncode)]
#[strict_type(lib = LIB_NAME_COMMIT_VERIFY)]
pub struct ReservedBytes<const LEN: usize, const VAL: u8 = 0>([u8; LEN]);
impl<const LEN: usize, const VAL: u8> Default for ReservedBytes<LEN, VAL> {
fn default() -> Self { Self([VAL; LEN]) }
}
impl<const LEN: usize, const VAL: u8> From<[u8; LEN]> for ReservedBytes<LEN, VAL> {
fn from(value: [u8; LEN]) -> Self {
assert_eq!(value, [VAL; LEN]);
Self(value)
}
}
impl<const LEN: usize, const VAL: u8> ReservedBytes<LEN, VAL> {
pub const fn new() -> Self { Self([VAL; LEN]) }
}
mod _reserved {
use strict_encoding::{DecodeError, ReadTuple, StrictDecode, TypedRead};
use crate::{CommitEncode, CommitEngine, ReservedBytes, StrictHash};
impl<const LEN: usize, const VAL: u8> CommitEncode for ReservedBytes<LEN, VAL> {
type CommitmentId = StrictHash;
fn commit_encode(&self, e: &mut CommitEngine) { e.commit_to_serialized(self) }
}
impl<const LEN: usize, const VAL: u8> StrictDecode for ReservedBytes<LEN, VAL> {
fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
let reserved = reader.read_tuple(|r| r.read_field().map(Self))?;
if reserved != ReservedBytes::<LEN, VAL>::default() {
Err(DecodeError::DataIntegrityError(format!(
"unsupported reserved byte value indicating a future RGB version. Please \
update your software, or, if the problem persists, contact your vendor \
providing the following version information: {reserved}"
)))
} else {
Ok(reserved)
}
}
}
#[cfg(feature = "serde")]
mod _serde {
use amplify::hex::{FromHex, ToHex};
use serde::de::Error;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use super::*;
impl<const LEN: usize, const VAL: u8> Serialize for ReservedBytes<LEN, VAL> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer {
if serializer.is_human_readable() {
serializer.serialize_str(&self.0.to_hex())
} else {
serializer.serialize_bytes(self.0.as_ref())
}
}
}
impl<'de, const LEN: usize, const VAL: u8> Deserialize<'de> for ReservedBytes<LEN, VAL> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de> {
let v = if deserializer.is_human_readable() {
let s = String::deserialize(deserializer)?;
Vec::<u8>::from_hex(&s)
.map_err(|_| D::Error::custom("invalid reserved value"))?
} else {
Vec::<u8>::deserialize(deserializer)?
};
if v != [VAL; LEN] {
return Err(Error::custom("invalid reserved value"));
}
Ok(default!())
}
}
}
}
#[cfg(test)]
pub mod test_helpers {
#![cfg_attr(coverage_nightly, coverage(off))]
use amplify::confinement::SmallVec;
use amplify::hex::FromHex;
pub use super::commit::test_helpers::*;
pub use super::embed::test_helpers::*;
use super::*;
pub fn gen_messages() -> Vec<SmallVec<u8>> {
vec![
b"".to_vec(),
b"\x00".to_vec(),
b"test".to_vec(),
b"test*".to_vec(),
Vec::from_hex("deadbeef").unwrap(),
Vec::from_hex("deadbeef00").unwrap(),
Vec::from_hex("00deadbeef").unwrap(),
b"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798".to_vec(),
Vec::from_hex("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")
.unwrap(),
Vec::from_hex("02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9")
.unwrap(),
]
.into_iter()
.map(|v| SmallVec::try_from(v).unwrap())
.collect()
}
}